From: Richard Guy Briggs <rgb@redhat.com>
To: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
linux-audit@redhat.com, linux-kernel@vger.kernel.org,
"Eric W. Biederman" <ebiederm@xmission.com>
Subject: Re: [PATCH 3/5] audit: store audit_pid as a struct pid pointer
Date: Tue, 21 Jan 2014 18:37:42 -0500 [thread overview]
Message-ID: <20140121233742.GC1981@madcap2.tricolour.ca> (raw)
In-Reply-To: <20131230175103.GC2457@redhat.com>
On 13/12/30, Oleg Nesterov wrote:
> On 12/23, Richard Guy Briggs wrote:
> >
> > - PID will be reported in the relevant querying PID namespace.
> >
> > - Refuse to change the current audit_pid if the new value does not
> > point to an existing process.
> >
> > - Refuse to set the current audit_pid if the new value is not its own PID
> > (unless it is being unset).
>
> I started to read the changelog only after I failed to understand the
> patch. And it looks confusing too.
>
> "Refuse to set the current audit_pid if the new value is not its own PID",
> OK, but if the new value is the caller's pid then it should obviously
> point to the existing process, current?
Yes, but it may be lying, which helps nobody. The value should either
be its own pid, or zero.
> > - Convert audit_pid into the initial pid namespace for reports
>
> I can't apply this patch (and the previous one) due to multiple rejects,
> I guess it depends on other changes?
It depends on other patches in my for-next tree, but not necessarily
functionally.
> In any case, this patch looks wrong.
>
> > @@ -412,9 +412,11 @@ static void kauditd_send_skb(struct sk_buff *skb)
> > BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */
> > if (audit_pid) {
> > pr_err("audit: *NO* daemon at audit_pid=%d\n",
> > - audit_pid);
> > + pid_nr(audit_pid));
> > audit_log_lost("auditd disappeared\n");
> > - audit_pid = 0;
> > + put_pid(audit_pid);
>
> But this can actually free this pid. Why it is safe to use it elsewhere?
>
> > + audit_pid = NULL;
>
> This also means that every "if (audit_pid)" is racy.
Ok, so I really need something like:
if (audit_pid) {
struct pid *temp_pid = audit_pid;
pr_err("*NO* daemon at audit_pid=%d\n", pid_nr(audit_pid));
audit_log_lost("auditd disappeared\n");
audit_pid = NULL;
smp_mb();
put_pid(temp_pid);
audit_sock = NULL;
}
Do I actually need the memory barrier there? Is that the right one to
use?
> > @@ -814,12 +816,26 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
> > return err;
> > }
> > if (s.mask & AUDIT_STATUS_PID) {
> > - int new_pid = s.pid;
> > -
> > - if ((!new_pid) && (task_tgid_vnr(current) != audit_pid))
> > + struct pid *new_pid = find_get_pid(s.pid);
> > + if (s.pid && !new_pid)
> > + return -ESRCH;
>
> can't understand... find_get_pid(s.pid) is pointless if s.pid == 0 ?
"can't understand"? I hope you mean "don't understand". ;-)
> struct pid *new_pid = NULL;
>
> if (new_pid) {
I think you mean "if (s.pid) {".
> new_pid = find_get_pid(s.pid);
> if (!new_pid)
> return -ESRCH;
> }
>
> looks more understandable.
Agreed.
> > + /* check that non-zero pid it is trying to set is its
> > + * own*/
> > + if (s.pid && (s.pid != task_pid_vnr(current)))
>
> again, this looks a bit confusing and suboptimal. Imho it would be better
> to add
>
> if (new_pid != task_tgid(current))
It is not so obvious to me, because this code had been dealing with
pid_t rather than struct pid*, but I agree it may be more optimal.
> into the "if (s.pid)" above. Hmm, actually task_pid_vnr() above looks
> simply wrong, we need tgid or I am totally confused.
The use of task_tgid_vnr() in isolation in commit 34eab0a7 was an error,
I believe, and should have been task_pid_vnr() unless new_pid was then
converted to the thread group leader before being assigned to audit_pid.
I believe auditd only ever registers from the thread group leader, but I
will have to check that assumption with Steve and Eric. If not, I may
have to change it to reference the tgid, making this code a bit more
complex since it would need to convert from pid_t to struct pid*, then
find the tgid.
I'd need to replace:
new_pid = find_get_pid(s.pid);
with:
rcu_read_lock();
new_pid = get_pid(task_tgid(find_task_by_vpid(s.pid)))
rcu_read_unlock();
or it might be nicer to define:
struct pid *audit_find_get_tgid(pid_t vnr) {
rcu_read_lock();
new_pid = get_pid(task_tgid(find_task_by_vpid(vnr)));
rcu_read_unlock();
}
or better yet in kernel/pid.c:
struct pid *find_get_tgid(pid_t vnr) {
rcu_read_lock();
new_pid = get_pid(task_tgid(find_task_by_vpid(vnr)));
rcu_read_unlock();
}
Do you have another reason to believe we need task_tgid_vnr()?
Part of the answer is in 582edda5, but if my assumption above is
correct, we don't need it here.
> OTOH, if we require s.pid == task_pid_vnr(current), then why do we need
> find_pid() at all?
Because userspace may be trying to set it to zero on shutdown, but I
suppose we could special-case zero.
> > + return -EPERM;
>
> this lacks put_pid(new_pid).
Thanks.
> > + /* check that it isn't orphaning another process */
> > + if ((!new_pid) &&
> > + (task_tgid_vnr(current) != pid_vnr(audit_pid)))
> > return -EACCES;
>
> and this can go into the "else" branch.
Yup.
> And I can't understand the "it isn't orphaning another process" logic...
There was a potential race condition that if a second auditd started up
while there was still one running, when the first eventually shut down,
it would try to set the audit_pid to zero to indicate it was going away
and orphan the newer auditd from kaudit.
If we check that the pid of the auditd trying to set it to zero was the
same as the pid recorded in kaudit, we can safely assume it is the
newest and safely set audit_pid to zero.
A newer auditd can orphan a previous auditd, but this isn't really
avoidable since it may be awol and need replacing anyways.
> OK, what if s.pid == 0 and audit_pid == NULL, should we fail in this case?
It doesn't really matter since auditd isn't likely to try this
combinaiton and it won't matter if it fails.
> And I do not see how this matches "Refuse to set the current audit_pid
> if the new value is not its own PID" from the changelog.
>
> > +
> > audit_pid = new_pid;
>
> Another leak, it seems.
Oops, thanks.
> > @@ -1331,7 +1347,8 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
> > return NULL;
> >
> > if (gfp_mask & __GFP_WAIT) {
> > - if (audit_pid && audit_pid == current->pid)
> > + if (pid_nr(audit_pid) == task_pid_nr(current))
>
> So is this audit_pid tid or tgid? Its usage looks totally confusing.
pid, as noted above, but could be changed to tgid.
> Anyway,
>
> if (audit_pid == task_pid(current))
>
> (or probably task_tgid) looks much better.
Fair enough, compare struct pid* rather than the original pid_t.
> > + //if (pid_task(audit_pid, PIDTYPE_PID) == current)
>
> in this case you need to update Documentation/CodingStyle ;)
Heh... trust the SCM... and that was comparing task_structs rather
than pid_t or struct pid*. Still getting comfortable with struct pid*.
> Oleg.
- RGB
--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545
next prev parent reply other threads:[~2014-01-21 23:37 UTC|newest]
Thread overview: 105+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-20 21:31 [PATCH 00/12] RFC: steps to make audit pid namespace-safe Richard Guy Briggs
2013-08-20 21:31 ` [PATCH 01/12] audit: Kill the unused struct audit_aux_data_capset Richard Guy Briggs
2013-08-20 21:31 ` [PATCH 02/12] audit: fix netlink portid naming and types Richard Guy Briggs
2013-08-20 21:31 ` [PATCH 03/12] pid: get ppid pid_t of task in init_pid_ns safely Richard Guy Briggs
2013-08-27 17:21 ` Oleg Nesterov
2013-08-30 19:56 ` Richard Guy Briggs
2013-08-30 20:37 ` John Johansen
2013-08-30 22:41 ` [PATCH 1/3] apparmor: fix capability to not use the current task, during reporting John Johansen
2013-08-30 22:42 ` [PATCH 2/3] apparmor: remove tsk field from the apparmor_audit_struct John Johansen
2013-08-30 22:43 ` [PATCH 03/3] apparmor: remove parent task info from audit logging John Johansen
2013-09-03 18:31 ` [PATCH 03/12] pid: get ppid pid_t of task in init_pid_ns safely Richard Guy Briggs
2013-12-11 14:47 ` Richard Guy Briggs
2013-12-11 16:44 ` John Johansen
2013-12-11 17:19 ` Richard Guy Briggs
2013-08-20 21:31 ` [PATCH 04/12] audit: convert PPIDs to the inital PID namespace Richard Guy Briggs
2013-08-20 21:31 ` [PATCH 05/12] pid: get pid_t of task in init_pid_ns correctly Richard Guy Briggs
2013-08-20 21:31 ` [PATCH 06/12] audit: Simplify and correct audit_log_capset Richard Guy Briggs
2013-08-20 21:31 ` [PATCH 07/12] audit: store audit_pid as a struct pid pointer Richard Guy Briggs
2013-08-20 21:32 ` [PATCH 08/12] audit: anchor all pid references in the initial pid namespace Richard Guy Briggs
2013-08-20 21:32 ` [PATCH 09/12] pid: modify task_pid_nr to work without task->pid Richard Guy Briggs
2013-12-16 21:03 ` [PATCH] pid: change task_struct::pid to read-only Richard Guy Briggs
2013-12-17 9:58 ` Peter Zijlstra
[not found] ` <20131220044826.GF14944@madcap2.tricolour.ca>
2013-12-20 4:48 ` Richard Guy Briggs
2013-12-17 9:59 ` Peter Zijlstra
2013-12-17 15:36 ` Oleg Nesterov
2013-12-17 15:40 ` Oleg Nesterov
2013-12-20 19:01 ` Oleg Nesterov
2013-12-20 20:19 ` Richard Guy Briggs
2013-12-20 21:33 ` Peter Zijlstra
2013-12-22 16:03 ` Oleg Nesterov
2014-01-23 19:24 ` Richard Guy Briggs
[not found] ` <20131220140417.GE14884@madcap2.tricolour.ca>
2014-01-23 19:32 ` [PATCH 0/7][RFC] pid: changes to support audit Richard Guy Briggs
2014-01-23 19:32 ` [PATCH 1/7] pid: change task_struct::pid to read-only Richard Guy Briggs
2014-01-23 19:32 ` [PATCH 2/7] compiler: CONST_CAST makes writing const vars easier and obvious Richard Guy Briggs
2014-01-23 19:32 ` [PATCH 3/7] pid: use the CONST_CAST macro instead to write to const task_struct::pid Richard Guy Briggs
2014-01-23 19:32 ` [PATCH 4/7] pid: modify task_tgid_nr to work without task->tgid Richard Guy Briggs
2014-02-20 18:35 ` Oleg Nesterov
2014-02-21 20:47 ` Richard Guy Briggs
2014-02-24 18:40 ` Oleg Nesterov
2014-01-23 19:32 ` [PATCH 5/7] pid: rewrite task helper function is_global_init() avoiding task->pid Richard Guy Briggs
2014-02-20 18:39 ` Oleg Nesterov
2014-02-21 16:10 ` Richard Guy Briggs
2014-01-23 19:32 ` [PATCH 6/7] pid: mark struct task const in helper functions Richard Guy Briggs
2014-01-23 19:32 ` [PATCH 7/7] pid: get pid_t ppid of task in init_pid_ns Richard Guy Briggs
2014-02-20 19:01 ` Oleg Nesterov
2014-02-21 18:10 ` Richard Guy Briggs
2014-02-24 18:32 ` Oleg Nesterov
2014-03-17 20:14 ` Tony Luck
2014-03-17 20:15 ` Eric Paris
2014-01-23 21:25 ` [PATCH 0/7][RFC] pid: changes to support audit Peter Zijlstra
2014-01-24 6:14 ` Richard Guy Briggs
2014-01-24 8:52 ` Peter Zijlstra
2014-01-24 14:31 ` Richard Guy Briggs
2014-02-19 16:18 ` Richard Guy Briggs
2014-02-19 17:47 ` Oleg Nesterov
2014-02-19 18:15 ` Richard Guy Briggs
2014-02-20 19:08 ` Oleg Nesterov
2013-08-20 21:32 ` [PATCH 10/12] pid: modify task_tgid_nr to work without task->tgid Richard Guy Briggs
2013-08-20 21:32 ` [PATCH 11/12] pid: rewrite task helper functions avoiding task->pid and task->tgid Richard Guy Briggs
2013-08-22 19:08 ` Oleg Nesterov
2013-08-26 22:07 ` Richard Guy Briggs
2013-08-27 16:15 ` Oleg Nesterov
2013-12-16 17:35 ` Richard Guy Briggs
2013-12-16 21:05 ` Oleg Nesterov
2013-12-16 22:20 ` Richard Guy Briggs
2013-12-17 9:34 ` Peter Zijlstra
2013-12-17 9:48 ` Peter Zijlstra
2013-12-20 4:54 ` Richard Guy Briggs
2013-08-22 20:05 ` Peter Zijlstra
2013-08-22 21:43 ` Richard Guy Briggs
2013-08-23 6:36 ` Peter Zijlstra
2013-08-27 2:37 ` Richard Guy Briggs
2013-08-27 12:11 ` Peter Zijlstra
2013-08-27 21:35 ` Eric W. Biederman
2013-08-28 8:16 ` Peter Zijlstra
2013-08-23 19:28 ` Oleg Nesterov
2013-08-27 3:04 ` Richard Guy Briggs
2013-08-27 17:11 ` Oleg Nesterov
2013-08-30 19:06 ` audit looks unmaintained? [was: Re: [PATCH 11/12] pid: rewrite task helper functions avoiding task->pid and task->tgid] Richard Guy Briggs
2013-08-30 19:54 ` Steve Grubb
2013-09-08 15:54 ` Oleg Nesterov
2013-09-10 17:20 ` Oleg Nesterov
2013-09-13 18:42 ` Steve Grubb
2013-09-14 18:10 ` Oleg Nesterov
2013-09-13 18:28 ` Steve Grubb
2013-09-14 18:08 ` Oleg Nesterov
2013-08-20 21:32 ` [PATCH 12/12] pid: mark struct task const in helper functions Richard Guy Briggs
2013-12-23 22:27 ` [PATCH 0/5][RFC][v2] steps to make audit pid namespace-safe Richard Guy Briggs
2013-12-23 22:27 ` [PATCH 1/5] pid: get pid_t ppid of task in init_pid_ns Richard Guy Briggs
2013-12-30 17:04 ` Oleg Nesterov
2013-12-23 22:27 ` [PATCH 2/5] audit: convert PPIDs to the inital PID namespace Richard Guy Briggs
2013-12-30 17:07 ` Oleg Nesterov
2013-12-23 22:27 ` [PATCH 3/5] audit: store audit_pid as a struct pid pointer Richard Guy Briggs
2013-12-30 17:51 ` Oleg Nesterov
2014-01-21 23:37 ` Richard Guy Briggs [this message]
2013-12-23 22:27 ` [PATCH 4/5] audit: anchor all pid references in the initial pid namespace Richard Guy Briggs
2013-12-30 18:06 ` Oleg Nesterov
2014-02-19 20:28 ` Richard Guy Briggs
2013-12-23 22:27 ` [PATCH 5/5] audit: allow user processes to log from another PID namespace Richard Guy Briggs
2014-02-19 20:57 ` [PATCH 0/5][RFC][v3] steps to make audit pid namespace-safe Richard Guy Briggs
2014-02-19 20:57 ` [PATCH 1/5] pid: get pid_t ppid of task in init_pid_ns Richard Guy Briggs
2014-02-19 20:57 ` [PATCH 2/5] audit: convert PPIDs to the inital PID namespace Richard Guy Briggs
2014-02-19 20:57 ` [PATCH 3/5] audit: store audit_pid as a struct pid pointer Richard Guy Briggs
2014-02-19 20:57 ` [PATCH 4/5] audit: anchor all pid references in the initial pid namespace Richard Guy Briggs
2014-02-19 20:57 ` [PATCH 5/5] audit: allow user processes to log from another PID namespace Richard Guy Briggs
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=20140121233742.GC1981@madcap2.tricolour.ca \
--to=rgb@redhat.com \
--cc=ebiederm@xmission.com \
--cc=linux-audit@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=oleg@redhat.com \
--cc=peterz@infradead.org \
/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).