Thread (16 messages) 16 messages, 3 authors, 2025-05-27

Re: [RFC PATCH v1 0/5] Landlock tracepoints

From: Mickaël Salaün <mic@digikod.net>
Date: 2025-05-27 14:52:55
Also in: linux-security-module

On Mon, May 26, 2025 at 07:37:41PM +0100, Tingmao Wang wrote:
On 5/23/25 17:57, Mickaël Salaün wrote:
quoted
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 <redacted>

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.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help