Hello! These patches add simple ioctl(2) support to Landlock. Objective ~~~~~~~~~ Make ioctl(2) requests restrictable with Landlock, in a way that is useful for real-world applications. Proposed approach ~~~~~~~~~~~~~~~~~ Introduce the LANDLOCK_ACCESS_FS_IOCTL right, which restricts the use of ioctl(2) on file descriptors. We attach the LANDLOCK_ACCESS_FS_IOCTL right to opened file descriptors, as we already do for LANDLOCK_ACCESS_FS_TRUNCATE. I believe that this approach works for the majority of use cases, and offers a good trade-off between Landlock API and implementation complexity and flexibility when the feature is used. Current limitations ~~~~~~~~~~~~~~~~~~~ With this patch set, ioctl(2) requests can *not* be filtered based on file type, device number (dev_t) or on the ioctl(2) request number. On the initial RFC patch set [1], we have reached consensus to start with this simpler coarse-grained approach, and build additional ioctl restriction capabilities on top in subsequent steps. [1] https://lore.kernel.org/linux-security-module/d4f1395c-d2d4-1860-3a02-2a0c023dd761@xxxxxxxxxxx/ Notable implications of this approach ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Existing inherited file descriptors stay unaffected when a program enables Landlock. This means in particular that in common scenarios, the terminal's ioctls (ioctl_tty(2)) continue to work. * ioctl(2) continues to be available for file descriptors acquired through means other than open(2). Example: Network sockets, memfd_create(2), file descriptors that are already open before the Landlock ruleset is enabled. Examples ~~~~~~~~ Starting a sandboxed shell from $HOME with samples/landlock/sandboxer: LL_FS_RO=/ LL_FS_RW=. ./sandboxer /bin/bash The LANDLOCK_ACCESS_FS_IOCTL right is part of the "read-write" rights here, so we expect that newly opened files outside of $HOME don't work with ioctl(2). * "stty" works: It probes terminal properties * "stty </dev/tty" fails: /dev/tty can be reopened, but the ioctl is denied. * "eject" fails: ioctls to use CD-ROM drive are denied. * "ls /dev" works: It uses ioctl to get the terminal size for columnar layout * The text editors "vim" and "mg" work. (GNU Emacs fails because it attempts to reopen /dev/tty.) Related Work ~~~~~~~~~~~~ OpenBSD's pledge(2) [2] restricts ioctl(2) independent of the file descriptor which is used. The implementers maintain multiple allow-lists of predefined ioctl(2) operations required for different application domains such as "audio", "bpf", "tty" and "inet". OpenBSD does not guarantee ABI backwards compatibility to the same extent as Linux does, so it's easier for them to update these lists in later versions. It might not be a feasible approach for Linux though. [2] https://man.openbsd.org/OpenBSD-7.3/pledge.2 Changes ~~~~~~~ V2: * rebased on mic-next * added documentation * exercise ioctl in the memfd test * test: Use layout0 for the test --- V1: https://lore.kernel.org/linux-security-module/20230502171755.9788-1-gnoack3000@xxxxxxxxx/ Günther Noack (6): landlock: Increment Landlock ABI version to 4 landlock: Add LANDLOCK_ACCESS_FS_IOCTL access right selftests/landlock: Test ioctl support selftests/landlock: Test ioctl with memfds samples/landlock: Add support for LANDLOCK_ACCESS_FS_IOCTL landlock: Document ioctl support Documentation/userspace-api/landlock.rst | 52 ++++++++----- include/uapi/linux/landlock.h | 19 +++-- samples/landlock/sandboxer.c | 12 ++- security/landlock/fs.c | 21 +++++- security/landlock/limits.h | 2 +- security/landlock/syscalls.c | 2 +- tools/testing/selftests/landlock/base_test.c | 2 +- tools/testing/selftests/landlock/fs_test.c | 77 ++++++++++++++++++-- 8 files changed, 149 insertions(+), 38 deletions(-) base-commit: 35ca4239929737bdc021ee923f97ebe7aff8fcc4 -- 2.41.0.162.gfafddb0af9-goog