Thread (43 messages) 43 messages, 4 authors, 2024-09-25

Re: [RFC PATCH v2 00/12] Socket type control for Landlock

From: Mikhail Ivanov <hidden>
Date: 2024-06-06 11:44:35
Also in: netdev, netfilter-devel


6/4/2024 11:22 PM, Günther Noack wrote:
On Fri, May 24, 2024 at 05:30:03PM +0800, Mikhail Ivanov wrote:
quoted
Hello! This is v2 RFC patch dedicated to socket protocols restriction.

It is based on the landlock's mic-next branch on top of v6.9 kernel
version.
Hello Mikhail!

I patched in your patchset and tried to use the feature with a small
demo tool, but I ran into what I think is a bug -- do you happen to
know what this might be?

I used 6.10-rc1 as a base and patched your patches on top.

The code is a small tool called "nonet", which does the following:

   - Disable socket creation with a Landlock ruleset with the following
     attributes:
   
     struct landlock_ruleset_attr attr = {
       .handled_access_socket = LANDLOCK_ACCESS_SOCKET_CREATE,
     };

   - open("/dev/null", O_WRONLY)

Expected result:

   - open() should work

Observed result:

   - open() fails with EACCES.

I traced this with perf, and found that the open() gets rejected from
Landlock's hook_file_open, whereas hook_socket_create does not get
invoked.  This is surprising to me -- Enabling a policy for socket
creation should not influence the outcome of opening files!

Tracing commands:

   sudo perf probe hook_socket_create '$params'
   sudo perf probe 'hook_file_open%return $retval'
   sudo perf record -e 'probe:*' -g -- ./nonet
   sudo perf report
  
You can find the tool in my landlock-examples repo in the nonet_bug branch:
https://github.com/gnoack/landlock-examples/blob/nonet_bug/nonet.c

Landlock is enabled like this:
https://github.com/gnoack/landlock-examples/blob/nonet_bug/sandbox_socket.c

Do you have a hunch what might be going on?
Hello Günther!
Big thanks for this research!

I figured out that I define LANDLOCK_SHIFT_ACCESS_SOCKET macro in
really strange way (see landlock/limits.h):

   #define LANDLOCK_SHIFT_ACCESS_SOCKET	LANDLOCK_NUM_ACCESS_SOCKET

With this definition, socket access mask overlaps the fs access
mask in ruleset->access_masks[layer_level]. That's why
landlock_get_fs_access_mask() returns non-zero mask in hook_file_open().

So, the macro must be defined in this way:

   #define LANDLOCK_SHIFT_ACCESS_SOCKET	(LANDLOCK_NUM_ACCESS_NET +
                                          LANDLOCK_NUM_ACCESS_FS)

With this fix, open() doesn't fail in your example.

I'm really sorry that I somehow made such a stupid typo. I will try my
best to make sure this doesn't happen again.
Thanks,
–Günther
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help