[RFC PATCH v1 0/5] Landlock tracepoints
Mickaël Salaün
mic at digikod.net
Tue May 27 14:52:51 UTC 2025
On Mon, May 26, 2025 at 07:37:41PM +0100, Tingmao Wang wrote:
> On 5/23/25 17:57, Mickaël Salaün wrote:
> > Hi,
> >
> > This series adds two tracepoints to Landlock, one tied to rule addition,
> > and another to rule checking. With these new tracepoints, we can see
> > all steps leading to an access decision. They can be directly used with
> > /sys/kernel/tracing/events/landlock/* or attached by eBPF programs to
> > get a more complete view of Landlock internals.
> >
> > This new feature is useful to trouble shoot policy issues, and it should
> > also limit the need for custom debugging kernel code when developing new
> > Landlock features.
> >
> > Landlock already has audit support, which enables us to log denied
> > access requests. Audit is useful to identify security issues or sandbox
> > misconfiguration. However, it might not be enough to debug Landlock
> > policies. The main differences with audit events is that traces are
> > disabled by default, can be very verbose, and can be filtered according
> > to process and Landlock properties (e.g. domain ID).
> >
> > As for audit, this tracing feature may expose sensitive information and
> > must then only be accessible to the system administrator.
> >
> > This RFC only fully supports filesystem rules but the next series will
> > also support network rules. Tests are also missing for now.
> >
> > Regards,
> >
> > Mickaël Salaün (5):
> > landlock: Rename landlock_id to landlock_rule_ref
> > landlock: Merge landlock_find_rule() into landlock_unmask_layers()
> > tracing: Add __print_untrusted_str()
> > landlock: Add landlock_add_rule_fs tracepoint
> > landlock: Add landlock_check_rule tracepoint
> >
> > MAINTAINERS | 1 +
> > include/linux/trace_events.h | 3 +
> > include/trace/events/landlock.h | 124 ++++++++++++++
> > include/trace/stages/stage3_trace_output.h | 4 +
> > include/trace/stages/stage7_class_define.h | 1 +
> > kernel/trace/trace_output.c | 40 +++++
> > security/landlock/Makefile | 11 +-
> > security/landlock/fs.c | 178 +++++++++++++--------
> > security/landlock/fs.h | 3 +
> > security/landlock/net.c | 18 +--
> > security/landlock/ruleset.c | 65 ++++----
> > security/landlock/ruleset.h | 15 +-
> > security/landlock/trace.c | 15 ++
> > 13 files changed, 365 insertions(+), 113 deletions(-)
> > create mode 100644 include/trace/events/landlock.h
> > create mode 100644 security/landlock/trace.c
> >
> >
> > base-commit: a5806cd506af5a7c19bcd596e4708b5c464bfd21
>
> Tested-by: Tingmao Wang <m at maowtm.org>
>
> Here is an example output I got with `trace-cmd record -e landlock`:
>
> landlock-add-ru-776 [001] 75134.554776: landlock_add_rule_fs: [FAILED TO
> PARSE] ruleset=0xffff88811a459200 ref_key=18446612686420679296 allowed=57343
> dev=21 ino=53 pathname=/tmp/test
> landlock-add-ru-776 [001] 75134.555336: landlock_check_rule: [FAILED TO
> PARSE] domain_id=7838764077 access_request=4 ref_type=1
> ref_key=18446612686420679296 layers=ARRAY[ff, df]
> I suggest adding some more events which I think shouldn't be too difficult
> to implement and I can see them helping a lot with tracing / debugging
> especially by BPF programs or someone new to landlock:
>
> - landlock_restrict_self: Currently we trace out the ruleset pointer in add
> rule, and the domain ID in check rule. However there is no way for someone
> just looking at this trace (or a BPF program for landlock) to relate which
> rulesets are applied to which domains. I think a simple event we could add
> that will help with this is, on landlock_restrict_self, prints out the
> ruleset passed in as well as the domain ID newly created. Maybe also
> num_rules and num_layers on the new ruleset since it's trivial to do so, and
> could be informative to someone analyzing a Landlock thing.
Yep, that was my plan for v2. :)
I was also wondering about adding a tracepoint for ruleset creation.
This one would print the ruleset's attributes as an array.
>
> - landlock_check_fs: Distinct from landlock_check_rule, this will happen
> once the outcome of the access check is determined (maybe at the end of
> is_access_to_paths_allowed and collect_domain_accesses?). It would include
> the pathname of the target file (only allocated if this event is enabled of
> course), so something like:
>
> landlock_check_fs: domain_id=7838764077 access_request=4
> pathname=/tmp/test allowed=true
> landlock_check_fs: domain_id=7838764077 access_request=4
> pathname=/tmp/test2 allowed=false
>
> We already produces audit logs for denied requests so it is a little bit
> duplicating that, but I think this trace event shouldn't be too costly to
> include. It has the benefit that
>
> 1. If an access is denied because no rules matched, we don't get any
> landlock_check_rule traces, and so there's no way for someone looking at the
> trace log to find out landlock denied something.
That would indeed be useful to see final access decisions. It might be
a bit tricky to generically handle all the allowed access but I'll try
something.
>
> 2. Having an event that represents an access check makes it possible for BPF
> programs to find out about all landlock access checks (most interestingly
> denied ones but we could expose the allowed ones too), and potentially
> relate the various `landlock_check_rule` events to an access check.
>
> Actually, maybe it's worth having a "landlock_check_fs_enter", emitted at
> the beginning of is_access_to_paths_allowed and collect_domain_accesses?
> This could be useful for performance measurements, and also makes it more
Aren't kprobes/kretprobes enough for performance measurement? They can
also be used with current kernels.
> explicit which landlock_check_rule resulted from which access check. Maybe
> the pathname and domain_id could be printed on the enter event, and the exit
> event would just have the outcome? (Just an idea, I feel less certain about
> this. "Enter"/"exit" naming taken from sys_enter_*/sys_exit_* but start/end
> also works)
This landlock_check_fs_enter event would only be called after the
landlock_get_applicable_subject() check though.
More information about the Linux-security-module-archive
mailing list