From patchwork Fri Mar 22 15:09:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13600245 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3CC3A4DA04 for ; Fri, 22 Mar 2024 15:10:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120226; cv=none; b=ZCJJDC+2YJoTEqx3TEDV67SeY4Fc1HtI+K+MeMfNbJ/7M26nEw3TvJr/zropKDUgigg9vN/zfabFuGd5U8yOtdEvhzzOoMMWmeSNWo9vPtfuixuKz01dGRq6QVSzcdmHlVxYYnViMuPVk2g20Puc3rjuJM4bkt4gK46hvIaG9WQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120226; c=relaxed/simple; bh=+Hidl1ehKUSK8ydVzl55FyxdRreg3sym0kYT+TQBai8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Rv2xGMa4wmlkYLB2SpwR89hVBeZFjpbnuuCvaiX7j5yZBJg+yl1i24ov48fwWyW4bTWkFUPWodT0e6HS5MJOcIAetob+ysCQOblwNzogtTOJVj2A25q4VFnlBfCt98W6vN+uzSMR+gIhsbsvc+wt28ubg2piQLDBoaHecdldrr0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=aD2x6u1b; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="aD2x6u1b" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-60a20c33f06so29765507b3.2 for ; Fri, 22 Mar 2024 08:10:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1711120223; x=1711725023; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=rrMfPjDTmime8VPkqMYXqjoi2kkgDssgVWNi4eoAsFo=; b=aD2x6u1b6VdYdGYiRrVrpmc1iOK2RVDAKOd0pSWe080t8eXDPvpdpSDSF/oAAf4Lwy qZYvTV45HnOxbj9A+PZVkJ0Z7H/NQYnzhNu0Rg5kk8D6KIuRJVEgk7nyaHNcTroduxVV 4UdX4pJXlShqVOdbQGe7Nzom8Qbl3cIxuWgSoMKO2EZMJNasrGs9djN4NRXa1tbrHP8o Cb2pqxl/r4X07sH5UVFRjsrcXUBV8BqeVPEURl3Ru++KGo9eLDY7fS0d4uDu8+fMj9Mn GYQWDlDpHd9uJ75nO5LISCdx1o1yJoNqQFNz0IW3MAy2NGh5c/7WpYV7oE17bTWehFb7 bhAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711120223; x=1711725023; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=rrMfPjDTmime8VPkqMYXqjoi2kkgDssgVWNi4eoAsFo=; b=QhQOXWRScbTD2ZDMPzLMt/TRz5Hyepfl+FKUOh3gUt8nZ7qj6Ih9GvJQz6xmHBbG32 LRZeZHN0woMwHDov09YNZYvDg9OgadwnEcSHwQzJYUYbHF/jyvFa0k7SQFw41Ww9/X5M VEaDIeYnFHFYB2IuX6l+rLIjBzUqoATUzSv1qPtri7Gc5vBQUkwNdomhUKKU6FtAhWGJ bMaTPrqmGJCUnCk+U8y7STQf8iwyPdeWZddzCvBfntr0sv+ZI6kyzbCaYBcmtO08H5V3 CL06gBeTbMf2dLY2KcKCAcUAFMbL8jYHsSMQEKmHkjpR26TvdY4JpGvOEbVugVd0LD/B Lbpg== X-Gm-Message-State: AOJu0YxE8rGUZhxYymHsqvuHhTzm2/Ut20IZ/MUhb9PePLRR/5QBT07O LCSwxtlnOyyQry3uUvVBTb0hQrI2dR7EnTGAZYFUYwOs+QELhw/RENZkmqY6NruN4lBZN9eSA+d WBTl54Igg1TgL5mEY4NFUijA+DV1x+EJzuTpBezGZ4dhDofsl56YKNBvow0vhqvCw3x9UBCtLkc W3MBDRAKokvPLvqKa4HaaOxJR6VJSHYEhj7Etr3r7cfYiSUoaCruUE X-Google-Smtp-Source: AGHT+IGlES/YNQ9UCh4CUNIF73oHCTUaMPNnteBer91iiVVUBqjuPX3EV2H6/jWDpiW9Dn/g7KKRRLWqLIA= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a81:5213:0:b0:610:ee9b:430c with SMTP id g19-20020a815213000000b00610ee9b430cmr627465ywb.5.1711120223243; Fri, 22 Mar 2024 08:10:23 -0700 (PDT) Date: Fri, 22 Mar 2024 15:09:54 +0000 In-Reply-To: <20240322151002.3653639-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240322151002.3653639-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.396.g6e790dbe36-goog Message-ID: <20240322151002.3653639-2-gnoack@google.com> Subject: [PATCH v11 1/9] fs: Add and use vfs_get_ioctl_handler() From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, Arnd Bergmann , Christian Brauner , " =?utf-8?q?G=C3=BCnther_Noack?= " From: Mickaël Salaün Add a new vfs_get_ioctl_handler() helper to identify if an IOCTL command is handled by the first IOCTL layer. Each IOCTL command is now handled by a dedicated function, and all of them use the same signature. Apart from the VFS, this helper is also intended to be used by Landlock to cleanly categorize VFS IOCTLs and create appropriate security policies. This is an alternative to a first RFC [1] and a proposal for a new LSM hook [2]. By dereferencing some pointers only when required, this should also slightly improve do_vfs_ioctl(). Remove (double) pointer castings on put_user() calls. Remove potential double vfs_ioctl() call for FIONREAD. Fix ioctl_file_clone_range() return type from long to int. Cc: Arnd Bergmann Cc: Christian Brauner Cc: Günther Noack Cc: Paul Moore Link: https://lore.kernel.org/r/20240219183539.2926165-1-mic@digikod.net [1] Link: https://lore.kernel.org/r/20240309075320.160128-2-gnoack@google.com [2] Signed-off-by: Mickaël Salaün --- fs/ioctl.c | 213 +++++++++++++++++++++++++++++++-------------- include/linux/fs.h | 6 ++ 2 files changed, 155 insertions(+), 64 deletions(-) diff --git a/fs/ioctl.c b/fs/ioctl.c index 76cf22ac97d7..d2b6691ded16 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -56,8 +56,9 @@ long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } EXPORT_SYMBOL(vfs_ioctl); -static int ioctl_fibmap(struct file *filp, int __user *p) +static int ioctl_fibmap(struct file *filp, unsigned int fd, unsigned long arg) { + int __user *p = (void __user *)arg; struct inode *inode = file_inode(filp); struct super_block *sb = inode->i_sb; int error, ur_block; @@ -197,11 +198,12 @@ int fiemap_prep(struct inode *inode, struct fiemap_extent_info *fieinfo, } EXPORT_SYMBOL(fiemap_prep); -static int ioctl_fiemap(struct file *filp, struct fiemap __user *ufiemap) +static int ioctl_fiemap(struct file *filp, unsigned int fd, unsigned long arg) { struct fiemap fiemap; struct fiemap_extent_info fieinfo = { 0, }; struct inode *inode = file_inode(filp); + struct fiemap __user *ufiemap = (void __user *)arg; int error; if (!inode->i_op->fiemap) @@ -228,6 +230,18 @@ static int ioctl_fiemap(struct file *filp, struct fiemap __user *ufiemap) return error; } +static int ioctl_figetbsz(struct file *file, unsigned int fd, unsigned long arg) +{ + struct inode *inode = file_inode(file); + int __user *argp = (void __user *)arg; + + /* anon_bdev filesystems may not have a block size */ + if (!inode->i_sb->s_blocksize) + return -EINVAL; + + return put_user(inode->i_sb->s_blocksize, argp); +} + static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd, u64 off, u64 olen, u64 destoff) { @@ -249,9 +263,15 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd, return ret; } -static long ioctl_file_clone_range(struct file *file, - struct file_clone_range __user *argp) +static int ioctl_ficlone(struct file *file, unsigned int fd, unsigned long arg) +{ + return ioctl_file_clone(file, arg, 0, 0, 0); +} + +static int ioctl_file_clone_range(struct file *file, unsigned int fd, + unsigned long arg) { + struct file_clone_range __user *argp = (void __user *)arg; struct file_clone_range args; if (copy_from_user(&args, argp, sizeof(args))) @@ -292,6 +312,27 @@ static int ioctl_preallocate(struct file *filp, int mode, void __user *argp) sr.l_len); } +static int ioctl_resvsp(struct file *filp, unsigned int fd, unsigned long arg) +{ + int __user *p = (void __user *)arg; + + return ioctl_preallocate(filp, 0, p); +} + +static int ioctl_unresvsp(struct file *filp, unsigned int fd, unsigned long arg) +{ + int __user *p = (void __user *)arg; + + return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p); +} + +static int ioctl_zero_range(struct file *filp, unsigned int fd, unsigned long arg) +{ + int __user *p = (void __user *)arg; + + return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p); +} + /* on ia32 l_start is on a 32-bit boundary */ #if defined CONFIG_COMPAT && defined(CONFIG_X86_64) /* just account for different alignment */ @@ -321,28 +362,41 @@ static int compat_ioctl_preallocate(struct file *file, int mode, } #endif -static int file_ioctl(struct file *filp, unsigned int cmd, int __user *p) +static ioctl_handler_t file_ioctl(unsigned int cmd) { switch (cmd) { case FIBMAP: - return ioctl_fibmap(filp, p); + return ioctl_fibmap; case FS_IOC_RESVSP: case FS_IOC_RESVSP64: - return ioctl_preallocate(filp, 0, p); + return ioctl_resvsp; case FS_IOC_UNRESVSP: case FS_IOC_UNRESVSP64: - return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p); + return ioctl_unresvsp; case FS_IOC_ZERO_RANGE: - return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p); + return ioctl_zero_range; } - return -ENOIOCTLCMD; + return NULL; +} + +static int ioctl_fioclex(struct file *file, unsigned int fd, unsigned long arg) +{ + set_close_on_exec(fd, 1); + return 0; +} + +static int ioctl_fionclex(struct file *file, unsigned int fd, unsigned long arg) +{ + set_close_on_exec(fd, 0); + return 0; } -static int ioctl_fionbio(struct file *filp, int __user *argp) +static int ioctl_fionbio(struct file *filp, unsigned int fd, unsigned long arg) { unsigned int flag; int on, error; + int __user *argp = (void __user *)arg; error = get_user(on, argp); if (error) @@ -362,11 +416,11 @@ static int ioctl_fionbio(struct file *filp, int __user *argp) return error; } -static int ioctl_fioasync(unsigned int fd, struct file *filp, - int __user *argp) +static int ioctl_fioasync(struct file *filp, unsigned int fd, unsigned long arg) { unsigned int flag; int on, error; + int __user *argp = (void __user *)arg; error = get_user(on, argp); if (error) @@ -384,7 +438,22 @@ static int ioctl_fioasync(unsigned int fd, struct file *filp, return error < 0 ? error : 0; } -static int ioctl_fsfreeze(struct file *filp) +static int ioctl_fioqsize(struct file *file, unsigned int fd, unsigned long arg) +{ + struct inode *inode = file_inode(file); + void __user *argp = (void __user *)arg; + + if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) || + S_ISLNK(inode->i_mode)) { + loff_t res = inode_get_bytes(inode); + + return copy_to_user(argp, &res, sizeof(res)) ? -EFAULT : 0; + } + + return -ENOTTY; +} + +static int ioctl_fsfreeze(struct file *filp, unsigned int fd, unsigned long arg) { struct super_block *sb = file_inode(filp)->i_sb; @@ -401,7 +470,7 @@ static int ioctl_fsfreeze(struct file *filp) return freeze_super(sb, FREEZE_HOLDER_USERSPACE); } -static int ioctl_fsthaw(struct file *filp) +static int ioctl_fsthaw(struct file *filp, unsigned int fd, unsigned long arg) { struct super_block *sb = file_inode(filp)->i_sb; @@ -414,9 +483,9 @@ static int ioctl_fsthaw(struct file *filp) return thaw_super(sb, FREEZE_HOLDER_USERSPACE); } -static int ioctl_file_dedupe_range(struct file *file, - struct file_dedupe_range __user *argp) +static int ioctl_file_dedupe_range(struct file *file, unsigned int fd, unsigned long arg) { + struct file_dedupe_range __user *argp = (void __user *)arg; struct file_dedupe_range *same = NULL; int ret; unsigned long size; @@ -454,6 +523,14 @@ static int ioctl_file_dedupe_range(struct file *file, return ret; } +static int ioctl_fionread(struct file *filp, unsigned int fd, unsigned long arg) +{ + int __user *argp = (void __user *)arg; + struct inode *inode = file_inode(filp); + + return put_user(i_size_read(inode) - filp->f_pos, argp); +} + /** * fileattr_fill_xflags - initialize fileattr with xflags * @fa: fileattr pointer @@ -702,8 +779,9 @@ int vfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, } EXPORT_SYMBOL(vfs_fileattr_set); -static int ioctl_getflags(struct file *file, unsigned int __user *argp) +static int ioctl_getflags(struct file *file, unsigned int fd, unsigned long arg) { + unsigned int __user *argp = (void __user *)arg; struct fileattr fa = { .flags_valid = true }; /* hint only */ int err; @@ -713,8 +791,9 @@ static int ioctl_getflags(struct file *file, unsigned int __user *argp) return err; } -static int ioctl_setflags(struct file *file, unsigned int __user *argp) +static int ioctl_setflags(struct file *file, unsigned int fd, unsigned long arg) { + unsigned int __user *argp = (void __user *)arg; struct mnt_idmap *idmap = file_mnt_idmap(file); struct dentry *dentry = file->f_path.dentry; struct fileattr fa; @@ -733,8 +812,9 @@ static int ioctl_setflags(struct file *file, unsigned int __user *argp) return err; } -static int ioctl_fsgetxattr(struct file *file, void __user *argp) +static int ioctl_fsgetxattr(struct file *file, unsigned int fd, unsigned long arg) { + struct fsxattr __user *argp = (void __user *)arg; struct fileattr fa = { .fsx_valid = true }; /* hint only */ int err; @@ -745,8 +825,9 @@ static int ioctl_fsgetxattr(struct file *file, void __user *argp) return err; } -static int ioctl_fssetxattr(struct file *file, void __user *argp) +static int ioctl_fssetxattr(struct file *file, unsigned int fd, unsigned long arg) { + struct fsxattr __user *argp = (void __user *)arg; struct mnt_idmap *idmap = file_mnt_idmap(file); struct dentry *dentry = file->f_path.dentry; struct fileattr fa; @@ -764,94 +845,98 @@ static int ioctl_fssetxattr(struct file *file, void __user *argp) } /* - * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. - * It's just a simple helper for sys_ioctl and compat_sys_ioctl. + * Return NULL when no handler exists for @cmd, or the appropriate function + * otherwise. This means that these handlers should never return -ENOIOCTLCMD. * * When you add any new common ioctls to the switches above and below, * please ensure they have compatible arguments in compat mode. */ -static int do_vfs_ioctl(struct file *filp, unsigned int fd, - unsigned int cmd, unsigned long arg) +ioctl_handler_t vfs_get_ioctl_handler(struct file *filp, unsigned int cmd) { - void __user *argp = (void __user *)arg; - struct inode *inode = file_inode(filp); - switch (cmd) { case FIOCLEX: - set_close_on_exec(fd, 1); - return 0; + return ioctl_fioclex; case FIONCLEX: - set_close_on_exec(fd, 0); - return 0; + return ioctl_fionclex; case FIONBIO: - return ioctl_fionbio(filp, argp); + return ioctl_fionbio; case FIOASYNC: - return ioctl_fioasync(fd, filp, argp); + return ioctl_fioasync; case FIOQSIZE: - if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) || - S_ISLNK(inode->i_mode)) { - loff_t res = inode_get_bytes(inode); - return copy_to_user(argp, &res, sizeof(res)) ? - -EFAULT : 0; - } - - return -ENOTTY; + return ioctl_fioqsize; case FIFREEZE: - return ioctl_fsfreeze(filp); + return ioctl_fsfreeze; case FITHAW: - return ioctl_fsthaw(filp); + return ioctl_fsthaw; case FS_IOC_FIEMAP: - return ioctl_fiemap(filp, argp); + return ioctl_fiemap; case FIGETBSZ: - /* anon_bdev filesystems may not have a block size */ - if (!inode->i_sb->s_blocksize) - return -EINVAL; - - return put_user(inode->i_sb->s_blocksize, (int __user *)argp); + return ioctl_figetbsz; case FICLONE: - return ioctl_file_clone(filp, arg, 0, 0, 0); + return ioctl_ficlone; case FICLONERANGE: - return ioctl_file_clone_range(filp, argp); + return ioctl_file_clone_range; case FIDEDUPERANGE: - return ioctl_file_dedupe_range(filp, argp); + return ioctl_file_dedupe_range; case FIONREAD: - if (!S_ISREG(inode->i_mode)) - return vfs_ioctl(filp, cmd, arg); + if (!S_ISREG(file_inode(filp)->i_mode)) + break; - return put_user(i_size_read(inode) - filp->f_pos, - (int __user *)argp); + return ioctl_fionread; case FS_IOC_GETFLAGS: - return ioctl_getflags(filp, argp); + return ioctl_getflags; case FS_IOC_SETFLAGS: - return ioctl_setflags(filp, argp); + return ioctl_setflags; case FS_IOC_FSGETXATTR: - return ioctl_fsgetxattr(filp, argp); + return ioctl_fsgetxattr; case FS_IOC_FSSETXATTR: - return ioctl_fssetxattr(filp, argp); + return ioctl_fssetxattr; default: - if (S_ISREG(inode->i_mode)) - return file_ioctl(filp, cmd, argp); + if (S_ISREG(file_inode(filp)->i_mode)) + return file_ioctl(cmd); break; } - return -ENOIOCTLCMD; + /* Forwards call to vfs_ioctl(filp, cmd, arg) */ + return NULL; +} + +/* + * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. + * It's just a simple helper for sys_ioctl and compat_sys_ioctl. + */ +static int do_vfs_ioctl(struct file *filp, unsigned int fd, + unsigned int cmd, unsigned long arg) +{ + ioctl_handler_t handler = vfs_get_ioctl_handler(filp, cmd); + int ret; + + if (!handler) + return -ENOIOCTLCMD; + + ret = (*handler)(filp, fd, arg); + /* Makes sure handle() really handles this command. */ + if (WARN_ON_ONCE(ret == -ENOIOCTLCMD)) + return -ENOTTY; + + return ret; } SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) diff --git a/include/linux/fs.h b/include/linux/fs.h index 1fbc72c5f112..92bf421aae83 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1904,6 +1904,12 @@ extern long compat_ptr_ioctl(struct file *file, unsigned int cmd, #define compat_ptr_ioctl NULL #endif +typedef int (*ioctl_handler_t)(struct file *file, unsigned int fd, + unsigned long arg); + +extern ioctl_handler_t vfs_get_ioctl_handler(struct file *filp, + unsigned int cmd); + /* * VFS file helper functions. */ From patchwork Fri Mar 22 15:09:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13600246 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D81BA4E1B3 for ; Fri, 22 Mar 2024 15:10:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120228; cv=none; b=cM4PJeZuLgV3xyw/MRZoeV51meHo86Q24MfnrORsLzPlEi0DrkxEF8a+UgLwAdR9vxow/hfbusdg2SO46KnPexzg0LGN7MjH5vLIm6+3tSnaddvClw3zOWt1KMxAnkPh45pxaDLgc+9uytDRh5lxHrSMKpneGn+U8oxRw7XQZeY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120228; c=relaxed/simple; bh=SUlqwgDoB+j6mp3daqLN3lDcVKqBzs5Zdx5JbddS8p8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=rkr9h6Y5xCDJjzxl/aIeB7litNfdwcz79LhaleS/HmUMp8P8oIXL5LDio4zmgxTK9PR76TUTQXl10yWZ+v1K7OMtljrLF40mbX2rDtiuMd8mQ4rakbgOrNmJrluF253eX2l3MQZJ2TTcfSss3NXrLTjQuuf+UuGCAZija3STUCU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=quz2UjAZ; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="quz2UjAZ" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-60ff1816749so37959247b3.3 for ; Fri, 22 Mar 2024 08:10:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1711120226; x=1711725026; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=Sz0NfA7QwlgjZXRVL07X3cjKoeJcVAaE+B0NiSWNqrk=; b=quz2UjAZA/PNAlWw/gkt4KKRCuRFaoT9et67P4b8syFevZDR4RZ8z6yxU0IEYg5/wd oTjDRaeOtDxe3x7/VGR3xhesnm7lhynRmop8ePHc9uIms106kg5NEMNEAmXVx+Z6bLO1 b5IzWxSICYdkIh3s32hgc2lAS8wnoPHBl2hQluyvxCGiDwkVRVWEJup9VnEXbAiUcPF0 3rQYQ6nsv0OFr3ExaSHzFcVzZkTdeRjmc55GOvo/Y8vgMAl5kxJixaBaGlfvJUaWaPuE h/CPUuPFRu2JW+lhl1w9bHZO91e0poZ8hFF2eN7lwzsnZ3nmS2CFD5uJFiQJrSx98G3Y eXEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711120226; x=1711725026; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=Sz0NfA7QwlgjZXRVL07X3cjKoeJcVAaE+B0NiSWNqrk=; b=LTRX2ynkJY3hK2eAD3H1q4QTWYNaem9c0vxYZ4k04LOi+eRHQMQczruSKJltiTBNKU U5ZEKnHvGESdcMyHw7WWo/nFkO3HBAZibCC+Vp+nJnGnqT5c5163C9bthoLfAhGwLqTR aQHzR3BLTEq7CHnSi1ec0hKULP72T47hMHzkZL3cs6mrXWiUH2MANrPJDhT0Q6YLHGHQ SaFEiO6RmOCuvdDXTO/dOUq1x71zaPGArqY5JcKtyv2Mz+7Kh+T+Iot1nvriHQy+86Qs Hz/eVMPtMQxdqZ0mkdRgQjB5LwnyMt+rzu0xpnepL+W8KdpEgfPv/LCrsr4gHqzCD4v8 henw== X-Gm-Message-State: AOJu0YyKEDZX3VMohrVqEB5qeWMh8CYrMt9/euvu4Z6N2VNG6Jr4GRzJ +iomtzlW2hDbFnZhIL0x2Zcx+mAr+Hfufy9otNiwnpHpGCaIZiAs68S70Vj0bmqHN7on5LMTqSB yOX/90DLIMrGIKXe0wbEFg/NFYSXnjNWW2EE/UXcdenb47mBhr+9kIGIkOVsn2riSuyN/90Spwu 0hKwdZmH48q7xM5h+mrsO5FU5eYhZRXjUS68tqPwIMrG84tnpINPD8 X-Google-Smtp-Source: AGHT+IEVl0nVf2PkeBJWX1+vgaRwh9j+KpSXxFnpu62kxn7SmBtWi+DHOmt41T2f5FKy8GzvDuEOQ7REKGw= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a05:6902:230a:b0:dcc:6bf0:2eb6 with SMTP id do10-20020a056902230a00b00dcc6bf02eb6mr54487ybb.6.1711120225591; Fri, 22 Mar 2024 08:10:25 -0700 (PDT) Date: Fri, 22 Mar 2024 15:09:55 +0000 In-Reply-To: <20240322151002.3653639-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240322151002.3653639-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.396.g6e790dbe36-goog Message-ID: <20240322151002.3653639-3-gnoack@google.com> Subject: [PATCH v11 2/9] landlock: Add IOCTL access right for character and block devices From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " , Christian Brauner , Arnd Bergmann Introduces the LANDLOCK_ACCESS_FS_IOCTL_DEV right and increments the Landlock ABI version to 5. This access right applies to device-custom IOCTL commands when they are invoked on block or character device files. Like the truncate right, this right is associated with a file descriptor at the time of open(2), and gets respected even when the file descriptor is used outside of the thread which it was originally opened in. Therefore, a newly enabled Landlock policy does not apply to file descriptors which are already open. If the LANDLOCK_ACCESS_FS_IOCTL_DEV right is handled, only a small number of safe IOCTL commands will be permitted on newly opened device files. These include FIOCLEX, FIONCLEX, FIONBIO and FIOASYNC, as well as other IOCTL commands for regular files which are implemented in fs/ioctl.c. Noteworthy scenarios which require special attention: TTY devices are often passed into a process from the parent process, and so a newly enabled Landlock policy does not retroactively apply to them automatically. In the past, TTY devices have often supported IOCTL commands like TIOCSTI and some TIOCLINUX subcommands, which were letting callers control the TTY input buffer (and simulate keypresses). This should be restricted to CAP_SYS_ADMIN programs on modern kernels though. Known limitations: The LANDLOCK_ACCESS_FS_IOCTL_DEV access right is a coarse-grained control over IOCTL commands. Landlock users may use path-based restrictions in combination with their knowledge about the file system layout to control what IOCTLs can be done. Cc: Paul Moore Cc: Christian Brauner Cc: Arnd Bergmann Signed-off-by: Günther Noack --- include/uapi/linux/landlock.h | 35 ++++++++++--- security/landlock/fs.c | 52 ++++++++++++++++++-- security/landlock/limits.h | 2 +- security/landlock/syscalls.c | 8 ++- tools/testing/selftests/landlock/base_test.c | 2 +- tools/testing/selftests/landlock/fs_test.c | 5 +- 6 files changed, 87 insertions(+), 17 deletions(-) diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h index 25c8d7677539..193733d833b1 100644 --- a/include/uapi/linux/landlock.h +++ b/include/uapi/linux/landlock.h @@ -128,7 +128,7 @@ struct landlock_net_port_attr { * files and directories. Files or directories opened before the sandboxing * are not subject to these restrictions. * - * A file can only receive these access rights: + * The following access rights apply only to files: * * - %LANDLOCK_ACCESS_FS_EXECUTE: Execute a file. * - %LANDLOCK_ACCESS_FS_WRITE_FILE: Open a file with write access. Note that @@ -138,12 +138,13 @@ struct landlock_net_port_attr { * - %LANDLOCK_ACCESS_FS_READ_FILE: Open a file with read access. * - %LANDLOCK_ACCESS_FS_TRUNCATE: Truncate a file with :manpage:`truncate(2)`, * :manpage:`ftruncate(2)`, :manpage:`creat(2)`, or :manpage:`open(2)` with - * ``O_TRUNC``. Whether an opened file can be truncated with - * :manpage:`ftruncate(2)` is determined during :manpage:`open(2)`, in the - * same way as read and write permissions are checked during - * :manpage:`open(2)` using %LANDLOCK_ACCESS_FS_READ_FILE and - * %LANDLOCK_ACCESS_FS_WRITE_FILE. This access right is available since the - * third version of the Landlock ABI. + * ``O_TRUNC``. This access right is available since the third version of the + * Landlock ABI. + * + * Whether an opened file can be truncated with :manpage:`ftruncate(2)` or used + * with `ioctl(2)` is determined during :manpage:`open(2)`, in the same way as + * read and write permissions are checked during :manpage:`open(2)` using + * %LANDLOCK_ACCESS_FS_READ_FILE and %LANDLOCK_ACCESS_FS_WRITE_FILE. * * A directory can receive access rights related to files or directories. The * following access right is applied to the directory itself, and the @@ -198,13 +199,30 @@ struct landlock_net_port_attr { * If multiple requirements are not met, the ``EACCES`` error code takes * precedence over ``EXDEV``. * + * The following access right applies both to files and directories: + * + * - %LANDLOCK_ACCESS_FS_IOCTL_DEV: Invoke :manpage:`ioctl(2)` commands on an opened + * character or block device. + * + * This access right applies to all `ioctl(2)` commands implemented by device + * drivers. However, the following common IOCTL commands continue to be + * invokable independent of the %LANDLOCK_ACCESS_FS_IOCTL_DEV right: + * + * ``FIOCLEX``, ``FIONCLEX``, ``FIONBIO``, ``FIOASYNC``, ``FIOQSIZE``, + * ``FIFREEZE``, ``FITHAW``, ``FS_IOC_FIEMAP``, ``FIGETBSZ``, ``FICLONE``, + * ``FICLONERANGE``, ``FIDEDUPERANGE``, ``FS_IOC_GETFLAGS``, + * ``FS_IOC_SETFLAGS``, ``FS_IOC_FSGETXATTR``, ``FS_IOC_FSSETXATTR`` + * + * This access right is available since the fifth version of the Landlock + * ABI. + * * .. warning:: * * It is currently not possible to restrict some file-related actions * accessible through these syscall families: :manpage:`chdir(2)`, * :manpage:`stat(2)`, :manpage:`flock(2)`, :manpage:`chmod(2)`, * :manpage:`chown(2)`, :manpage:`setxattr(2)`, :manpage:`utime(2)`, - * :manpage:`ioctl(2)`, :manpage:`fcntl(2)`, :manpage:`access(2)`. + * :manpage:`fcntl(2)`, :manpage:`access(2)`. * Future Landlock evolutions will enable to restrict them. */ /* clang-format off */ @@ -223,6 +241,7 @@ struct landlock_net_port_attr { #define LANDLOCK_ACCESS_FS_MAKE_SYM (1ULL << 12) #define LANDLOCK_ACCESS_FS_REFER (1ULL << 13) #define LANDLOCK_ACCESS_FS_TRUNCATE (1ULL << 14) +#define LANDLOCK_ACCESS_FS_IOCTL_DEV (1ULL << 15) /* clang-format on */ /** diff --git a/security/landlock/fs.c b/security/landlock/fs.c index c15559432d3d..30b70d38ddcc 100644 --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -148,7 +148,8 @@ static struct landlock_object *get_inode_object(struct inode *const inode) LANDLOCK_ACCESS_FS_EXECUTE | \ LANDLOCK_ACCESS_FS_WRITE_FILE | \ LANDLOCK_ACCESS_FS_READ_FILE | \ - LANDLOCK_ACCESS_FS_TRUNCATE) + LANDLOCK_ACCESS_FS_TRUNCATE | \ + LANDLOCK_ACCESS_FS_IOCTL_DEV) /* clang-format on */ /* @@ -1335,8 +1336,10 @@ static int hook_file_alloc_security(struct file *const file) static int hook_file_open(struct file *const file) { layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {}; - access_mask_t open_access_request, full_access_request, allowed_access; - const access_mask_t optional_access = LANDLOCK_ACCESS_FS_TRUNCATE; + access_mask_t open_access_request, full_access_request, allowed_access, + optional_access; + const struct inode *inode = file_inode(file); + const bool is_device = S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode); const struct landlock_ruleset *const dom = get_fs_domain(landlock_cred(file->f_cred)->domain); @@ -1354,6 +1357,10 @@ static int hook_file_open(struct file *const file) * We look up more access than what we immediately need for open(), so * that we can later authorize operations on opened files. */ + optional_access = LANDLOCK_ACCESS_FS_TRUNCATE; + if (is_device) + optional_access |= LANDLOCK_ACCESS_FS_IOCTL_DEV; + full_access_request = open_access_request | optional_access; if (is_access_to_paths_allowed( @@ -1410,6 +1417,43 @@ static int hook_file_truncate(struct file *const file) return -EACCES; } +static int hook_file_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + const struct inode *inode = file_inode(file); + const bool is_device = S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode); + access_mask_t required_access, allowed_access; + + if (!is_device) + return 0; + + /* + * We permit IOCTL commands which have a do_vfs_ioctl handler for the + * given file. + */ + if (vfs_get_ioctl_handler(file, cmd)) + return 0; + + /* + * It is the access rights at the time of opening the file which + * determine whether IOCTL can be used on the opened file later. + * + * The access right is attached to the opened file in hook_file_open(). + */ + required_access = LANDLOCK_ACCESS_FS_IOCTL_DEV; + allowed_access = landlock_file(file)->allowed_access; + if ((allowed_access & required_access) == required_access) + return 0; + + return -EACCES; +} + +static int hook_file_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return hook_file_ioctl(file, cmd, arg); +} + static struct security_hook_list landlock_hooks[] __ro_after_init = { LSM_HOOK_INIT(inode_free_security, hook_inode_free_security), @@ -1432,6 +1476,8 @@ static struct security_hook_list landlock_hooks[] __ro_after_init = { LSM_HOOK_INIT(file_alloc_security, hook_file_alloc_security), LSM_HOOK_INIT(file_open, hook_file_open), LSM_HOOK_INIT(file_truncate, hook_file_truncate), + LSM_HOOK_INIT(file_ioctl, hook_file_ioctl), + LSM_HOOK_INIT(file_ioctl_compat, hook_file_ioctl_compat), }; __init void landlock_add_fs_hooks(void) diff --git a/security/landlock/limits.h b/security/landlock/limits.h index 93c9c6f91556..20fdb5ff3514 100644 --- a/security/landlock/limits.h +++ b/security/landlock/limits.h @@ -18,7 +18,7 @@ #define LANDLOCK_MAX_NUM_LAYERS 16 #define LANDLOCK_MAX_NUM_RULES U32_MAX -#define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_TRUNCATE +#define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_IOCTL_DEV #define LANDLOCK_MASK_ACCESS_FS ((LANDLOCK_LAST_ACCESS_FS << 1) - 1) #define LANDLOCK_NUM_ACCESS_FS __const_hweight64(LANDLOCK_MASK_ACCESS_FS) #define LANDLOCK_SHIFT_ACCESS_FS 0 diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c index 6788e73b6681..9ae3dfa47443 100644 --- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c @@ -149,7 +149,7 @@ static const struct file_operations ruleset_fops = { .write = fop_dummy_write, }; -#define LANDLOCK_ABI_VERSION 4 +#define LANDLOCK_ABI_VERSION 5 /** * sys_landlock_create_ruleset - Create a new ruleset @@ -321,7 +321,11 @@ static int add_rule_path_beneath(struct landlock_ruleset *const ruleset, if (!path_beneath_attr.allowed_access) return -ENOMSG; - /* Checks that allowed_access matches the @ruleset constraints. */ + /* + * Checks that allowed_access matches the @ruleset constraints and only + * consists of publicly visible access rights (as opposed to synthetic + * ones). + */ mask = landlock_get_raw_fs_access_mask(ruleset, 0); if ((path_beneath_attr.allowed_access | mask) != mask) return -EINVAL; diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c index 646f778dfb1e..d292b419ccba 100644 --- a/tools/testing/selftests/landlock/base_test.c +++ b/tools/testing/selftests/landlock/base_test.c @@ -75,7 +75,7 @@ TEST(abi_version) const struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, }; - ASSERT_EQ(4, landlock_create_ruleset(NULL, 0, + ASSERT_EQ(5, landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION)); ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index 2d6d9b43d958..0bcbbf594fd7 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -527,9 +527,10 @@ TEST_F_FORK(layout1, inval) LANDLOCK_ACCESS_FS_EXECUTE | \ LANDLOCK_ACCESS_FS_WRITE_FILE | \ LANDLOCK_ACCESS_FS_READ_FILE | \ - LANDLOCK_ACCESS_FS_TRUNCATE) + LANDLOCK_ACCESS_FS_TRUNCATE | \ + LANDLOCK_ACCESS_FS_IOCTL_DEV) -#define ACCESS_LAST LANDLOCK_ACCESS_FS_TRUNCATE +#define ACCESS_LAST LANDLOCK_ACCESS_FS_IOCTL_DEV #define ACCESS_ALL ( \ ACCESS_FILE | \ From patchwork Fri Mar 22 15:09:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13600247 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-ej1-f73.google.com (mail-ej1-f73.google.com [209.85.218.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A81A4F615 for ; Fri, 22 Mar 2024 15:10:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120231; cv=none; b=FW2Gu1izvancmnm6eKzXuTwofqIh779KGWFXvYujI9dlKCqtxv0UQrVILGF3hvvlD4Gxf15b7EXK63TvDkgbBV5+X9sRxtXKXoJiHJz+9+4wW+m9B5fcjolxmIQUvr7LkRpsR3SjfOfD7tu4Uwi/Qee5E4azrXOCUETmOX8FEB0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120231; c=relaxed/simple; bh=Zui2v1od/elMRFrLL3WvczuYkqdRJ607JihPTYWoBxc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=MDBNzkbQl4sTvJPHnbzyHZNet5pdDucYuBNHXk6CWkhDCsLb0kqtqbzIRytW4UwiuMdsw9g7HXYpTJLfEyzqZRbTQiTT7gZQQJ0dDCIdm0nzL4mZ7YOFLYX52DG7QcDMzSQVbCJQl9nSzNUaJSvQytLCcgQ2pe7Ld3vjTtsAylM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ZXDtZmIg; arc=none smtp.client-ip=209.85.218.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ZXDtZmIg" Received: by mail-ej1-f73.google.com with SMTP id a640c23a62f3a-a4715d8c761so117805666b.1 for ; Fri, 22 Mar 2024 08:10:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1711120228; x=1711725028; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=l9e1vLBZyU81CA03W1c5FAr2hW3zhJCc3KJ54WTxEPY=; b=ZXDtZmIguQVMivdv/eOsPXtjuDZHr9Zqhl9lzMxoNPQaM6bghCdX9BR9HjPo0/d6TB gC3YxZht84HQh5/8MNoktYxrWaot4+JcaCjOaHpRFF0OX7cNA411EuVySrRLMJ9l+Rf0 guGWShjFk36qUjkkgPoCKYnnuD3SwxAl8VkHPSuvkCb2TVtMAB2fJ4BcJvjsPWe6kLIL 32Q6ahNBOudnMXoMvoTzeuoELpL8UsnS7I2aOh2UpJbPdbnKfivHlDVXOSNlxejByaYK LVjBIaJCbJVbt1UdrF0qW0YLSWUq1Dr51DazQFCnmw5foedCFL1ZzK4wXLPrH2u5Uxs4 B2PA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711120228; x=1711725028; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=l9e1vLBZyU81CA03W1c5FAr2hW3zhJCc3KJ54WTxEPY=; b=HwBqjtcJ14Bc1Z+vSaZ1VtURF+n3ozKKV+ExMxmk0WYnlq/oCqKvaXahUVp+zDY2Aw pCEv2bx4XVAgbUgudvpzgSypHEXODaFkrW7bEUWaeeyOXSne1AJEVGIcbxVSAd1hfZGp nACRu/rxFsLNtDcBLDtCt/2LgJ3QsTSRn7CAs0G1liQch2/p3vkzbwhT1vBLQRmzZffs 3UWPOBY89+UIfwLq6IZ/vV/Aam6sW4UySwacfVqzNUKHYGZFfA3RJO+gtAKmgbZqnDXA g0eQ8nznxSiwNqNFaCf/zaoIWXmFXItGPhEri/G1Ip7v9rTflN+3zw5S0tkp25+jzW7I yXtA== X-Gm-Message-State: AOJu0YwT7L6UJAr8IvEcvHEnC6gV4UrNz01Qlu/gbjafbyw/vTPhcuBa 68YslCWtZALsudAZJVP4HD2MYIOuHnEyx2nKWduwNik3mMhKB0/yR7PO+TWSBfTOeYGmvGBlNy+ jRUAyGzP+XDYWOqDKEDywJBsxRYYvVJuUPepBMH4K1QahcCs0VSM46Al0KAU7Whp0WMNJumbGPM 7LLgsrQgUSNYKxfo+8r17eoKAGFFtCS9XAy4XuaXf/DnuT4r+1aeM3 X-Google-Smtp-Source: AGHT+IG6Ca8DZ4cAM6ldO7A7OzePRWTyWzZ4f5MoTIu+1T3g5D4zS1hMo9S/KsL/azFqdsCMVJKywOvmTqo= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a17:907:2669:b0:a47:33f1:3ba with SMTP id ci9-20020a170907266900b00a4733f103bamr3ejc.10.1711120227818; Fri, 22 Mar 2024 08:10:27 -0700 (PDT) Date: Fri, 22 Mar 2024 15:09:56 +0000 In-Reply-To: <20240322151002.3653639-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240322151002.3653639-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.396.g6e790dbe36-goog Message-ID: <20240322151002.3653639-4-gnoack@google.com> Subject: [PATCH v11 3/9] selftests/landlock: Test IOCTL support From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " Exercises Landlock's IOCTL feature in different combinations of handling and permitting the LANDLOCK_ACCESS_FS_IOCTL_DEV right, and in different combinations of using files and directories. Signed-off-by: Günther Noack --- tools/testing/selftests/landlock/fs_test.c | 236 ++++++++++++++++++++- 1 file changed, 233 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index 0bcbbf594fd7..22229fe3e403 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -8,6 +8,7 @@ */ #define _GNU_SOURCE +#include #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +25,12 @@ #include #include +/* + * Intentionally included last to work around header conflict. + * See https://sourceware.org/glibc/wiki/Synchronizing_Headers. + */ +#include + #include "common.h" #ifndef renameat2 @@ -735,6 +743,9 @@ static int create_ruleset(struct __test_metadata *const _metadata, } for (i = 0; rules[i].path; i++) { + if (!rules[i].access) + continue; + add_path_beneath(_metadata, ruleset_fd, rules[i].access, rules[i].path); } @@ -3443,7 +3454,7 @@ TEST_F_FORK(layout1, truncate_unhandled) LANDLOCK_ACCESS_FS_WRITE_FILE; int ruleset_fd; - /* Enable Landlock. */ + /* Enables Landlock. */ ruleset_fd = create_ruleset(_metadata, handled, rules); ASSERT_LE(0, ruleset_fd); @@ -3526,7 +3537,7 @@ TEST_F_FORK(layout1, truncate) LANDLOCK_ACCESS_FS_TRUNCATE; int ruleset_fd; - /* Enable Landlock. */ + /* Enables Landlock. */ ruleset_fd = create_ruleset(_metadata, handled, rules); ASSERT_LE(0, ruleset_fd); @@ -3752,7 +3763,7 @@ TEST_F_FORK(ftruncate, open_and_ftruncate) }; int fd, ruleset_fd; - /* Enable Landlock. */ + /* Enables Landlock. */ ruleset_fd = create_ruleset(_metadata, variant->handled, rules); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); @@ -3829,6 +3840,16 @@ TEST_F_FORK(ftruncate, open_and_ftruncate_in_different_processes) ASSERT_EQ(0, close(socket_fds[1])); } +/* Invokes the FS_IOC_GETFLAGS IOCTL and returns its errno or 0. */ +static int test_fs_ioc_getflags_ioctl(int fd) +{ + uint32_t flags; + + if (ioctl(fd, FS_IOC_GETFLAGS, &flags) < 0) + return errno; + return 0; +} + TEST(memfd_ftruncate) { int fd; @@ -3845,6 +3866,215 @@ TEST(memfd_ftruncate) ASSERT_EQ(0, close(fd)); } +static int test_fionread_ioctl(int fd) +{ + size_t sz = 0; + + if (ioctl(fd, FIONREAD, &sz) < 0 && errno == EACCES) + return errno; + return 0; +} + +/* clang-format off */ +FIXTURE(ioctl) {}; + +FIXTURE_SETUP(ioctl) {}; + +FIXTURE_TEARDOWN(ioctl) {}; +/* clang-format on */ + +FIXTURE_VARIANT(ioctl) +{ + const __u64 handled; + const __u64 allowed; + const mode_t open_mode; + /* + * TCGETS is used as a characteristic device-specific IOCTL command. + * The logic is the same for other IOCTL commands as well. + */ + const int expected_tcgets_result; /* terminal device IOCTL */ + /* + * FIONREAD is implemented in fs/ioctl.c for regular files, + * but we do not blanket-permit it for devices. + */ + const int expected_fionread_result; +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ioctl, handled_i_allowed_none) { + /* clang-format on */ + .handled = LANDLOCK_ACCESS_FS_IOCTL_DEV, + .allowed = 0, + .open_mode = O_RDWR, + .expected_tcgets_result = EACCES, + .expected_fionread_result = EACCES, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ioctl, handled_i_allowed_i) { + /* clang-format on */ + .handled = LANDLOCK_ACCESS_FS_IOCTL_DEV, + .allowed = LANDLOCK_ACCESS_FS_IOCTL_DEV, + .open_mode = O_RDWR, + .expected_tcgets_result = 0, + .expected_fionread_result = 0, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ioctl, unhandled) { + /* clang-format on */ + .handled = LANDLOCK_ACCESS_FS_EXECUTE, + .allowed = LANDLOCK_ACCESS_FS_EXECUTE, + .open_mode = O_RDWR, + .expected_tcgets_result = 0, + .expected_fionread_result = 0, +}; + +static int test_fioqsize_ioctl(int fd) +{ + size_t sz; + + if (ioctl(fd, FIOQSIZE, &sz) < 0) + return errno; + return 0; +} + +static int test_tcgets_ioctl(int fd) +{ + struct termios info; + + if (ioctl(fd, TCGETS, &info) < 0) + return errno; + return 0; +} + +TEST_F_FORK(ioctl, handle_dir_access_file) +{ + const int flag = 0; + const struct rule rules[] = { + { + .path = "/dev", + .access = variant->allowed, + }, + {}, + }; + int file_fd, ruleset_fd; + + /* Enables Landlock. */ + ruleset_fd = create_ruleset(_metadata, variant->handled, rules); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + file_fd = open("/dev/tty", variant->open_mode); + ASSERT_LE(0, file_fd); + + /* Checks that IOCTL commands return the expected errors. */ + EXPECT_EQ(variant->expected_tcgets_result, test_tcgets_ioctl(file_fd)); + EXPECT_EQ(variant->expected_fionread_result, + test_fionread_ioctl(file_fd)); + + /* Checks that unrestrictable commands are unrestricted. */ + EXPECT_EQ(0, ioctl(file_fd, FIOCLEX)); + EXPECT_EQ(0, ioctl(file_fd, FIONCLEX)); + EXPECT_EQ(0, ioctl(file_fd, FIONBIO, &flag)); + EXPECT_EQ(0, ioctl(file_fd, FIOASYNC, &flag)); + EXPECT_EQ(ENOTTY, test_fioqsize_ioctl(file_fd)); + + ASSERT_EQ(0, close(file_fd)); +} + +TEST_F_FORK(ioctl, handle_dir_access_dir) +{ + const int flag = 0; + const struct rule rules[] = { + { + .path = "/dev", + .access = variant->allowed, + }, + {}, + }; + int dir_fd, ruleset_fd; + + /* Enables Landlock. */ + ruleset_fd = create_ruleset(_metadata, variant->handled, rules); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* + * Ignore variant->open_mode for this test, as we intend to open a + * directory. If the directory can not be opened, the variant is + * infeasible to test with an opened directory. + */ + dir_fd = open("/dev", O_RDONLY); + if (dir_fd < 0) + return; + + /* + * Checks that IOCTL commands return the expected errors. + * We do not use the expected values from the fixture here. + * + * When using IOCTL on a directory, no Landlock restrictions apply. + * TCGETS will fail anyway because it is not invoked on a TTY device. + */ + EXPECT_EQ(ENOTTY, test_tcgets_ioctl(dir_fd)); + EXPECT_EQ(0, test_fionread_ioctl(dir_fd)); + + /* Checks that unrestrictable commands are unrestricted. */ + EXPECT_EQ(0, ioctl(dir_fd, FIOCLEX)); + EXPECT_EQ(0, ioctl(dir_fd, FIONCLEX)); + EXPECT_EQ(0, ioctl(dir_fd, FIONBIO, &flag)); + EXPECT_EQ(0, ioctl(dir_fd, FIOASYNC, &flag)); + EXPECT_EQ(0, test_fioqsize_ioctl(dir_fd)); + + ASSERT_EQ(0, close(dir_fd)); +} + +TEST_F_FORK(ioctl, handle_file_access_file) +{ + const int flag = 0; + const struct rule rules[] = { + { + .path = "/dev/tty0", + .access = variant->allowed, + }, + {}, + }; + int file_fd, ruleset_fd; + + if (variant->allowed & LANDLOCK_ACCESS_FS_READ_DIR) { + SKIP(return, "LANDLOCK_ACCESS_FS_READ_DIR " + "can not be granted on files"); + } + + /* Enables Landlock. */ + ruleset_fd = create_ruleset(_metadata, variant->handled, rules); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + file_fd = open("/dev/tty0", variant->open_mode); + ASSERT_LE(0, file_fd) + { + TH_LOG("Failed to open /dev/tty0: %s", strerror(errno)); + } + + /* Checks that IOCTL commands return the expected errors. */ + EXPECT_EQ(variant->expected_tcgets_result, test_tcgets_ioctl(file_fd)); + EXPECT_EQ(variant->expected_fionread_result, + test_fionread_ioctl(file_fd)); + + /* Checks that unrestrictable commands are unrestricted. */ + EXPECT_EQ(0, ioctl(file_fd, FIOCLEX)); + EXPECT_EQ(0, ioctl(file_fd, FIONCLEX)); + EXPECT_EQ(0, ioctl(file_fd, FIONBIO, &flag)); + EXPECT_EQ(0, ioctl(file_fd, FIOASYNC, &flag)); + EXPECT_EQ(ENOTTY, test_fioqsize_ioctl(file_fd)); + + ASSERT_EQ(0, close(file_fd)); +} + /* clang-format off */ FIXTURE(layout1_bind) {}; /* clang-format on */ From patchwork Fri Mar 22 15:09:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13600248 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-ej1-f74.google.com (mail-ej1-f74.google.com [209.85.218.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 740F54DA16 for ; Fri, 22 Mar 2024 15:10:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120235; cv=none; b=bUZETkt5amr58gDNvo+KRqxuhgC1ugCs+GE+5zHObAN7b87wKsQB7S0VQX6gUXCR7OXIkEFcvWBSmZ6gY6amzZf4FBLlJWuoM2ldHlRMt+dFUyY7GR5rp/U4CNk5ztVvnFfn6jaOVz70SWoFMuUDKkTB+CwTLIvBOF+Xt5rm+Fs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120235; c=relaxed/simple; bh=Jdal8IKILETTWsojG5pDXheVDyQeR66rUe3RKtiUO/I=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LAMfjkWBxXJlqggNNNdjsTpJFjlj9OMBpSq0YTmvi5MVtRzOTBq34tMxTrSjoaCgfCiRt77Jj7oggcavKb1zJWB+WzmxY8K3/foD8yj8pSlUXndz0S5pP4qs+zIh3XVZLHNshnQufC469dHzfFs3a0LmuaYf7FK3mQFCM+CZKu8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=bU6hjMje; arc=none smtp.client-ip=209.85.218.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="bU6hjMje" Received: by mail-ej1-f74.google.com with SMTP id a640c23a62f3a-a471cf9c035so39211266b.3 for ; Fri, 22 Mar 2024 08:10:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1711120231; x=1711725031; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=qobHCRmb6cXg9TV4MF/PMa0SUI8jbJIaeOrvT83hbEo=; b=bU6hjMjePveUDucSLDn8BySlkBy3CDd27PP1gsW/OmGgY3ZIg9xZCE6iURr+OIjPj1 hqni29jfjGfdlCtNMdjgwqGyZsDk+hAUmd9uAPx+sQqV6PlFFPCRlUKxyDEe6nZ/b9CN BKoMp/E+vrHPa2TKonVLWWpzsoXS1gL3DQkPDbseyK5mgtOFMDD7RVkH9HS59xoqx0Mw u3dogKvsP02RuL5N59PkrRaiB74/SK3wTlmQDl27hl/q5xsIyPQsOIpzp5QXu2tuOb7Y UPCgIy4yFvyH+CMq9NTHx+hpcVWKYQeHhnJm6XjbsitzfQ4lZTy2WrYhDuGgtz690Dlk 4gEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711120231; x=1711725031; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=qobHCRmb6cXg9TV4MF/PMa0SUI8jbJIaeOrvT83hbEo=; b=G/NI/50akrb0CDjj9OrNP4jnK0wMHFWjDzybQFhdzbvbVUZJJAT284iYddTHQIQhyO 6xmLO9m6zcswDj1qwbXEmVFmZzb3L+aAM6GIhmYP4rbO/X7QoM9tF523EG/cYqTTvCNI Soee+v7bEbbZ9cfV/ecDrsAMeLcMGRMXQZM8NU3/xUdZhH5ifRJvBR4Ld9O105XJ4mbh 1+vHuHUQqatHBQjcpiBsznqUsolcnKpRsn2aWkVOSa31affQ2MBcQ8XSkED0TtuS3Kux cSGsmrOGYhkcnr2eAY3cf4GSHEVQymuZrl2QcyDyka1LqcLUUqPG35RZ5P6L+ABohY1x VZ8g== X-Gm-Message-State: AOJu0YzStTZ9ya+YYdWfoIFTX/tIWqX9NqlMOvdUlQy05lxctHqS1YWE LfI+lY7tc2Az+Uw5TU4BOi56HWsFAcxqs1e4+dRGmMBg9SusBwA2NI5rxOHIO/CEchimDMeL12m wmLNWPmV5bKOU55mgxLGfC82O7owLYA5/2/jo5m45Cp0pFBRCvdtDZN5QhhIVvnZGHHOOkdqkQb KuEvTEfV4ixOEjw6bbGcbkLgdAHGylqWnmHoDLoeQwtpeBNq0kDNO4 X-Google-Smtp-Source: AGHT+IGKONiWvctPFgaXTgXqq9xxHFVwjT49Su0OSiBo8MX70YapJ4UVh8nInJsSxxBNK14VBxvLp0hWONE= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a17:906:a1d0:b0:a47:1499:6de0 with SMTP id bx16-20020a170906a1d000b00a4714996de0mr0ejb.7.1711120230227; Fri, 22 Mar 2024 08:10:30 -0700 (PDT) Date: Fri, 22 Mar 2024 15:09:57 +0000 In-Reply-To: <20240322151002.3653639-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240322151002.3653639-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.396.g6e790dbe36-goog Message-ID: <20240322151002.3653639-5-gnoack@google.com> Subject: [PATCH v11 4/9] selftests/landlock: Test IOCTL with memfds From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " Because the LANDLOCK_ACCESS_FS_IOCTL_DEV right is associated with the opened file during open(2), IOCTLs are supposed to work with files which are opened by means other than open(2). Signed-off-by: Günther Noack --- tools/testing/selftests/landlock/fs_test.c | 36 ++++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index 22229fe3e403..32a77757462b 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -3850,20 +3850,38 @@ static int test_fs_ioc_getflags_ioctl(int fd) return 0; } -TEST(memfd_ftruncate) +TEST(memfd_ftruncate_and_ioctl) { - int fd; - - fd = memfd_create("name", MFD_CLOEXEC); - ASSERT_LE(0, fd); + const struct landlock_ruleset_attr attr = { + .handled_access_fs = ACCESS_ALL, + }; + int ruleset_fd, fd, i; /* - * Checks that ftruncate is permitted on file descriptors that are - * created in ways other than open(2). + * We exercise the same test both with and without Landlock enabled, to + * ensure that it behaves the same in both cases. */ - EXPECT_EQ(0, test_ftruncate(fd)); + for (i = 0; i < 2; i++) { + /* Creates a new memfd. */ + fd = memfd_create("name", MFD_CLOEXEC); + ASSERT_LE(0, fd); - ASSERT_EQ(0, close(fd)); + /* + * Checks that operations associated with the opened file + * (ftruncate, ioctl) are permitted on file descriptors that are + * created in ways other than open(2). + */ + EXPECT_EQ(0, test_ftruncate(fd)); + EXPECT_EQ(0, test_fs_ioc_getflags_ioctl(fd)); + + ASSERT_EQ(0, close(fd)); + + /* Enables Landlock. */ + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + } } static int test_fionread_ioctl(int fd) From patchwork Fri Mar 22 15:09:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13600249 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CDC724E1C4 for ; Fri, 22 Mar 2024 15:10:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120235; cv=none; b=AlmBZQ8wa9HZHr2HVUjtZsXfLKLotUQZbojqmBOyUZ2muMDXXCmrjLDRsUd+EtDcY34vx5+loWVig0GY999JYao/M1oA9kzSQ9UDh8oHlUw6xDWuKN3Fl8OvzurrA8kzRXASppBc9iUCRzurmzexrSOa147ENFuAiyKlBWltSMM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120235; c=relaxed/simple; bh=HzbXoAKj1O2Axw/b80Ha7oRq747pOMPBeo9PHNh77I4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=AH+ijm6L5nQiqMoWjrPUpBLuYfIm/eOBiESgN4YSj1XC4Rn1a8F71Yx/W4itEElB3dHYXHoVd8ay2DWpuYIYqssyDVpWorQ8jdhrmX3ez+zzxG51hPoLXIC0tN/2L6/oL3/OUG/X8As9VuFD4SgoyhMdHJ84eDBCUxrf92wTSMg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=1v7j8ggj; arc=none smtp.client-ip=209.85.128.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="1v7j8ggj" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-60cbba6fa0bso42942637b3.3 for ; Fri, 22 Mar 2024 08:10:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1711120233; x=1711725033; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=WK2iXIrfoq6Fz3IO0C5eVV32OG2FmcAULBO6/ELXu64=; b=1v7j8ggj6NwLNkUhsMNVaDxzFqBz3qp3KXXWb/6DM/utylO4tpyqxkNoCmuaUzN2IH xmMdWOxzGm13IbxuIjQSLbEzFviu4iFGJRPbUUKLsm1JxqehnhZ1bWxiOHXWp+njmbOQ xH9pLh+ZgvLQCmJNxWHZX1Y+iWHy3sZMEFeMPMwk5+wEWA8JYjxDnM80H3ZNyR7p3ftg FFHXu6p7qbn94inFIv1bPvBLccJlpbXkyVJu5dVYw8nMUGK/rw5keL7WUnpNLlrh5Ce/ 6wZ1xVJduQbtEm60rmajcq7b9YhWcCPnT33LelNi8yVuMvp0Z+pEZdM8xDXsHE8TsFbZ GlJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711120233; x=1711725033; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=WK2iXIrfoq6Fz3IO0C5eVV32OG2FmcAULBO6/ELXu64=; b=UxY+EhldceLsPjAM/S3tEixrYuNgWf5hXI3GQYGsKP+JAqNJFJe+HWHe6tf6VNngVM oxM7G9txV50hdcLCXQvum/zr3KTwSNDOmUfxzOXt39qhA7AoXSbXx52aksiTK8Aov5sF iEWq6TrgHtJBNl6MsLyK5qhVgKExGebZ7QjgQASxYXJvT+9ABNaTnFtzHxPt79PWLYOi TvA5gi9wMGRgGz0bQUb0F+UwujEq7ICzGrKfM3mEjm17tTWceUOR61LURDIxtSuNOFDP 42ryD05yRSODvBzz4MTRCN50WlPe5rGe22N4fUdODuKQb5/VCX3hYm+j0i4YtC1LNbnf tJ6A== X-Gm-Message-State: AOJu0YzArstODCvJpD6Wy7rhb+KfBEWXlbnwzNBzxmviHTDZU8g/UkYD cUMMmS2NR2MrHZh2PKf2duH7O41ZHG2RGdI2YJOF6H2rxJU+B9lJp9dP5r666VgFrNPfMPDgHKb AX7UMUgId5e/20WXxjtx5jJha3g9VuW2PyUU3PXoqagWruDIEuLoZXv4ycSZShnsxZV752iR4D/ 8A6JKgJsvld41i7cbfKvtJYKpjFThc+NRImT0D7FNGdhQ05gaJaoW7 X-Google-Smtp-Source: AGHT+IE/skOcqhwr+ZTj08fMTLjErgP9sxDZA9kKjc1KHwbR43EKvperDiZY9OJDs96Y5WSECFwxnpc28bg= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a81:9c0d:0:b0:611:2ae5:2ea7 with SMTP id m13-20020a819c0d000000b006112ae52ea7mr151930ywa.6.1711120232760; Fri, 22 Mar 2024 08:10:32 -0700 (PDT) Date: Fri, 22 Mar 2024 15:09:58 +0000 In-Reply-To: <20240322151002.3653639-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240322151002.3653639-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.396.g6e790dbe36-goog Message-ID: <20240322151002.3653639-6-gnoack@google.com> Subject: [PATCH v11 5/9] selftests/landlock: Test ioctl(2) and ftruncate(2) with open(O_PATH) From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " ioctl(2) and ftruncate(2) operations on files opened with O_PATH should always return EBADF, independent of the LANDLOCK_ACCESS_FS_TRUNCATE and LANDLOCK_ACCESS_FS_IOCTL_DEV access rights in that file hierarchy. Suggested-by: Mickaël Salaün Signed-off-by: Günther Noack --- tools/testing/selftests/landlock/fs_test.c | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index 32a77757462b..dde4673e2df4 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -3893,6 +3893,46 @@ static int test_fionread_ioctl(int fd) return 0; } +TEST_F_FORK(layout1, o_path_ftruncate_and_ioctl) +{ + const struct landlock_ruleset_attr attr = { + .handled_access_fs = ACCESS_ALL, + }; + int ruleset_fd, fd; + + /* + * Checks that for files opened with O_PATH, both ioctl(2) and + * ftruncate(2) yield EBADF, as it is documented in open(2) for the + * O_PATH flag. + */ + fd = open(dir_s1d1, O_PATH | O_CLOEXEC); + ASSERT_LE(0, fd); + + EXPECT_EQ(EBADF, test_ftruncate(fd)); + EXPECT_EQ(EBADF, test_fs_ioc_getflags_ioctl(fd)); + + ASSERT_EQ(0, close(fd)); + + /* Enables Landlock. */ + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* + * Checks that after enabling Landlock, + * - the file can still be opened with O_PATH + * - both ioctl and truncate still yield EBADF (not EACCES). + */ + fd = open(dir_s1d1, O_PATH | O_CLOEXEC); + ASSERT_LE(0, fd); + + EXPECT_EQ(EBADF, test_ftruncate(fd)); + EXPECT_EQ(EBADF, test_fs_ioc_getflags_ioctl(fd)); + + ASSERT_EQ(0, close(fd)); +} + /* clang-format off */ FIXTURE(ioctl) {}; From patchwork Fri Mar 22 15:09:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13600250 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B37151C4F for ; Fri, 22 Mar 2024 15:10:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120237; cv=none; b=tOg6bicQrX/6Xg+axXSSYVAfyH+yDZBUJ+IRQeYY7+c392fdvCfyzBaz4sw6IAog0lLQmXvxSNs2+mw62Lzo+YAv2Mj9LP2XemXbStLKM4EoNhxgF2q5Amkl+i9cf29BJldIPRv5tZ/xTQOmMIQg9mu5MCjXnhF/QQdF+pjKCac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120237; c=relaxed/simple; bh=4Wux5xa/CaSDeSCUYomCmTq0IllWEfYpxAtQo5oE6Es=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=PeGWqBCSNCyvlEN/wT4Bpuo9SyY6fee0n/eeftoBeN1OmLXcI0H4SMIzNPLivlyGzpedArjPrP37bGnim7hL3BsrIkQYWajoEikP23FoD6Mvo17d9S/W5x0WKT5ZI354+sOCg/8YfhVIGiZlBU8dQ9/YHlY3ucGpUV1jVr5VGZE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=peNyGOeC; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="peNyGOeC" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dd0ae66422fso4306798276.0 for ; Fri, 22 Mar 2024 08:10:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1711120235; x=1711725035; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=wVuQbOd4o/tS0DiPUw74ee5jBWWOCcrb2jESG2kQjGE=; b=peNyGOeC8vSxwz3XojdjjoNgm5aCiv1hqGFDTPkWg6bH2Ck9Sy9f4ZJ87SG3vaewUS XuFRIjSrBuQBXbIPUFac4xmcsFBczcEwZoJ8+xiH6STg5LKEDpZVqMvNREabJx9KgpH/ QUq4o1IM3w6aXpjqC4Lc4EnPhZSiqCAk7UcwCLLhb5l0e0Yy3KJEFy66teZwbCUBr2io btoo1/j47SDxqsHW20OhupR8/M7ZNn+XHHiZLSRFLbRvuVEbeoTWPPH0IV0HErFLUFcY uSQKjYx5yWpguwMNYu8hnAvrxkyC48w74U3i3fPZSTlU1O1rBLXMXShRxPiuiVd0M8KP /aVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711120235; x=1711725035; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=wVuQbOd4o/tS0DiPUw74ee5jBWWOCcrb2jESG2kQjGE=; b=prd4De6ypKL8/F8G+nTI+ydx4jQctntdxcjXtPDEJ2yATTMe+Pub1tmTDszXswO8gn WeGk52lL977da0BYJvsw/E/DK6FVymT76CWS7dEuM23uFso+CiQjDxgiKp4LSnI2zrZv ZBRfMz6/CG1v9XT/6lDnLnkeJOU31JDs4YvHN5/jtgmfcyfdXduwMZPae64FTQU55xDw AG24XYcSoXxQugkP2GJYUP2sEazyL69CN/vLtnUxrRWlL3aTEZaS3303Xmk9U2PlNrss CdmtPddengOG90V8hOHts27ghai5vTzk6lMbBnYztL29QtdQrjosRrFtJpZhDWSftBZA 8ZVg== X-Gm-Message-State: AOJu0YyPcCDLrXNy1wOsBbM92azpjfHBnd5dCvEuW9G3tdFytNfFp0Hu B+jR0VDtoTIz1I7z4llLDfCYVxZ1f+U1kR22w5i9hOA10j3VQU+IwU6GKW0YN4iDeAsDrJGL+as yzjtQMFpQoOp8l7N2lAdKPxgifWgssK9gU+R5dExPv4hH1L5UuY4rf0hnAWGd832aM4pEqUom9J Aqpxk37XNpUJYNZ0J7RTU0is2Jt+ibcYLH3pw4me6uS63wVkn+hEqs X-Google-Smtp-Source: AGHT+IHdoIRrYCQ5q0Pp2bP8dBRgqXOW6UZEosLGOrjKbm9gVcMoCyJPSj2NcTPjlJog/th1Dcb8QRDIEhE= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a05:6902:1a48:b0:dc2:2e5c:a21d with SMTP id cy8-20020a0569021a4800b00dc22e5ca21dmr624303ybb.6.1711120235018; Fri, 22 Mar 2024 08:10:35 -0700 (PDT) Date: Fri, 22 Mar 2024 15:09:59 +0000 In-Reply-To: <20240322151002.3653639-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240322151002.3653639-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.396.g6e790dbe36-goog Message-ID: <20240322151002.3653639-7-gnoack@google.com> Subject: [PATCH v11 6/9] selftests/landlock: Test IOCTLs on named pipes From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " Named pipes should behave like pipes created with pipe(2), so we don't want to restrict IOCTLs on them. Suggested-by: Mickaël Salaün Signed-off-by: Günther Noack --- tools/testing/selftests/landlock/fs_test.c | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index dde4673e2df4..d3aaa343f6e4 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -3933,6 +3933,49 @@ TEST_F_FORK(layout1, o_path_ftruncate_and_ioctl) ASSERT_EQ(0, close(fd)); } +/* + * Named pipes are not governed by the LANDLOCK_ACCESS_FS_IOCTL_DEV right, + * because they are not character or block devices. + */ +TEST_F_FORK(layout1, named_pipe_ioctl) +{ + pid_t child_pid; + int fd, ruleset_fd; + const char *const path = file1_s1d1; + const struct landlock_ruleset_attr attr = { + .handled_access_fs = LANDLOCK_ACCESS_FS_IOCTL_DEV, + }; + + ASSERT_EQ(0, unlink(path)); + ASSERT_EQ(0, mkfifo(path, 0600)); + + /* Enables Landlock. */ + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* The child process opens the pipe for writing. */ + child_pid = fork(); + ASSERT_NE(-1, child_pid); + if (child_pid == 0) { + fd = open(path, O_WRONLY); + close(fd); + exit(0); + } + + fd = open(path, O_RDONLY); + ASSERT_LE(0, fd); + + /* FIONREAD is implemented by pipefifo_fops. */ + EXPECT_EQ(0, test_fionread_ioctl(fd)); + + ASSERT_EQ(0, close(fd)); + ASSERT_EQ(0, unlink(path)); + + ASSERT_EQ(child_pid, waitpid(child_pid, NULL, 0)); +} + /* clang-format off */ FIXTURE(ioctl) {}; From patchwork Fri Mar 22 15:10:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13600251 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-ej1-f74.google.com (mail-ej1-f74.google.com [209.85.218.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 582144D595 for ; Fri, 22 Mar 2024 15:10:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120241; cv=none; b=gH5y/uIGRI+dgJIrwBjCQDxDYY5WV3Fl25YdeKL9Paj4v3YVhGysALVTBZEEqLzNxqcAOH1t7QEol3P67oe6shUwiy4e+sSkmhBJyLc36LFUPOktW9hdJZo19LL5/pcKYlx2fl34298B37dnxMYdJY4EtJerYjNLekF0U5iKUEo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120241; c=relaxed/simple; bh=R63P4N4ut3QWcKBwrsSKNW9gphHCqTPMh/5hYUZu3qs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=TFtth6Ji+mHGSpQx0samzjJl0fZZzMrKdQOy8VNMkNjqpQdoyk6lqx6vKbjlXAN5F8mVoxhCBM3LDL61EnIVRVPDKawY0rBZSzfNGbMMznFnsScbKt4kFYOH9DfbkwxpYf/jf09xfdlPa2gpY7ES+LwxOA3Q6eVs8TVSN6XaZxE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Sz9OYgp5; arc=none smtp.client-ip=209.85.218.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Sz9OYgp5" Received: by mail-ej1-f74.google.com with SMTP id a640c23a62f3a-a46852c2239so161328966b.1 for ; Fri, 22 Mar 2024 08:10:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1711120238; x=1711725038; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=M9xd0irwbkgB8QE4v3yIoFgRxbZM8RilcqJPUwmelvc=; b=Sz9OYgp5515+cpnek6qEzGRbWochr7j6lqrzNOakvmM//iMNqYcGoTrK+KuA3ngkab GBQEBwSq4iuB9ahVMqV9mVKPtNF413I2Hg0HLI5giJXZNUmexJFREzZJqWdZRgYvBcbz ufAqAVIWxWJ4epF01Sj6hSd6lmHEAXGpXXFefro0PTFv03Mlxtwgh1NdAuzdM9pQLi6F lDqX+7Rd87PNALAidlAeNbJEqKG/vTluP0iPEvKa97DNIcNw2M4qF91VZVGb+lukGcrK xupmADQ67KAINzoqQeFjVmAvhBowlO9jXOCv/H6RlLOOGeRfJZ0+jBI6jANDefjf+2gX 0DVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711120238; x=1711725038; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=M9xd0irwbkgB8QE4v3yIoFgRxbZM8RilcqJPUwmelvc=; b=oKydZtUldX0y3xU9JE5+qYoGD8LRYDJowXjJHg1gVK6mxwOjmjvIq98uU4k8jszmOi cAXh3axuq1ZL3VkoKSoFZmVRJBlCYiLSLp8dGAknXm/7j7gdtLG8tNlyEe1HogqqAEub 5B5pXDTQZxgdQPr4ZoUbPHCXbAdBZJRV2DxKM4dOOpW47LAPP/un5p+RyPBJC/NX8VEW uydm2uVv7bSVLsfQSoelOpsocEiwtncwCoDf3DEAYJXvjIP6MtM3Fbg20pRGPOBocKeY xab+NAhbY2OrV6tznJu2BHFdWOIbfMoSNr1SR6m6/YdbEsREI1FbZwr8bllEvppruKAg OP4w== X-Gm-Message-State: AOJu0YwKRIW9B9tySomAfbOECnQuSFXllSbf9fbxv2IK2Z6V/jjAHvUf 6rKcl3AxSEjEww0tPuV6OTGogjP6DQP1o/r7pQlMCouoELG+4SZTouIFxwaZqbedr3S3owj06Q0 Yx3cndXV2H8vQ11wzJQT2NAuJiYu/ZDeSLjlPRuWPomtK+KeWALFf1Q8ImDHxyUezF934Hn8d5Q RI7gpJhcJK09Hio9DUltpMgbRGoisrlK5fdgvRFEDbosR95lfra5dd X-Google-Smtp-Source: AGHT+IHn7g7WhrbCoj+qwr3+lnHh3Nzxk3BhHeFxtHPYejqb8fDsbQYGnt/pSY23Iu2Eb9T3/kTLwpxNCzo= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a17:906:4c4b:b0:a47:31bb:1581 with SMTP id d11-20020a1709064c4b00b00a4731bb1581mr4777ejw.9.1711120237415; Fri, 22 Mar 2024 08:10:37 -0700 (PDT) Date: Fri, 22 Mar 2024 15:10:00 +0000 In-Reply-To: <20240322151002.3653639-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240322151002.3653639-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.396.g6e790dbe36-goog Message-ID: <20240322151002.3653639-8-gnoack@google.com> Subject: [PATCH v11 7/9] selftests/landlock: Check IOCTL restrictions for named UNIX domain sockets From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " Suggested-by: Mickaël Salaün Signed-off-by: Günther Noack --- tools/testing/selftests/landlock/fs_test.c | 51 ++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index d3aaa343f6e4..2ade195bde56 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -20,8 +20,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -3976,6 +3978,55 @@ TEST_F_FORK(layout1, named_pipe_ioctl) ASSERT_EQ(child_pid, waitpid(child_pid, NULL, 0)); } +/* For named UNIX domain sockets, no IOCTL restrictions apply. */ +TEST_F_FORK(layout1, named_unix_domain_socket_ioctl) +{ + const char *const path = file1_s1d1; + int srv_fd, cli_fd, ruleset_fd; + socklen_t size; + struct sockaddr_un srv_un, cli_un; + const struct landlock_ruleset_attr attr = { + .handled_access_fs = LANDLOCK_ACCESS_FS_IOCTL_DEV, + }; + + /* Sets up a server */ + srv_un.sun_family = AF_UNIX; + strncpy(srv_un.sun_path, path, sizeof(srv_un.sun_path)); + + ASSERT_EQ(0, unlink(path)); + ASSERT_LE(0, (srv_fd = socket(AF_UNIX, SOCK_STREAM, 0))); + + size = offsetof(struct sockaddr_un, sun_path) + strlen(srv_un.sun_path); + ASSERT_EQ(0, bind(srv_fd, (struct sockaddr *)&srv_un, size)); + ASSERT_EQ(0, listen(srv_fd, 10 /* qlen */)); + + /* Enables Landlock. */ + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* Sets up a client connection to it */ + cli_un.sun_family = AF_UNIX; + + ASSERT_LE(0, (cli_fd = socket(AF_UNIX, SOCK_STREAM, 0))); + + size = offsetof(struct sockaddr_un, sun_path) + strlen(cli_un.sun_path); + ASSERT_EQ(0, bind(cli_fd, (struct sockaddr *)&cli_un, size)); + + bzero(&cli_un, sizeof(cli_un)); + cli_un.sun_family = AF_UNIX; + strncpy(cli_un.sun_path, path, sizeof(cli_un.sun_path)); + size = offsetof(struct sockaddr_un, sun_path) + strlen(cli_un.sun_path); + + ASSERT_EQ(0, connect(cli_fd, (struct sockaddr *)&cli_un, size)); + + /* FIONREAD and other IOCTLs should not be forbidden. */ + EXPECT_EQ(0, test_fionread_ioctl(cli_fd)); + + ASSERT_EQ(0, close(cli_fd)); +} + /* clang-format off */ FIXTURE(ioctl) {}; From patchwork Fri Mar 22 15:10:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13600252 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DAD874DA13 for ; Fri, 22 Mar 2024 15:10:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120242; cv=none; b=tAIBC0Hk9NZ5YgDeBD+JFtiQ/7yKCsxDyOw4lZg68f0SxGc0Yy7GbXADicT+WnR2o4hbqx03pSu1YAsIDi+C2VqCKcYmXzaFfu6xYtsrTeFQD85k3lgeQZnlJgFFgMPWLg6wei/mKaMf+q+91arw4pgkj7K8At8+nR/67mAHG7k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120242; c=relaxed/simple; bh=I4ujxSWG1rQZvUOG3aGaAfaG34o0FSxd2yK2pMFboO4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=k7qRu40hyrkJbtJtCyetJB3NrbkTZ1jUcqoHaVvnoey1TQfvrX6QzYyEKE23wxiDK86E7m7gxsQmKXXnNr5eYdm0qAR2XRf+qtuqCSdItyORp7WItOIDZdDJlsd2vC8cFeaQOnnhUVN6uf+vi3+AOmwEDr8RAqWK9UGpyMqpsw4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=1dcz2Iyo; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="1dcz2Iyo" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-60a3bb05c9bso36752377b3.1 for ; Fri, 22 Mar 2024 08:10:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1711120240; x=1711725040; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=Zqw6HHB8TTWWZzHXrC+t6B4vKHkVHyluYvVzQQIi1bo=; b=1dcz2IyosX9KKA/3KNSmY5XarlU3xLIluGbKMtygfwNnoyMFBRfWeywZPxHnxy+aG1 pUGJL17Cyln8hlvNSwB7LCp+jb50RmjMZ1Flhg2s+9pVn2+y/oJ8QC+5kDL/6pwbwXSI Iui/JGOf0GZSoVblLDKAMZhRT7OcyH3CrYFSwabzXMUQru3SgVxg4IZcix/y04H3wSQQ SqBat4OlSo+MHoxMLQQjwqkP6XEBOkaD2Xdn077IxfRrT8LC25K9gFd/jyfAi7O87cUu 9qpjOuDlWA698J9z7v90G+f6XEAoFRoYqldeda4P7znZ2JPSfmObE1kPhfy9UtfXCgga +GMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711120240; x=1711725040; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=Zqw6HHB8TTWWZzHXrC+t6B4vKHkVHyluYvVzQQIi1bo=; b=B6YvqzxhTbzGKvyFvnTN8/lf/xYtJ8s1zmwvnr5Ux6TEACxk5IU25KokOqCQiYG9bz 8UHrrSoEoXIpKP6uVB2O6xDhK+SPe4xs8pLl9LOf1LVh32KdSoXky9h2jmJ5J9DV2qcU O9OuhFmMj0UgXsmtjF41mcVYOcvGvhiwHRPh2hlqnA+V9ZB0V0+z6pdeIsuPr8W1C6Zn alWdNsIJz/RIweoWhgIJRtA354c5CW8IsnOZfBnWUUZRrw4DpkxalexMYDW8Hqcn42j/ tyt6VaZ7HRaMKqzBYBaW6xLBRMJhWr9YNYAcxcLvchxqSqLByFNbKFi0SjTn1uy7awW1 EWUw== X-Gm-Message-State: AOJu0YyKDcJgeXeycsWzVqIW0mks27YD5+wwCl1Ry/+i3zyZTS4dvImx RjS85zh87KolJQQ/hmhLD/WFf8+e4iLEX1vds9YLAuP6jmXYfhuNBqZ5jF9Tjt9YAI7D2t6wYsy KFo3OX4xDfCoGuk0Yq6LO7DHuhJ2DwhK1iIjyGievmZCX5fhJTMGfj6hZMv5gfhA1YIQdIQXK1A uH8k/eQSYcMcdv/H/9hrvCq18l9joOhiJHtS19w6RpsdA5tm5PWGH7 X-Google-Smtp-Source: AGHT+IEXCHg6NIh+6BQFmtU5UD6PB7Ny9+kH183mfOWzk4uupBXeY0DzvqGg9OiO4ZZ5PXxcNwqEBQGE664= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a05:6902:2686:b0:dc6:d1d7:d03e with SMTP id dx6-20020a056902268600b00dc6d1d7d03emr60950ybb.8.1711120239831; Fri, 22 Mar 2024 08:10:39 -0700 (PDT) Date: Fri, 22 Mar 2024 15:10:01 +0000 In-Reply-To: <20240322151002.3653639-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240322151002.3653639-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.396.g6e790dbe36-goog Message-ID: <20240322151002.3653639-9-gnoack@google.com> Subject: [PATCH v11 8/9] samples/landlock: Add support for LANDLOCK_ACCESS_FS_IOCTL_DEV From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " Add IOCTL support to the Landlock sample tool. The IOCTL right is grouped with the read-write rights in the sample tool, as some IOCTL requests provide features that mutate state. Signed-off-by: Günther Noack --- samples/landlock/sandboxer.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c index 32e930c853bb..997f774e88ae 100644 --- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c @@ -81,7 +81,8 @@ static int parse_path(char *env_path, const char ***const path_list) LANDLOCK_ACCESS_FS_EXECUTE | \ LANDLOCK_ACCESS_FS_WRITE_FILE | \ LANDLOCK_ACCESS_FS_READ_FILE | \ - LANDLOCK_ACCESS_FS_TRUNCATE) + LANDLOCK_ACCESS_FS_TRUNCATE | \ + LANDLOCK_ACCESS_FS_IOCTL_DEV) /* clang-format on */ @@ -201,11 +202,12 @@ static int populate_ruleset_net(const char *const env_var, const int ruleset_fd, LANDLOCK_ACCESS_FS_MAKE_BLOCK | \ LANDLOCK_ACCESS_FS_MAKE_SYM | \ LANDLOCK_ACCESS_FS_REFER | \ - LANDLOCK_ACCESS_FS_TRUNCATE) + LANDLOCK_ACCESS_FS_TRUNCATE | \ + LANDLOCK_ACCESS_FS_IOCTL_DEV) /* clang-format on */ -#define LANDLOCK_ABI_LAST 4 +#define LANDLOCK_ABI_LAST 5 int main(const int argc, char *const argv[], char *const *const envp) { @@ -319,6 +321,11 @@ int main(const int argc, char *const argv[], char *const *const envp) ruleset_attr.handled_access_net &= ~(LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP); + __attribute__((fallthrough)); + case 4: + /* Removes LANDLOCK_ACCESS_FS_IOCTL_DEV for ABI < 5 */ + ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV; + fprintf(stderr, "Hint: You should update the running kernel " "to leverage Landlock features " From patchwork Fri Mar 22 15:10:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?G=C3=BCnther_Noack?= X-Patchwork-Id: 13600253 X-Patchwork-Delegate: paul@paul-moore.com Received: from mail-ej1-f73.google.com (mail-ej1-f73.google.com [209.85.218.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CE3A55677C for ; Fri, 22 Mar 2024 15:10:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120245; cv=none; b=FlC9fvIqQiok0WvUyhYyEgoOf9sZo3H5ndvUacuwE93+19SKMTQbDAwmqmO31pt9Dox97sRMXenLIYRklazPQ3E9f3UacX60e2vZqxpghxUnMnvo8JdHSTIJD+MVubF9WbtTr1fTAnDJKpvxzSDqFT7tr1EdiigLjPVrUI0AA4g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711120245; c=relaxed/simple; bh=4g64X2z2I9w1oZROI2GSCgDSQPRm3AXX/Vq984hPUy8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=uOCI6Aq83EmYW5grxfhoqoLxv0sygGnjLrQbx2r2UXuXOs91h3FVS846TMAE8dcvyf1SlZudF4ookXAHtERTM4br71LAwtmnDnMG25PuOGe7kX9P03Y7tpYIvwgygNXz8P6fmNpfNltlXyXt9sPbYyFolbAO5TkRqtKbWx9zgW8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=0m7yw4D0; arc=none smtp.client-ip=209.85.218.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--gnoack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="0m7yw4D0" Received: by mail-ej1-f73.google.com with SMTP id a640c23a62f3a-a47377536c6so33214766b.1 for ; Fri, 22 Mar 2024 08:10:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1711120242; x=1711725042; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=AL+pLtjmOCqOyTizrp229Q3mbwzX+z6isjzKlV0osFY=; b=0m7yw4D0krYCO3VRb9/2a3l8Pk/uNe0ufMF0hK/3HJ3hg2tO3ZuIOBe70DyX73T/kx XRY1wDlohe6V9hocZYP9Ar20bLmZesIZT5s7JVQvZovi3YId/81IWeaPoG1EXuclpl0b NasxomgE+vGhI0uVDaPVBBxKopMZaOy7xKIyL33+FlsafzubXLnic4yb8FGMs7WkQRjG SXWJ+GOIA7xRbPMgCIGYUw+mcGtbEEhJ2yFCvVJ7iKEY/uJi5/in0Nus7Fydlr8O5xgD hZVZmX1nAsqNDIqSzoGBCDf+ozVQBqdu+5cORdm/ij8IBtShq1SXx3PdENpOojh7NBCx WD8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711120242; x=1711725042; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=AL+pLtjmOCqOyTizrp229Q3mbwzX+z6isjzKlV0osFY=; b=BGRxhnkWOrheEqnlUsKp4p8czU1XNoQgQHRoh4LXoVBT5XpknbMYmUNInaXhgBIsms nsQiNzN9J00Mk7feg8GJZMgdV+MC4lRbpg/X8L3slcDq0fmevHQdHWQ6t7ivZrXyO7ul dLo9PsmiwupvE1tmMppr1a/PVm1dUE2zp3wy1PB4Gocxsvdv25gFTQzi8P9cfv2rRXYc qlatJLKXHNuiDKK7qJtvNWlp+nIGAmiXaOFI6/0eCoJTOoJmCboSx5VJmPk7VgbEceHf r8zRC5xPG+B2Wq/yujW5z5j38moX30dxSGagM36YZ6JPuZ9mcIds/a0FZURUr9shwgik dvZg== X-Gm-Message-State: AOJu0Yy8+YevSocrY3JYy8+kDckt+4sMC0ybfSXQ2mJ5iTyR0eE2sLqy 6gxFkIQxtUcxKhWN1qiT/LM6mp39XClHSIPn7HD+EULlDlkJTRwXNb1594Y+vTWCnh3/TRNYnyl OIUqrnkD/WvPurKNH5I8tNxROJD7o/P5LVK4yoJo07oP7WvhFD9nzuPFceOBhrWsgEfL0crV6Cs QoMW8m240TWN4Q8V9IdV51dFwAVdDG9oDxsxLi48dW+UP+WZAjNSIO X-Google-Smtp-Source: AGHT+IG2d2rmjGvZ8L0npAA4kPj345zFaKtlFzju5GVoQKkLNIQahXhY8zVyvi0udqKsdH8/yQOGcOsUFFY= X-Received: from swim.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:1605]) (user=gnoack job=sendgmr) by 2002:a17:906:b110:b0:a45:a016:4ea1 with SMTP id u16-20020a170906b11000b00a45a0164ea1mr1ejy.13.1711120242064; Fri, 22 Mar 2024 08:10:42 -0700 (PDT) Date: Fri, 22 Mar 2024 15:10:02 +0000 In-Reply-To: <20240322151002.3653639-1-gnoack@google.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240322151002.3653639-1-gnoack@google.com> X-Mailer: git-send-email 2.44.0.396.g6e790dbe36-goog Message-ID: <20240322151002.3653639-10-gnoack@google.com> Subject: [PATCH v11 9/9] landlock: Document IOCTL support From: " =?utf-8?q?G=C3=BCnther_Noack?= " To: linux-security-module@vger.kernel.org, " =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= " Cc: Jeff Xu , Jorge Lucangeli Obes , Allen Webb , Dmitry Torokhov , Paul Moore , Konstantin Meskhidze , Matt Bobrowski , linux-fsdevel@vger.kernel.org, " =?utf-8?q?G=C3=BCnther_Noack?= " In the paragraph above the fallback logic, use the shorter phrasing from the landlock(7) man page. Signed-off-by: Günther Noack --- Documentation/userspace-api/landlock.rst | 76 +++++++++++++++++++----- 1 file changed, 61 insertions(+), 15 deletions(-) diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst index 9dd636aaa829..145bd869c684 100644 --- a/Documentation/userspace-api/landlock.rst +++ b/Documentation/userspace-api/landlock.rst @@ -76,7 +76,8 @@ to be explicit about the denied-by-default access rights. LANDLOCK_ACCESS_FS_MAKE_BLOCK | LANDLOCK_ACCESS_FS_MAKE_SYM | LANDLOCK_ACCESS_FS_REFER | - LANDLOCK_ACCESS_FS_TRUNCATE, + LANDLOCK_ACCESS_FS_TRUNCATE | + LANDLOCK_ACCESS_FS_IOCTL_DEV, .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP, @@ -85,10 +86,10 @@ to be explicit about the denied-by-default access rights. Because we may not know on which kernel version an application will be executed, it is safer to follow a best-effort security approach. Indeed, we should try to protect users as much as possible whatever the kernel they are -using. To avoid binary enforcement (i.e. either all security features or -none), we can leverage a dedicated Landlock command to get the current version -of the Landlock ABI and adapt the handled accesses. Let's check if we should -remove access rights which are only supported in higher versions of the ABI. +using. + +To be compatible with older Linux versions, we detect the available Landlock ABI +version, and only use the available subset of access rights: .. code-block:: c @@ -114,6 +115,10 @@ remove access rights which are only supported in higher versions of the ABI. ruleset_attr.handled_access_net &= ~(LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP); + __attribute__((fallthrough)); + case 4: + /* Removes LANDLOCK_ACCESS_FS_IOCTL_DEV for ABI < 5 */ + ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV; } This enables to create an inclusive ruleset that will contain our rules. @@ -225,6 +230,7 @@ access rights per directory enables to change the location of such directory without relying on the destination directory access rights (except those that are required for this operation, see ``LANDLOCK_ACCESS_FS_REFER`` documentation). + Having self-sufficient hierarchies also helps to tighten the required access rights to the minimal set of data. This also helps avoid sinkhole directories, i.e. directories where data can be linked to but not linked from. However, @@ -318,18 +324,26 @@ It should also be noted that truncating files does not require the system call, this can also be done through :manpage:`open(2)` with the flags ``O_RDONLY | O_TRUNC``. -When opening a file, the availability of the ``LANDLOCK_ACCESS_FS_TRUNCATE`` -right is associated with the newly created file descriptor and will be used for -subsequent truncation attempts using :manpage:`ftruncate(2)`. The behavior is -similar to opening a file for reading or writing, where permissions are checked -during :manpage:`open(2)`, but not during the subsequent :manpage:`read(2)` and +The truncate right is associated with the opened file (see below). + +Rights associated with file descriptors +--------------------------------------- + +When opening a file, the availability of the ``LANDLOCK_ACCESS_FS_TRUNCATE`` and +``LANDLOCK_ACCESS_FS_IOCTL_DEV`` rights is associated with the newly created +file descriptor and will be used for subsequent truncation and ioctl attempts +using :manpage:`ftruncate(2)` and :manpage:`ioctl(2)`. The behavior is similar +to opening a file for reading or writing, where permissions are checked during +:manpage:`open(2)`, but not during the subsequent :manpage:`read(2)` and :manpage:`write(2)` calls. -As a consequence, it is possible to have multiple open file descriptors for the -same file, where one grants the right to truncate the file and the other does -not. It is also possible to pass such file descriptors between processes, -keeping their Landlock properties, even when these processes do not have an -enforced Landlock ruleset. +As a consequence, it is possible that a process has multiple open file +descriptors referring to the same file, but Landlock enforces different things +when operating with these file descriptors. This can happen when a Landlock +ruleset gets enforced and the process keeps file descriptors which were opened +both before and after the enforcement. It is also possible to pass such file +descriptors between processes, keeping their Landlock properties, even when some +of the involved processes do not have an enforced Landlock ruleset. Compatibility ============= @@ -458,6 +472,28 @@ Memory usage Kernel memory allocated to create rulesets is accounted and can be restricted by the Documentation/admin-guide/cgroup-v1/memory.rst. +IOCTL support +------------- + +The ``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right restricts the use of +:manpage:`ioctl(2)`, but it only applies to *newly opened* device files. This +means specifically that pre-existing file descriptors like stdin, stdout and +stderr are unaffected. + +Users should be aware that TTY devices have traditionally permitted to control +other processes on the same TTY through the ``TIOCSTI`` and ``TIOCLINUX`` IOCTL +commands. Both of these require ``CAP_SYS_ADMIN`` on modern Linux systems, but +the behavior is configurable for ``TIOCSTI``. + +On older systems, it is therefore recommended to close inherited TTY file +descriptors, or to reopen them from ``/proc/self/fd/*`` without the +``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right, if possible. + +Landlock's IOCTL support is coarse-grained at the moment, but may become more +fine-grained in the future. Until then, users are advised to establish the +guarantees that they need through the file hierarchy, by only allowing the +``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right on files where it is really required. + Previous limitations ==================== @@ -495,6 +531,16 @@ bind and connect actions to only a set of allowed ports thanks to the new ``LANDLOCK_ACCESS_NET_BIND_TCP`` and ``LANDLOCK_ACCESS_NET_CONNECT_TCP`` access rights. +IOCTL (ABI < 5) +--------------- + +IOCTL operations could not be denied before the fifth Landlock ABI, so +:manpage:`ioctl(2)` is always allowed when using a kernel that only supports an +earlier ABI. + +Starting with the Landlock ABI version 5, it is possible to restrict the use of +:manpage:`ioctl(2)` using the new ``LANDLOCK_ACCESS_FS_IOCTL_DEV`` access right. + .. _kernel_support: Kernel support