From: "Kaigai Kohei" <kaigai@ak.jp.nec.com>
To: "Stephen Smalley" <sds@epoch.ncsc.mil>
Cc: "SELinux-ML(Eng)" <selinux@tycho.nsa.gov>,
"Linux Kernel ML(Eng)" <linux-kernel@vger.kernel.org>,
"James Morris" <jmorris@redhat.com>
Subject: Re: RCU issue with SELinux (Re: SELINUX performance issues)
Date: Thu, 26 Aug 2004 16:53:02 +0900 [thread overview]
Message-ID: <02b701c48b41$b6b05100$f97d220a@linux.bs1.fc.nec.co.jp> (raw)
In-Reply-To: 1093449047.6743.186.camel@moss-spartans.epoch.ncsc.mil
Hi Stephen, thanks for your comments.
> A few other comments on the patch:
>
> + new = kmalloc(sizeof(struct avc_node), GFP_ATOMIC);
> + if (!new)
> + return NULL;
>
> Dynamically allocating the nodes at runtime (rather than pre-allocating
> them and then just reclaiming them as necessary as in the current AVC)
> worries me, as it introduces a new failure case for avc_has_perm.
> Denying permission to a resource due to transient memory shortage is not
> good for robustness. And changing the GFP_ATOMIC is not an option, as
> calling context may not allow blocking. Hence, pre-allocation seems
> desirable, regardless of the locking scheme.
In my understanding, your worry about robustness is the execution path
when kmalloc() returns NULL.
The most significant point is there.
--[ in the original kernel-2.6.8.1 ]--
:
rc = avc_insert(ssid,tsid,tclass,&entry,aeref);
if (rc) {
spin_unlock_irqrestore(&avc_lock,flags);
goto out;
}
:
--------------------------------------
In the original implementation, avc_insert() returns -ENOMEM when we can't
hold a avc_entry by avc_claim_node(), then avc_has_perm_noaudit() denies
the requested permition check by the reason an avc_node is not allocated.
(But avc_insert() always returns 0, because avc_insert() reclaim a avc_node
under the spinlock when free_list is empty.)
However, allocating an avc_node and making the decision according to
the policy of SELinux should be separated in considering.
In my approach with RCU, avc_insert() can actually return NULL.
Currently, avc_has_perm_noaudit() returns -ENOMEM without the decision-making
like as the original implementation.
But we can make an decision according to the policy of SELinux by a suitable
recover processing.
My proposal is as follows:
- Normaly, decision-making is performed to the entry on AVC.
These entries are allocated by kmalloc()
- When kmalloc() called by the extension of avc_insert() returns NULL,
the decision-making is performed to the entry on stack variable,
then the entry is not hold on AVC.
-- e.g. in avc_has_perm_noaudit() --------------
:
struct avc_entry local_ae, *ae;
:
node = avc_insert(....);
if (!node) {
SETUP_LOCAL_AE(&local_ae,&entry.avd);
ae = &local_ae;
} else {
ae = &node->ae;
}
if (avd)
memcpy(avd, &ae->avd, sizeof(*avd));
:
------------------------------------------------
By this method, the decision-making is available irrespective of
the result of kmalloc(). Is it robustless?
The original implementation has too many lock contensitons in Big-SMP
environment. It is more positive to consider the method using RCU.
> In trying to merge the logic related to latest_notif, you've introduced
> a bug - latest_notif should only be increased, never decreased. See the
> original logic from avc_control and avc_ss_reset prior to your patch.
> Those functions update the latest notif based on a policy change event.
> In the insert case, you are checking that the entry is not stale, i.e.
> has a smaller seqno than the latest notification due to an interleaving
> with a policy change event.
Ooooooops!
It is toooooo trivial BUG!
I'll fix them very soon.
> + if (node->ae.avd.allowed != (node->ae.avd.allowed|requested))
> + avc_update_node(AVC_CALLBACK_GRANT
> + ,requested,ssid,tsid,tclass);
> }
>
> The test seems unnecessary, as the function has already determined that
> not all of the requested permissions were granted, so you should be able
> to just unconditionally call avc_update_node here, and you only need to
> pass it the denied set that has already been computed, as any other
> permissions in requested were already allowed.
Indeed, it is right. I'll fix them soon.
avc_update_node() is in the section between rcu_read_lock() and rcu_read_unlock().
> - rc = -ENOENT;
> out:
> - return rc;
> + return node;
> +}
>
> Ah, I think the bug is here.
Oops!
I agree, and fix this soon.
Please wait for a patch, thanks.
--------
Kai Gai <kaigai@ak.jp.nec.com>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
WARNING: multiple messages have this Message-ID (diff)
From: "Kaigai Kohei" <kaigai@ak.jp.nec.com>
To: "Stephen Smalley" <sds@epoch.ncsc.mil>
Cc: "SELinux-ML(Eng)" <selinux@tycho.nsa.gov>,
"Linux Kernel ML(Eng)" <linux-kernel@vger.kernel.org>,
"James Morris" <jmorris@redhat.com>
Subject: Re: RCU issue with SELinux (Re: SELINUX performance issues)
Date: Thu, 26 Aug 2004 16:53:02 +0900 [thread overview]
Message-ID: <02b701c48b41$b6b05100$f97d220a@linux.bs1.fc.nec.co.jp> (raw)
In-Reply-To: 1093449047.6743.186.camel@moss-spartans.epoch.ncsc.mil
Hi Stephen, thanks for your comments.
> A few other comments on the patch:
>
> + new = kmalloc(sizeof(struct avc_node), GFP_ATOMIC);
> + if (!new)
> + return NULL;
>
> Dynamically allocating the nodes at runtime (rather than pre-allocating
> them and then just reclaiming them as necessary as in the current AVC)
> worries me, as it introduces a new failure case for avc_has_perm.
> Denying permission to a resource due to transient memory shortage is not
> good for robustness. And changing the GFP_ATOMIC is not an option, as
> calling context may not allow blocking. Hence, pre-allocation seems
> desirable, regardless of the locking scheme.
In my understanding, your worry about robustness is the execution path
when kmalloc() returns NULL.
The most significant point is there.
--[ in the original kernel-2.6.8.1 ]--
:
rc = avc_insert(ssid,tsid,tclass,&entry,aeref);
if (rc) {
spin_unlock_irqrestore(&avc_lock,flags);
goto out;
}
:
--------------------------------------
In the original implementation, avc_insert() returns -ENOMEM when we can't
hold a avc_entry by avc_claim_node(), then avc_has_perm_noaudit() denies
the requested permition check by the reason an avc_node is not allocated.
(But avc_insert() always returns 0, because avc_insert() reclaim a avc_node
under the spinlock when free_list is empty.)
However, allocating an avc_node and making the decision according to
the policy of SELinux should be separated in considering.
In my approach with RCU, avc_insert() can actually return NULL.
Currently, avc_has_perm_noaudit() returns -ENOMEM without the decision-making
like as the original implementation.
But we can make an decision according to the policy of SELinux by a suitable
recover processing.
My proposal is as follows:
- Normaly, decision-making is performed to the entry on AVC.
These entries are allocated by kmalloc()
- When kmalloc() called by the extension of avc_insert() returns NULL,
the decision-making is performed to the entry on stack variable,
then the entry is not hold on AVC.
-- e.g. in avc_has_perm_noaudit() --------------
:
struct avc_entry local_ae, *ae;
:
node = avc_insert(....);
if (!node) {
SETUP_LOCAL_AE(&local_ae,&entry.avd);
ae = &local_ae;
} else {
ae = &node->ae;
}
if (avd)
memcpy(avd, &ae->avd, sizeof(*avd));
:
------------------------------------------------
By this method, the decision-making is available irrespective of
the result of kmalloc(). Is it robustless?
The original implementation has too many lock contensitons in Big-SMP
environment. It is more positive to consider the method using RCU.
> In trying to merge the logic related to latest_notif, you've introduced
> a bug - latest_notif should only be increased, never decreased. See the
> original logic from avc_control and avc_ss_reset prior to your patch.
> Those functions update the latest notif based on a policy change event.
> In the insert case, you are checking that the entry is not stale, i.e.
> has a smaller seqno than the latest notification due to an interleaving
> with a policy change event.
Ooooooops!
It is toooooo trivial BUG!
I'll fix them very soon.
> + if (node->ae.avd.allowed != (node->ae.avd.allowed|requested))
> + avc_update_node(AVC_CALLBACK_GRANT
> + ,requested,ssid,tsid,tclass);
> }
>
> The test seems unnecessary, as the function has already determined that
> not all of the requested permissions were granted, so you should be able
> to just unconditionally call avc_update_node here, and you only need to
> pass it the denied set that has already been computed, as any other
> permissions in requested were already allowed.
Indeed, it is right. I'll fix them soon.
avc_update_node() is in the section between rcu_read_lock() and rcu_read_unlock().
> - rc = -ENOENT;
> out:
> - return rc;
> + return node;
> +}
>
> Ah, I think the bug is here.
Oops!
I agree, and fix this soon.
Please wait for a patch, thanks.
--------
Kai Gai <kaigai@ak.jp.nec.com>
next prev parent reply other threads:[~2004-08-26 7:53 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-08-16 9:33 RCU issue with SELinux (Re: SELINUX performance issues) Kaigai Kohei
2004-08-16 9:33 ` Kaigai Kohei
2004-08-16 15:19 ` James Morris
2004-08-16 15:19 ` James Morris
2004-08-20 13:36 ` Kaigai Kohei
2004-08-20 14:53 ` James Morris
2004-08-20 14:53 ` James Morris
2004-08-24 7:27 ` Kaigai Kohei
2004-08-24 7:27 ` Kaigai Kohei
2004-08-24 13:24 ` James Morris
2004-08-24 13:24 ` James Morris
2004-08-25 9:51 ` Kaigai Kohei
2004-08-25 9:51 ` Kaigai Kohei
2004-08-25 18:31 ` James Morris
2004-08-25 18:31 ` James Morris
2004-08-25 9:52 ` [PATCH]atomic_inc_return() for i386/x86_64 (Re: RCU issue with SELinux) Kaigai Kohei
2004-08-20 17:31 ` RCU issue with SELinux (Re: SELINUX performance issues) Luke Kenneth Casson Leighton
2004-08-20 17:31 ` Luke Kenneth Casson Leighton
2004-08-20 18:15 ` James Morris
2004-08-20 18:15 ` James Morris
2004-08-20 20:19 ` Paul E. McKenney
2004-08-20 20:35 ` James Morris
2004-08-20 20:35 ` James Morris
2004-08-24 7:27 ` Kaigai Kohei
2004-08-24 7:27 ` Kaigai Kohei
[not found] ` <1093014789.16585.186.camel@moss-spartans.epoch.ncsc.mil>
2004-08-24 7:25 ` Kaigai Kohei
2004-08-24 15:37 ` Stephen Smalley
2004-08-24 15:37 ` Stephen Smalley
2004-08-25 9:51 ` Kaigai Kohei
2004-08-25 15:50 ` Stephen Smalley
2004-08-25 15:50 ` Stephen Smalley
2004-08-25 16:11 ` Stephen Smalley
2004-08-25 16:11 ` Stephen Smalley
2004-08-26 7:53 ` Kaigai Kohei [this message]
2004-08-26 7:53 ` Kaigai Kohei
2004-08-26 13:24 ` Stephen Smalley
2004-08-26 13:24 ` Stephen Smalley
2004-08-27 11:07 ` Kaigai Kohei
2004-08-27 11:07 ` Kaigai Kohei
2004-08-30 11:17 ` [PATCH]SELinux performance improvement by RCU (Re: RCU issue with SELinux) Kaigai Kohei
2004-08-30 15:35 ` Stephen Smalley
2004-08-30 15:35 ` Stephen Smalley
2004-08-30 16:13 ` Paul E. McKenney
2004-08-30 16:13 ` Paul E. McKenney
2004-08-31 4:33 ` Kaigai Kohei
2004-08-31 4:33 ` Kaigai Kohei
2004-08-31 16:20 ` Paul E. McKenney
2004-08-31 16:20 ` Paul E. McKenney
2004-08-31 15:33 ` James Morris
2004-08-31 15:33 ` James Morris
2004-08-24 23:02 ` RCU issue with SELinux (Re: SELINUX performance issues) Paul E. McKenney
2004-08-24 23:02 ` Paul E. McKenney
2004-08-25 9:51 ` Kaigai Kohei
2004-08-25 9:51 ` Kaigai Kohei
2004-08-25 17:34 ` Paul E. McKenney
2004-08-25 17:34 ` Paul E. McKenney
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='02b701c48b41$b6b05100$f97d220a@linux.bs1.fc.nec.co.jp' \
--to=kaigai@ak.jp.nec.com \
--cc=jmorris@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=sds@epoch.ncsc.mil \
--cc=selinux@tycho.nsa.gov \
/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.