Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp1291863pxb; Thu, 24 Mar 2022 17:02:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy+CIzU+aJjfpr4dCIDGEfm+7KqPTAsZLixNTid8DhY7s5t0rik7byvsW/OhoZHK+YSO41l X-Received: by 2002:a65:6382:0:b0:381:353c:8b39 with SMTP id h2-20020a656382000000b00381353c8b39mr5689753pgv.574.1648166571974; Thu, 24 Mar 2022 17:02:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648166571; cv=none; d=google.com; s=arc-20160816; b=AlzpR4STiyQ1BcPrheWjOS3fcVpYPpZyRXseyGVXtvnwI29tycgu8TqL/9buww2p6j XPDP+jubkvSOLRa4VaoVrlXtxJuxFBjbiDnlfTsTfFtR2d4EtAXZNsxeVcygB+LlFvbE 8OLWBS8QTYuhE7BgpOs5GRf/gG6kVNCrGP6bgw0qRtyYNINiqIVkTlbsjRW8qGzrfybX Zr9DKuyE+7fbqiQE0kdNkhTfTbdtznzRv1UryJpSLujD+ceh8+ql8DyUM0DCzzx7Ajja ejFw29ZAtV4H2PC3+ljOLYiGgny64fau/W0zse790lz0IeV0Xqgj/LTBNOhwC67enKW1 Hi6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:subject :from:references:cc:to:content-language:user-agent:mime-version:date :message-id:dkim-signature; bh=obiiRMov/lkcNP1j2lqyNwiUAf0iK1e0hU6MhnIWVcE=; b=QUK8za7mAjchuq1/CHqxYLjRehvk6SAzoFlAk5dcYDbnoUQPosh6QOo79qEz2KvZ39 vvMw8455jttJTpx+QHXhdBo0OFLJULlfqbHaMowtr8v7kHHdD0vhXXvhu7wigVegQkS1 b6ZnBSqmPzZEUJe+V+X6dr1pfoDU18eJRrl6kJwOWy4ABXnU5/KMI1OStDCnQ771bqQ2 M232RvEeY19ajDq67VkdwDz9/6kvW2HPqS77g1e0AZ8PyCc/QODx9FRHaAbgT4NDuiVg kSIKqEhDcx2bvcb3ljlSbTdHxmiUdFjwOx3gTRT8fls0w+j/oOt7UH0XkDd1WQhJdciN 2a9Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@digikod.net header.s=20191114 header.b=IR2znwVG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h14-20020a170902f70e00b00153b2d164basi780128plo.194.2022.03.24.17.02.37; Thu, 24 Mar 2022 17:02:51 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@digikod.net header.s=20191114 header.b=IR2znwVG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345235AbiCWWii (ORCPT + 99 others); Wed, 23 Mar 2022 18:38:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241288AbiCWWih (ORCPT ); Wed, 23 Mar 2022 18:38:37 -0400 Received: from smtp-190b.mail.infomaniak.ch (smtp-190b.mail.infomaniak.ch [185.125.25.11]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 558AF5C644 for ; Wed, 23 Mar 2022 15:37:02 -0700 (PDT) Received: from smtp-2-0001.mail.infomaniak.ch (unknown [10.5.36.108]) by smtp-2-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4KP3BM6YjjzMqDnc; Wed, 23 Mar 2022 23:36:59 +0100 (CET) Received: from ns3096276.ip-94-23-54.eu (unknown [23.97.221.149]) by smtp-2-0001.mail.infomaniak.ch (Postfix) with ESMTPA id 4KP3BK20BnzljsT7; Wed, 23 Mar 2022 23:36:57 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=digikod.net; s=20191114; t=1648075019; bh=vAVFB2iElKMHpm9vUwd0asRHZ/fvZqt8PLW/qDoEF2Q=; h=Date:To:Cc:References:From:Subject:In-Reply-To:From; b=IR2znwVGk7TQsZP5s8rMWohjhz07WIgG5PbfUHcD0y13+jwU4vQ6QSwajL7KjVTXN O/AJqs2FYG1+EnGfmBdl06XF8ihX36IrOn8nVKlqR9M2HV9DyP4zozueCl7/+PfXIL nNMjKHcD/iBL6kx2MIeZ1+d4L3M16t63RYfOzsyE= Message-ID: <56ae0002-09ed-55ae-d033-0212fe78002c@digikod.net> Date: Wed, 23 Mar 2022 23:36:58 +0100 MIME-Version: 1.0 User-Agent: Content-Language: en-US To: John Johansen , James Morris , Kentaro Takeda , "Serge E . Hallyn" , Tetsuo Handa Cc: Brendan Jackman , Florent Revest , KP Singh , Paul Moore , linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, =?UTF-8?Q?Micka=c3=abl_Sala=c3=bcn?= References: <20220222175332.384545-1-mic@digikod.net> <4611f869-9a88-12d0-861c-7efcfa15bcba@canonical.com> From: =?UTF-8?Q?Micka=c3=abl_Sala=c3=bcn?= Subject: Re: [RFC PATCH v1] LSM: Remove double path_rename hook calls for RENAME_EXCHANGE In-Reply-To: <4611f869-9a88-12d0-861c-7efcfa15bcba@canonical.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Thanks Tetsuo and John. I'll include this patch in the rename/link Landlock series to fix the remaining issue: https://lore.kernel.org/r/20220221212522.320243-1-mic@digikod.net On 23/03/2022 18:38, John Johansen wrote: > Looks good to me. Of course now I am going to have to create a follow-up > patch to optimize the apparmor mediation. > > Acked-by: John Johansen > > On 3/23/22 01:40, Mickaël Salaün wrote: >> Any comment? John, Tetsuo, does it look OK for AppArmor and Tomoyo? >> >> On 22/02/2022 18:53, Mickaël Salaün wrote: >>> From: Mickaël Salaün >>> >>> In order to be able to identify a file exchange with renameat2(2) and >>> RENAME_EXCHANGE, which will be useful for Landlock [1], propagate the >>> rename flags to LSMs.  This may also improve performance because of the >>> switch from two set of LSM hook calls to only one, and because LSMs >>> using this hook may optimize the double check (e.g. only one lock, >>> reduce the number of path walks). >>> >>> AppArmor, Landlock and Tomoyo are updated to leverage this change.  This >>> should not change the current behavior (same check order), except >>> (different level of) speed boosts. >>> >>> [1] https://lore.kernel.org/r/20220221212522.320243-1-mic@digikod.net >>> >>> Cc: James Morris >>> Cc: John Johansen >>> Cc: Kentaro Takeda >>> Cc: Serge E. Hallyn >>> Cc: Tetsuo Handa >>> Signed-off-by: Mickaël Salaün >>> Link: https://lore.kernel.org/r/20220222175332.384545-1-mic@digikod.net >>> --- >>>   include/linux/lsm_hook_defs.h |  2 +- >>>   include/linux/lsm_hooks.h     |  1 + >>>   security/apparmor/lsm.c       | 30 +++++++++++++++++++++++++----- >>>   security/landlock/fs.c        | 12 ++++++++++-- >>>   security/security.c           |  9 +-------- >>>   security/tomoyo/tomoyo.c      | 11 ++++++++++- >>>   6 files changed, 48 insertions(+), 17 deletions(-) >>> >>> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h >>> index 819ec92dc2a8..d8b49c9c3a8a 100644 >>> --- a/include/linux/lsm_hook_defs.h >>> +++ b/include/linux/lsm_hook_defs.h >>> @@ -100,7 +100,7 @@ LSM_HOOK(int, 0, path_link, struct dentry *old_dentry, >>>        const struct path *new_dir, struct dentry *new_dentry) >>>   LSM_HOOK(int, 0, path_rename, const struct path *old_dir, >>>        struct dentry *old_dentry, const struct path *new_dir, >>> -     struct dentry *new_dentry) >>> +     struct dentry *new_dentry, unsigned int flags) >>>   LSM_HOOK(int, 0, path_chmod, const struct path *path, umode_t mode) >>>   LSM_HOOK(int, 0, path_chown, const struct path *path, kuid_t uid, kgid_t gid) >>>   LSM_HOOK(int, 0, path_chroot, const struct path *path) >>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h >>> index 3bf5c658bc44..32cd2a7fe9fc 100644 >>> --- a/include/linux/lsm_hooks.h >>> +++ b/include/linux/lsm_hooks.h >>> @@ -358,6 +358,7 @@ >>>    *    @old_dentry contains the dentry structure of the old link. >>>    *    @new_dir contains the path structure for parent of the new link. >>>    *    @new_dentry contains the dentry structure of the new link. >>> + *    @flags may contain rename options such as RENAME_EXCHANGE. >>>    *    Return 0 if permission is granted. >>>    * @path_chmod: >>>    *    Check for permission to change a mode of the file @path. The new >>> diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c >>> index 4f0eecb67dde..900bc540656a 100644 >>> --- a/security/apparmor/lsm.c >>> +++ b/security/apparmor/lsm.c >>> @@ -354,13 +354,16 @@ static int apparmor_path_link(struct dentry *old_dentry, const struct path *new_ >>>   } >>>     static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_dentry, >>> -                const struct path *new_dir, struct dentry *new_dentry) >>> +                const struct path *new_dir, struct dentry *new_dentry, >>> +                const unsigned int flags) >>>   { >>>       struct aa_label *label; >>>       int error = 0; >>>         if (!path_mediated_fs(old_dentry)) >>>           return 0; >>> +    if ((flags & RENAME_EXCHANGE) && !path_mediated_fs(new_dentry)) >>> +        return 0; >>>         label = begin_current_label_crit_section(); >>>       if (!unconfined(label)) { >>> @@ -374,10 +377,27 @@ static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_d >>>               d_backing_inode(old_dentry)->i_mode >>>           }; >>>   -        error = aa_path_perm(OP_RENAME_SRC, label, &old_path, 0, >>> -                     MAY_READ | AA_MAY_GETATTR | MAY_WRITE | >>> -                     AA_MAY_SETATTR | AA_MAY_DELETE, >>> -                     &cond); >>> +        if (flags & RENAME_EXCHANGE) { >>> +            struct path_cond cond_exchange = { >>> +                i_uid_into_mnt(mnt_userns, d_backing_inode(new_dentry)), >>> +                d_backing_inode(new_dentry)->i_mode >>> +            }; >>> + >>> +            error = aa_path_perm(OP_RENAME_SRC, label, &new_path, 0, >>> +                         MAY_READ | AA_MAY_GETATTR | MAY_WRITE | >>> +                         AA_MAY_SETATTR | AA_MAY_DELETE, >>> +                         &cond_exchange); >>> +            if (!error) >>> +                error = aa_path_perm(OP_RENAME_DEST, label, &old_path, >>> +                             0, MAY_WRITE | AA_MAY_SETATTR | >>> +                             AA_MAY_CREATE, &cond_exchange); >>> +        } >>> + >>> +        if (!error) >>> +            error = aa_path_perm(OP_RENAME_SRC, label, &old_path, 0, >>> +                         MAY_READ | AA_MAY_GETATTR | MAY_WRITE | >>> +                         AA_MAY_SETATTR | AA_MAY_DELETE, >>> +                         &cond); >>>           if (!error) >>>               error = aa_path_perm(OP_RENAME_DEST, label, &new_path, >>>                            0, MAY_WRITE | AA_MAY_SETATTR | >>> diff --git a/security/landlock/fs.c b/security/landlock/fs.c >>> index 97b8e421f617..7e57fca6e814 100644 >>> --- a/security/landlock/fs.c >>> +++ b/security/landlock/fs.c >>> @@ -574,10 +574,12 @@ static inline u32 maybe_remove(const struct dentry *const dentry) >>>   static int hook_path_rename(const struct path *const old_dir, >>>           struct dentry *const old_dentry, >>>           const struct path *const new_dir, >>> -        struct dentry *const new_dentry) >>> +        struct dentry *const new_dentry, >>> +        const unsigned int flags) >>>   { >>>       const struct landlock_ruleset *const dom = >>>           landlock_get_current_domain(); >>> +    u32 exchange_access = 0; >>>         if (!dom) >>>           return 0; >>> @@ -585,11 +587,17 @@ static int hook_path_rename(const struct path *const old_dir, >>>       if (old_dir->dentry != new_dir->dentry) >>>           /* Gracefully forbids reparenting. */ >>>           return -EXDEV; >>> +    if (flags & RENAME_EXCHANGE) { >>> +        if (unlikely(d_is_negative(new_dentry))) >>> +            return -ENOENT; >>> +        exchange_access = >>> +            get_mode_access(d_backing_inode(new_dentry)->i_mode); >>> +    } >>>       if (unlikely(d_is_negative(old_dentry))) >>>           return -ENOENT; >>>       /* RENAME_EXCHANGE is handled because directories are the same. */ >>>       return check_access_path(dom, old_dir, maybe_remove(old_dentry) | >>> -            maybe_remove(new_dentry) | >>> +            maybe_remove(new_dentry) | exchange_access | >>>               get_mode_access(d_backing_inode(old_dentry)->i_mode)); >>>   } >>>   diff --git a/security/security.c b/security/security.c >>> index 22261d79f333..8634da4cfd46 100644 >>> --- a/security/security.c >>> +++ b/security/security.c >>> @@ -1184,15 +1184,8 @@ int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, >>>                (d_is_positive(new_dentry) && IS_PRIVATE(d_backing_inode(new_dentry))))) >>>           return 0; >>>   -    if (flags & RENAME_EXCHANGE) { >>> -        int err = call_int_hook(path_rename, 0, new_dir, new_dentry, >>> -                    old_dir, old_dentry); >>> -        if (err) >>> -            return err; >>> -    } >>> - >>>       return call_int_hook(path_rename, 0, old_dir, old_dentry, new_dir, >>> -                new_dentry); >>> +                new_dentry, flags); >>>   } >>>   EXPORT_SYMBOL(security_path_rename); >>>   diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c >>> index b6a31901f289..71e82d855ebf 100644 >>> --- a/security/tomoyo/tomoyo.c >>> +++ b/security/tomoyo/tomoyo.c >>> @@ -264,17 +264,26 @@ static int tomoyo_path_link(struct dentry *old_dentry, const struct path *new_di >>>    * @old_dentry: Pointer to "struct dentry". >>>    * @new_parent: Pointer to "struct path". >>>    * @new_dentry: Pointer to "struct dentry". >>> + * @flags: Rename options. >>>    * >>>    * Returns 0 on success, negative value otherwise. >>>    */ >>>   static int tomoyo_path_rename(const struct path *old_parent, >>>                     struct dentry *old_dentry, >>>                     const struct path *new_parent, >>> -                  struct dentry *new_dentry) >>> +                  struct dentry *new_dentry, >>> +                  const unsigned int flags) >>>   { >>>       struct path path1 = { .mnt = old_parent->mnt, .dentry = old_dentry }; >>>       struct path path2 = { .mnt = new_parent->mnt, .dentry = new_dentry }; >>>   +    if (flags & RENAME_EXCHANGE) { >>> +        const int err = tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path2, >>> +                &path1); >>> + >>> +        if (err) >>> +            return err; >>> +    } >>>       return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2); >>>   } >>> >>> base-commit: cfb92440ee71adcc2105b0890bb01ac3cddb8507 >