linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christian Brauner <christian.brauner@ubuntu.com>
To: Stefan Berger <stefanb@linux.ibm.com>
Cc: linux-integrity@vger.kernel.org, zohar@linux.ibm.com,
	serge@hallyn.com, containers@lists.linux.dev,
	dmitry.kasatkin@gmail.com, ebiederm@xmission.com,
	krzysztof.struczynski@huawei.com, roberto.sassu@huawei.com,
	mpeters@redhat.com, lhinds@redhat.com, lsturman@redhat.com,
	puiterwi@redhat.com, jejb@linux.ibm.com, jamjoom@us.ibm.com,
	linux-kernel@vger.kernel.org, paul@paul-moore.com,
	rgb@redhat.com, linux-security-module@vger.kernel.org,
	jmorris@namei.org
Subject: Re: [PATCH v5 15/16] ima: Move dentries into ima_namespace
Date: Thu, 9 Dec 2021 16:47:03 +0100	[thread overview]
Message-ID: <20211209154703.4mprhv2rcgvgkmx5@wittgenstein> (raw)
In-Reply-To: <f0710142-0d91-d6c4-8d2c-7eac1a946969@linux.ibm.com>

On Thu, Dec 09, 2021 at 10:00:59AM -0500, Stefan Berger wrote:
> 
> On 12/9/21 09:41, Christian Brauner wrote:
> > On Thu, Dec 09, 2021 at 03:37:49PM +0100, Christian Brauner wrote:
> > > On Thu, Dec 09, 2021 at 03:34:28PM +0100, Christian Brauner wrote:
> > > > On Wed, Dec 08, 2021 at 05:18:17PM -0500, Stefan Berger wrote:
> > > > > Move the dentries into the ima_namespace for reuse by virtualized
> > > > > SecurityFS. Implement function freeing the dentries in order of
> > > > > files and symlinks before directories.
> > > > > 
> > > > > Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> > > > > ---
> > > > This doesn't work as implemented, I think.
> > > > 
> > > > What I would have preferred and what I tried to explain in the earlier
> > > > review was:
> > > > Keep the dentry stashing global since it is only needed for init_ima_ns.
> > > > Then struct ima_namespace becomes way smaller and simpler.
> > > > If you do that then it makes sense to remove the additional dget() in
> > > > securityfs_create_dentry() for non-init_ima_ns.
> > > > Then you can rely on auto-cleanup in .kill_sb() or on
> > > > ima_securityfs_init() failure and you only need to call
> > > > ima_fs_ns_free_dentries() if ns != init_ima_ns.
> > s/ns != init_ima_ns/ns == init_ima_ns/
> > 
> > > > IIuc, it seems you're currently doing one dput() too many since you're
> > > > calling securityfs_remove() in the error path for non-init_ima_ns which
> > > > relies on the previous increased dget() which we removed.
> 
> I thought that securityfs_remove() will now simply influence when a dentry
> is removed and freed. If we call it in the error cleanup path in
> non-init_user_ns case it would go away right there and leave nothing to do
> for .kill_sb() while an additional dget() would require the cleanup as well
> but do another cleanup then in .kill_sb() since that brings the reference
> count to 0 via the dput()s that it does. Am I wrong on this?

