All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: Paul Moore <paul@paul-moore.com>
Cc: linux-fsdevel@vger.kernel.org, Seth Forshee <sforshee@kernel.org>,
	Christoph Hellwig <hch@lst.de>, Al Viro <viro@zeniv.linux.org.uk>,
	Mimi Zohar <zohar@linux.ibm.com>,
	linux-integrity@vger.kernel.org,
	linux-security-module@vger.kernel.org
Subject: Re: [PATCH v4 12/30] integrity: implement get and set acl hook
Date: Fri, 30 Sep 2022 10:11:23 +0200	[thread overview]
Message-ID: <20220930081123.dwoijem2fpy6ubpp@wittgenstein> (raw)
In-Reply-To: <CAHC9VhSxr-aUj7mqKo05B5Oj=5FWeajx_mNjR_EszzpYR1YozA@mail.gmail.com>

On Thu, Sep 29, 2022 at 03:14:42PM -0400, Paul Moore wrote:
> On Thu, Sep 29, 2022 at 11:33 AM Christian Brauner <brauner@kernel.org> wrote:
> >
> > The current way of setting and getting posix acls through the generic
> > xattr interface is error prone and type unsafe. The vfs needs to
> > interpret and fixup posix acls before storing or reporting it to
> > userspace. Various hacks exist to make this work. The code is hard to
> > understand and difficult to maintain in it's current form. Instead of
> > making this work by hacking posix acls through xattr handlers we are
> > building a dedicated posix acl api around the get and set inode
> > operations. This removes a lot of hackiness and makes the codepaths
> > easier to maintain. A lot of background can be found in [1].
> >
> > So far posix acls were passed as a void blob to the security and
> > integrity modules. Some of them like evm then proceed to interpret the
> > void pointer and convert it into the kernel internal struct posix acl
> > representation to perform their integrity checking magic. This is
> > obviously pretty problematic as that requires knowledge that only the
> > vfs is guaranteed to have and has lead to various bugs. Add a proper
> > security hook for setting posix acls and pass down the posix acls in
> > their appropriate vfs format instead of hacking it through a void
> > pointer stored in the uapi format.
> >
> > I spent considerate time in the security module and integrity
> > infrastructure and audited all codepaths. EVM is the only part that
> > really has restrictions based on the actual posix acl values passed
> > through it. Before this dedicated hook EVM used to translate from the
> > uapi posix acl format sent to it in the form of a void pointer into the
> > vfs format. This is not a good thing. Instead of hacking around in the
> > uapi struct give EVM the posix acls in the appropriate vfs format and
> > perform sane permissions checks that mirror what it used to to in the
> > generic xattr hook.
> >
> > IMA doesn't have any restrictions on posix acls. When posix acls are
> > changed it just wants to update its appraisal status.
> >
> > The removal of posix acls is equivalent to passing NULL to the posix set
> > acl hooks. This is the same as before through the generic xattr api.
> >
> > Link: https://lore.kernel.org/all/20220801145520.1532837-1-brauner@kernel.org [1]
> > Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
> > ---
> >
> > Notes:
> >     /* v2 */
> >     unchanged
> >
> >     /* v3 */
> >     Paul Moore <paul@paul-moore.com>:
> >     - Add get, and remove acl hook
> >
> >     /* v4 */
> >     unchanged
> >
> >  include/linux/evm.h                   | 23 +++++++++
> >  include/linux/ima.h                   | 21 ++++++++
> >  security/integrity/evm/evm_main.c     | 70 ++++++++++++++++++++++++++-
> >  security/integrity/ima/ima_appraise.c |  9 ++++
> >  security/security.c                   | 21 +++++++-
> >  5 files changed, 141 insertions(+), 3 deletions(-)
> 
> ...
> 
> > diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
> > index 23d484e05e6f..7904786b610f 100644
> > --- a/security/integrity/evm/evm_main.c
> > +++ b/security/integrity/evm/evm_main.c
> > @@ -8,7 +8,7 @@
> >   *
> >   * File: evm_main.c
> >   *     implements evm_inode_setxattr, evm_inode_post_setxattr,
> > - *     evm_inode_removexattr, and evm_verifyxattr
> > + *     evm_inode_removexattr, evm_verifyxattr, and evm_inode_set_acl.
> >   */
> >
> >  #define pr_fmt(fmt) "EVM: "fmt
> > @@ -670,6 +670,74 @@ int evm_inode_removexattr(struct user_namespace *mnt_userns,
> >         return evm_protect_xattr(mnt_userns, dentry, xattr_name, NULL, 0);
> >  }
> >
> > +static int evm_inode_set_acl_change(struct user_namespace *mnt_userns,
> > +                                   struct dentry *dentry, const char *name,
> > +                                   struct posix_acl *kacl)
> > +{
> > +#ifdef CONFIG_FS_POSIX_ACL
> > +       int rc;
> > +
> > +       umode_t mode;
> > +       struct inode *inode = d_backing_inode(dentry);
> > +
> > +       if (!kacl)
> > +               return 1;
> > +
> > +       rc = posix_acl_update_mode(mnt_userns, inode, &mode, &kacl);
> > +       if (rc || (inode->i_mode != mode))
> > +               return 1;
> > +#endif
> > +       return 0;
> > +}
> 
> I'm not too bothered by it either way, but one might consider pulling
> the #ifdef outside the function definition, for example:
> 
> #ifdef CONFIG_FS_POSIX_ACL
> static int evm_inode_foo(...)
> {
>   /* ... stuff ... */
> }
> #else
> static int evm_inode_foo(...)
> {
>   return 0;
> }
> #endif /* CONFIG_FS_POSIX_ACL */
> 
> > diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
> > index bde74fcecee3..698a8ae2fe3e 100644
> > --- a/security/integrity/ima/ima_appraise.c
> > +++ b/security/integrity/ima/ima_appraise.c
> > @@ -770,6 +770,15 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
> >         return result;
> >  }
> >
> > +int ima_inode_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
> > +                     const char *acl_name, struct posix_acl *kacl)
> > +{
> > +       if (evm_revalidate_status(acl_name))
> > +               ima_reset_appraise_flags(d_backing_inode(dentry), 0);
> > +
> > +       return 0;
> > +}
> 
> While the ima_inode_set_acl() implementation above looks okay for the
> remove case, I do see that the ima_inode_setxattr() function has a
> call to validate_hash_algo() before calling
> ima_reset_appraise_flags().  IANAIE (I Am Not An Ima Expert), but it
> seems like we would still want that check in the ACL case.

