Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp1661630pxf; Fri, 19 Mar 2021 12:21:49 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxYJxINLGvNgoqiaxYz2HW3WR74c8fzIsEzierez7/xveD7/OQUvuuGsrbr/5Y0QTsKEb0g X-Received: by 2002:a17:906:4747:: with SMTP id j7mr6093155ejs.221.1616181708733; Fri, 19 Mar 2021 12:21:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616181708; cv=none; d=google.com; s=arc-20160816; b=ll+EsNuOJAU2/tNGL2v4Rd9/XFj1GTxMKI6DDa0YoJQSAY9C5iaCzP4nW/ILePnc4/ DdNgIUQHKIfExs13H7nwBU5AAqevdE2MyDEEGCP8rO2FCFE9fpjxf+zZP1pJpyZ9g9eI trnQuh1+ZVnpl4agweTOGsGMzrTcWZVtr+u2xmhjTDQUWe/PVEVB8oi7PD74pcnMRDog pT6ZdrSClMfOKC26M6JLOj7VMmmA0XoPNB8NBUYOoNV8MQhnZx1ma+qeVHWrshFKwqGf XeaQXsjgN/tr4YS+6ntr/fbrX27PX7ixUpw1yCjmDaRBay3wmZU9DDsApM3Yaxp2yS2D T83Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:content-language :in-reply-to:mime-version:user-agent:date:message-id:from:references :cc:to:subject; bh=DtVHIa7soV3wNqlSDEhjNQn3+OMP6gWcgyIFdUkJt4U=; b=L9VsEuX60B0CdKbNb55FpdG1aRMhgaBnWlM6z02fwSWSGtJ93m8yx5lpanCUoMJ8EN BoX1ZFike4eED6f4TUgZ6wDkEaNk3PAJrEXytNS/6acMSg7klwtRwSlpsxcytUwu/Ss6 wQiRMhlPnqIHJTHr7y+laIohRD39qN+nxe52dnhSCQj0qmGJ0UK+xbquCHiZhfvehVRz oWJ74KEOet7VHNbVaBa9CKAXG069+E1MQPri8MLllrkgLAxMFEh+CNZHIk0E+ymzD4Rb prZyr3SsC79Z7PitvPs5EoKZ73DbAabAQPpY6uXm+tX1pnC+Bg+cnZF/pPT1ibgrgiLI 1k6g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id cb21si5085755ejb.170.2021.03.19.12.21.25; Fri, 19 Mar 2021 12:21:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230285AbhCSTUT (ORCPT + 99 others); Fri, 19 Mar 2021 15:20:19 -0400 Received: from smtp-bc0b.mail.infomaniak.ch ([45.157.188.11]:53697 "EHLO smtp-bc0b.mail.infomaniak.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230090AbhCSTTk (ORCPT ); Fri, 19 Mar 2021 15:19:40 -0400 Received: from smtp-3-0001.mail.infomaniak.ch (unknown [10.4.36.108]) by smtp-2-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4F2DGy5XxbzMqdQq; Fri, 19 Mar 2021 20:19:38 +0100 (CET) Received: from ns3096276.ip-94-23-54.eu (unknown [23.97.221.149]) by smtp-3-0001.mail.infomaniak.ch (Postfix) with ESMTPA id 4F2DGt2NL9zlh8T2; Fri, 19 Mar 2021 20:19:34 +0100 (CET) Subject: Re: [PATCH v30 07/12] landlock: Support filesystem access-control To: Kees Cook Cc: James Morris , Jann Horn , "Serge E . Hallyn" , Al Viro , Andrew Morton , Andy Lutomirski , Anton Ivanov , Arnd Bergmann , Casey Schaufler , David Howells , Jeff Dike , Jonathan Corbet , Michael Kerrisk , Richard Weinberger , Shuah Khan , Vincent Dagonneau , kernel-hardening@lists.openwall.com, linux-api@vger.kernel.org, linux-arch@vger.kernel.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-security-module@vger.kernel.org, x86@kernel.org, =?UTF-8?Q?Micka=c3=abl_Sala=c3=bcn?= References: <20210316204252.427806-1-mic@digikod.net> <20210316204252.427806-8-mic@digikod.net> <202103191148.6E819426D@keescook> From: =?UTF-8?Q?Micka=c3=abl_Sala=c3=bcn?= Message-ID: Date: Fri, 19 Mar 2021 20:19:50 +0100 User-Agent: MIME-Version: 1.0 In-Reply-To: <202103191148.6E819426D@keescook> Content-Type: text/plain; charset=iso-8859-15 Content-Language: en-US Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 19/03/2021 19:57, Kees Cook wrote: > On Tue, Mar 16, 2021 at 09:42:47PM +0100, Micka?l Sala?n wrote: >> From: Micka?l Sala?n >> >> Using Landlock objects and ruleset, it is possible to tag inodes >> according to a process's domain. To enable an unprivileged process to >> express a file hierarchy, it first needs to open a directory (or a file) >> and pass this file descriptor to the kernel through >> landlock_add_rule(2). When checking if a file access request is >> allowed, we walk from the requested dentry to the real root, following >> the different mount layers. The access to each "tagged" inodes are >> collected according to their rule layer level, and ANDed to create >> access to the requested file hierarchy. This makes possible to identify >> a lot of files without tagging every inodes nor modifying the >> filesystem, while still following the view and understanding the user >> has from the filesystem. >> >> Add a new ARCH_EPHEMERAL_INODES for UML because it currently does not >> keep the same struct inodes for the same inodes whereas these inodes are >> in use. >> >> This commit adds a minimal set of supported filesystem access-control >> which doesn't enable to restrict all file-related actions. This is the >> result of multiple discussions to minimize the code of Landlock to ease >> review. Thanks to the Landlock design, extending this access-control >> without breaking user space will not be a problem. Moreover, seccomp >> filters can be used to restrict the use of syscall families which may >> not be currently handled by Landlock. >> >> Cc: Al Viro >> Cc: Anton Ivanov >> Cc: James Morris >> Cc: Jann Horn >> Cc: Jeff Dike >> Cc: Kees Cook >> Cc: Richard Weinberger >> Cc: Serge E. Hallyn >> Signed-off-by: Micka?l Sala?n >> Link: https://lore.kernel.org/r/20210316204252.427806-8-mic@digikod.net >> [...] >> + spin_lock(&sb->s_inode_list_lock); >> + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { >> + struct landlock_object *object; >> + >> + /* Only handles referenced inodes. */ >> + if (!atomic_read(&inode->i_count)) >> + continue; >> + >> + /* >> + * Checks I_FREEING and I_WILL_FREE to protect against a race >> + * condition when release_inode() just called iput(), which >> + * could lead to a NULL dereference of inode->security or a >> + * second call to iput() for the same Landlock object. Also >> + * checks I_NEW because such inode cannot be tied to an object. >> + */ >> + spin_lock(&inode->i_lock); >> + if (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW)) { >> + spin_unlock(&inode->i_lock); >> + continue; >> + } > > This (and elsewhere here) seems like a lot of inode internals getting > exposed. Can any of this be repurposed into helpers? I see this test > scattered around the kernel a fair bit: > > $ git grep I_FREEING | grep I_WILL_FREE | grep I_NEW | wc -l > 9 Dealing with the filesystem is complex. Some helpers could probably be added, but with a series dedicated to the filesystem. I can work on that once this series is merged. > >> +static inline u32 get_mode_access(const umode_t mode) >> +{ >> + switch (mode & S_IFMT) { >> + case S_IFLNK: >> + return LANDLOCK_ACCESS_FS_MAKE_SYM; >> + case 0: >> + /* A zero mode translates to S_IFREG. */ >> + case S_IFREG: >> + return LANDLOCK_ACCESS_FS_MAKE_REG; >> + case S_IFDIR: >> + return LANDLOCK_ACCESS_FS_MAKE_DIR; >> + case S_IFCHR: >> + return LANDLOCK_ACCESS_FS_MAKE_CHAR; >> + case S_IFBLK: >> + return LANDLOCK_ACCESS_FS_MAKE_BLOCK; >> + case S_IFIFO: >> + return LANDLOCK_ACCESS_FS_MAKE_FIFO; >> + case S_IFSOCK: >> + return LANDLOCK_ACCESS_FS_MAKE_SOCK; >> + default: >> + WARN_ON_ONCE(1); >> + return 0; >> + } > > I'm assuming this won't be reachable from userspace. It should not, only a bogus kernel code could. > >> [...] >> index a5d6ef334991..f8e8e980454c 100644 >> --- a/security/landlock/setup.c >> +++ b/security/landlock/setup.c >> @@ -11,17 +11,24 @@ >> >> #include "common.h" >> #include "cred.h" >> +#include "fs.h" >> #include "ptrace.h" >> #include "setup.h" >> >> +bool landlock_initialized __lsm_ro_after_init = false; >> + >> struct lsm_blob_sizes landlock_blob_sizes __lsm_ro_after_init = { >> .lbs_cred = sizeof(struct landlock_cred_security), >> + .lbs_inode = sizeof(struct landlock_inode_security), >> + .lbs_superblock = sizeof(struct landlock_superblock_security), >> }; >> >> static int __init landlock_init(void) >> { >> landlock_add_cred_hooks(); >> landlock_add_ptrace_hooks(); >> + landlock_add_fs_hooks(); >> + landlock_initialized = true; > > I think this landlock_initialized is logically separate from the optional > DEFINE_LSM "enabled" variable, but I thought I'd double check. :) An LSM can be marked as enabled (at boot) but not yet initialized. > > It seems like it's used here to avoid releasing superblocks before > landlock_init() is called? What is the scenario where that happens? It is a condition for LSM hooks, syscalls and superblock management. > >> pr_info("Up and running.\n"); >> return 0; >> } >> diff --git a/security/landlock/setup.h b/security/landlock/setup.h >> index 9fdbf33fcc33..1daffab1ab4b 100644 >> --- a/security/landlock/setup.h >> +++ b/security/landlock/setup.h >> @@ -11,6 +11,8 @@ >> >> #include >> >> +extern bool landlock_initialized; >> + >> extern struct lsm_blob_sizes landlock_blob_sizes; >> >> #endif /* _SECURITY_LANDLOCK_SETUP_H */ >> -- >> 2.30.2 >> > > The locking and inode semantics are pretty complex, but since, again, > it's got significant test and syzkaller coverage, it looks good to me. > > With the inode helper cleanup: > > Reviewed-by: Kees Cook >