With your change you get one dget() from lookup_one_len() in
securityfs_create_dentry() for non-init_ima_ns. That's added to the
dcache via d_instantiate().
If you call securityfs_dentry_remove() in the error path or anywhere
else it does:

	dir = d_inode(dentry->d_parent);
	inode_lock(dir);
	if (simple_positive(dentry)) {
		if (d_is_dir(dentry))
			simple_rmdir(dir, dentry);
		else
			simple_unlink(dir, dentry);
		dput(dentry);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

That dput() right there is for the additional dget() in
securityfs_create_dentry() but we didn't take that. So the dput() is one
too many now since simple_rmdir() and simple_unlink() will have consumed
one already. (You should be able to easily see this if you compile with
sanitizers on and let your init function fail somewhere in the middle.)

(What usually should happen is sm like this:

void binderfs_remove_file(struct dentry *dentry)
{
	struct inode *parent_inode;

	parent_inode = d_inode(dentry->d_parent);
	inode_lock(parent_inode);
	if (simple_positive(dentry)) {
		dget(dentry);
		simple_unlink(parent_inode, dentry);
		d_delete(dentry);
		dput(dentry);
	}
	inode_unlock(parent_inode);
})

> 
> 
> > > If you really want to move the dentry stashing into struct ima_namespace
> > > even though it's really unnecessary then you may as well not care about
> > > the auto-cleanup and keep that additional ima_fs_ns_free_dentries(ns)
> > > call in .kill_sb(). But I really think not dragging dentry stashing into
> > > struct ima_namespace is the correct way to go about this.
> 
> 
> I moved the dentries into the ima_namespace so that each namespace holds a
> pointer to the dentries it owns and isolates them. We certainly wouldn't
> want to have IMA namespaces write over the current static variables and
> create a mess with what these are pointing to ( https://elixir.bootlin.com/linux/latest/source/security/integrity/ima/ima_fs.c#L359
> ) and possible race conditions when doing parallel initialization (if that's
> possible at all). This also reduces the code size and we don't need two
> different implementations for init_user_ns and non-init_user_ns. So I don't
> quite understand whey we wouldn't want to have the dentries isolated via
> ima_namespace?

My point was this:
Afaict, nowhere in ima are the stashed dentries needed apart from
ima_policy_release() which is the .release method of the
file_operations where the policy dentry is removed.

The dentries only exist because for pre-namespaced ima if you created a
dentry going through securityfs_create_dentry() you're pinning the
super_block of init-securityfs via simple_pin_fs(). That obliges you to
call securityfs_remove() later on in order to call simple_unpin_fs() for
all dentries.

But for namespaced-ima with namespaced-securityfs there is no more call
to simple_{pin,unpin}_fs(). Consequently you don't need to stash the
dentries anywhere to have them available for removal later on. They will
be automatically cleaned up during .kill_sb().

The one exception I was unaware of reading the code before is in
ima_policy_release(). So apologies, I didn't see that. There you remove:

static int ima_release_policy(struct inode *inode, struct file *file)
{
	struct ima_namespace *ns = get_current_ns();
	const char *cause = ns->valid_policy ? "completed" : "failed";

	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
		return seq_release(inode, file);

	if (ns->valid_policy && ima_check_policy(ns) < 0) {
		cause = "failed";
		ns->valid_policy = 0;
	}

	pr_info("policy update %s\n", cause);
	integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
			    "policy_update", cause, !ns->valid_policy, 0);

	if (!ns->valid_policy) {
		ima_delete_rules(ns);
		ns->valid_policy = 1;
		clear_bit(IMA_FS_BUSY, &ns->ima_fs_flags);
		return 0;
	}

	ima_update_policy(ns);
#if !defined(CONFIG_IMA_WRITE_POLICY) && !defined(CONFIG_IMA_READ_POLICY)
	securityfs_remove(ns->dentry[IMAFS_DENTRY_IMA_POLICY]);
	ns->dentry[IMAFS_DENTRY_IMA_POLICY] = NULL;

^^^^^^^^^^^^^^^^^^^^^^^^^

But even so, why then stash all those dentries if the only dentry that
you ever remove while ima is active - and ima isn't a module so can't be
unloaded - is the IMAFS_DENTRY_IMA_POLICY. Simply stash the single
dentry in struct ima_namespace and forget about all the other ones and
avoid wasting memory. But maybe I'm misunderstanding something.

I'm going to get my booster shot and hopefully I'll be able to work
tomorrow and later today but I wouldn't bet on it.

Christian

  reply	other threads:[~2021-12-09 15:47 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-08 22:18 [PATCH v5 00/16] ima: Namespace IMA with audit support in IMA-ns Stefan Berger
2021-12-08 22:18 ` [PATCH v5 01/16] ima: Add IMA namespace support Stefan Berger
2021-12-08 22:18 ` [PATCH v5 02/16] ima: Define ns_status for storing namespaced iint data Stefan Berger
2021-12-08 22:18 ` [PATCH v5 03/16] ima: Namespace audit status flags Stefan Berger
2021-12-08 22:18 ` [PATCH v5 04/16] ima: Move delayed work queue and variables into ima_namespace Stefan Berger
2021-12-09 13:11   ` Christian Brauner
2021-12-09 15:09     ` Stefan Berger
2021-12-08 22:18 ` [PATCH v5 05/16] ima: Move IMA's keys queue related " Stefan Berger
2021-12-08 22:18 ` [PATCH v5 06/16] ima: Move policy " Stefan Berger
2021-12-08 22:18 ` [PATCH v5 07/16] ima: Move ima_htable " Stefan Berger
2021-12-08 22:18 ` [PATCH v5 08/16] ima: Move measurement list related variables " Stefan Berger
2021-12-08 22:18 ` [PATCH v5 09/16] ima: Only accept AUDIT rules for IMA non-init_ima_ns namespaces for now Stefan Berger
2021-12-08 22:18 ` [PATCH v5 10/16] ima: Implement hierarchical processing of file accesses Stefan Berger
2021-12-08 22:18 ` [PATCH v5 11/16] securityfs: Only use simple_pin_fs/simple_release_fs for init_user_ns Stefan Berger
2021-12-08 22:18 ` [PATCH v5 12/16] securityfs: Extend securityfs with namespacing support Stefan Berger
2021-12-08 22:18 ` [PATCH v5 13/16] ima: Move some IMA policy and filesystem related variables into ima_namespace Stefan Berger
2021-12-09 19:11   ` Christian Brauner
2021-12-09 20:42     ` Stefan Berger
2021-12-10  0:57     ` Stefan Berger
2021-12-10 11:32       ` Christian Brauner
2021-12-10 13:57         ` Stefan Berger
2021-12-10 14:21           ` James Bottomley
2021-12-11  9:50           ` Christian Brauner
2021-12-11 10:45             ` Christian Brauner
2021-12-13 15:33             ` Stefan Berger
2021-12-13 15:50               ` Christian Brauner
2021-12-13 16:03                 ` Christian Brauner
2021-12-13 16:25                 ` Stefan Berger
2021-12-13 16:37                   ` Christian Brauner
2021-12-13 16:40                 ` Christian Brauner
2021-12-10 20:08         ` Stefan Berger
2021-12-11  8:46           ` Christian Brauner
2021-12-08 22:18 ` [PATCH v5 14/16] ima: Use mac_admin_ns_capable() to check corresponding capability Stefan Berger
2021-12-09  7:22   ` Denis Semakin
2021-12-09 13:23     ` James Bottomley
2021-12-09  8:09   ` Denis Semakin
2021-12-11 15:02     ` Serge E. Hallyn
2021-12-11 15:38       ` Stefan Berger
2021-12-11 16:00         ` James Bottomley
2021-12-08 22:18 ` [PATCH v5 15/16] ima: Move dentries into ima_namespace Stefan Berger
2021-12-09 14:34   ` Christian Brauner
2021-12-09 14:37     ` Christian Brauner
2021-12-09 14:41       ` Christian Brauner
2021-12-09 15:00         ` Stefan Berger
2021-12-09 15:47           ` Christian Brauner [this message]
2021-12-09 15:30       ` James Bottomley
2021-12-09 19:38         ` James Bottomley
2021-12-09 20:13           ` Stefan Berger
2021-12-10 11:49           ` Christian Brauner
2021-12-10 12:09             ` Mimi Zohar
2021-12-10 12:40               ` Stefan Berger
2021-12-10 13:02                 ` Mimi Zohar
2021-12-10 14:17                   ` Stefan Berger
2021-12-10 14:26                     ` James Bottomley
2021-12-10 15:26                       ` Mimi Zohar
2021-12-10 15:32                         ` Stefan Berger
2021-12-10 15:48                           ` Mimi Zohar
2021-12-10 16:40                             ` Stefan Berger
2021-12-10 12:40               ` James Bottomley
2021-12-10 12:54                 ` Mimi Zohar
2021-12-12 14:13             ` James Bottomley
2021-12-13 11:25               ` Christian Brauner
2021-12-08 22:18 ` [PATCH v5 16/16] ima: Setup securityfs for IMA namespace Stefan Berger

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=20211209154703.4mprhv2rcgvgkmx5@wittgenstein \
    --to=christian.brauner@ubuntu.com \
    --cc=containers@lists.linux.dev \
    --cc=dmitry.kasatkin@gmail.com \
    --cc=ebiederm@xmission.com \
    --cc=jamjoom@us.ibm.com \
    --cc=jejb@linux.ibm.com \
    --cc=jmorris@namei.org \
    --cc=krzysztof.struczynski@huawei.com \
    --cc=lhinds@redhat.com \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=lsturman@redhat.com \
    --cc=mpeters@redhat.com \
    --cc=paul@paul-moore.com \
    --cc=puiterwi@redhat.com \
    --cc=rgb@redhat.com \
    --cc=roberto.sassu@huawei.com \
    --cc=serge@hallyn.com \
    --cc=stefanb@linux.ibm.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).