Ah, you might've missed this bug...
The fact that they call validate_hash_algo() on posix acls is a bug in
ima. It's a type safety bug. IMA uses posix acls passed through the void
pointer as struct evm_ima_xattr:

 	const struct evm_ima_xattr_data *xvalue = xattr_value;

	result = validate_hash_algo(dentry, xvalue, xattr_value_len);

I reported this to them a little while ago and Mimi sent a fix for it
that's in -next:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=5926586f291b53cb8a0c9631fc19489be1186e2d

IOW, what I have here seems correct.

  parent reply	other threads:[~2022-09-30  8:11 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-29 15:30 [PATCH v4 00/30] acl: add vfs posix acl api Christian Brauner
2022-09-29 15:30 ` [PATCH v4 01/30] orangefs: rework posix acl handling when creating new filesystem objects Christian Brauner
2022-09-29 15:30 ` [PATCH v4 02/30] fs: pass dentry to set acl method Christian Brauner
2022-09-29 15:30 ` [PATCH v4 03/30] fs: rename current get " Christian Brauner
2022-09-29 15:30 ` [PATCH v4 04/30] fs: add new " Christian Brauner
2022-09-30  8:53   ` Miklos Szeredi
2022-09-30  9:09     ` Christian Brauner
2022-09-30  9:43       ` Miklos Szeredi
2022-09-30 10:05         ` Christian Brauner
2022-09-30 12:24           ` Miklos Szeredi
2022-09-30 12:49             ` Christian Brauner
2022-09-30 13:01               ` Miklos Szeredi
2022-09-30 13:51                 ` Christian Brauner
2022-10-04 19:53         ` Steve French
2022-10-05  7:15           ` Christian Brauner
2022-10-06  6:31             ` Miklos Szeredi
2022-10-06  7:40               ` Christian Brauner
2022-10-06  9:07                 ` Miklos Szeredi
2022-09-29 15:30 ` [PATCH v4 05/30] cifs: implement " Christian Brauner
2022-09-29 15:30 ` [PATCH v4 06/30] cifs: implement set " Christian Brauner
2022-09-29 15:30 ` [PATCH v4 07/30] 9p: implement get " Christian Brauner
2022-09-29 15:30 ` [PATCH v4 08/30] 9p: implement set " Christian Brauner
2022-09-29 15:30 ` [PATCH v4 09/30] security: add get, remove and set acl hook Christian Brauner
2022-09-29 19:15   ` Paul Moore
2022-09-29 15:30 ` [PATCH v4 10/30] selinux: implement get, set and remove " Christian Brauner
2022-09-29 19:15   ` Paul Moore
2022-09-30  8:38     ` Christian Brauner
2022-09-29 15:30 ` [PATCH v4 11/30] smack: " Christian Brauner
2022-09-29 19:15   ` Paul Moore
2022-09-30  8:40     ` Christian Brauner
2022-09-29 15:30 ` [PATCH v4 12/30] integrity: implement get and set " Christian Brauner
2022-09-29 19:14   ` Paul Moore
2022-09-30  3:19     ` Mimi Zohar
2022-09-30 14:11       ` Paul Moore
2022-09-30  8:11     ` Christian Brauner [this message]
2022-09-29 15:30 ` [PATCH v4 13/30] evm: add post " Christian Brauner
2022-09-30  1:44   ` Mimi Zohar
2022-09-30  2:51     ` Mimi Zohar
2022-09-30  8:44     ` Christian Brauner
2022-09-30 11:48       ` Mimi Zohar
2022-10-04  7:04         ` Christian Brauner
2022-09-29 15:30 ` [PATCH v4 14/30] internal: add may_write_xattr() Christian Brauner
2022-09-29 15:30 ` [PATCH v4 15/30] acl: add vfs_set_acl() Christian Brauner
2022-09-29 15:30 ` [PATCH v4 16/30] acl: add vfs_get_acl() Christian Brauner
2022-09-29 15:30 ` [PATCH v4 17/30] acl: add vfs_remove_acl() Christian Brauner
2022-09-29 15:30 ` [PATCH v4 18/30] ksmbd: use vfs_remove_acl() Christian Brauner
2022-09-29 15:30 ` [PATCH v4 19/30] ecryptfs: implement get acl method Christian Brauner
2022-09-29 15:30 ` [PATCH v4 20/30] ecryptfs: implement set " Christian Brauner
2022-09-29 15:30 ` [PATCH v4 21/30] ovl: implement get " Christian Brauner
2022-09-29 15:30 ` [PATCH v4 22/30] ovl: implement set " Christian Brauner
2022-10-06 12:39   ` Miklos Szeredi
2022-09-29 15:30 ` [PATCH v4 23/30] ovl: use posix acl api Christian Brauner
2022-10-06 12:50   ` Miklos Szeredi
2022-09-29 15:30 ` [PATCH v4 24/30] xattr: " Christian Brauner
2022-09-29 15:30 ` [PATCH v4 25/30] evm: remove evm_xattr_acl_change() Christian Brauner
2022-09-29 15:30 ` [PATCH v4 26/30] ecryptfs: use stub posix acl handlers Christian Brauner
2022-09-29 15:30 ` [PATCH v4 27/30] ovl: " Christian Brauner
2022-09-29 15:30 ` [PATCH v4 28/30] cifs: " Christian Brauner
2022-09-29 15:30 ` [PATCH v4 29/30] 9p: " Christian Brauner
2022-09-29 15:30 ` [PATCH v4 30/30] acl: remove a slew of now unused helpers Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220930081123.dwoijem2fpy6ubpp@wittgenstein \
    --to=brauner@kernel.org \
    --cc=hch@lst.de \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=paul@paul-moore.com \
    --cc=sforshee@kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=zohar@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.