Messages in this thread Patch in this message |  | | From | Richard Guy Briggs <> | Subject | [PATCH 3/5] audit: store audit_pid as a struct pid pointer | Date | Mon, 23 Dec 2013 17:27:37 -0500 |
| |
- 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).
- Convert audit_pid into the initial pid namespace for reports
(informed by ebiederman's 5bf431da) Cc: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Richard Guy Briggs <rgb@redhat.com> --- kernel/audit.c | 35 ++++++++++++++++++++++++++--------- kernel/audit.h | 4 ++-- kernel/auditsc.c | 6 +++--- 3 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c index 900f5d6..48312bf 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -93,7 +93,7 @@ static int audit_failure = AUDIT_FAIL_PRINTK; * contains the pid of the auditd process and audit_nlk_portid contains * the portid to use to send netlink messages to that process. */ -int audit_pid; +struct pid *audit_pid; static __u32 audit_nlk_portid; /* If audit_rate_limit is non-zero, limit the rate of sending audit records @@ -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); + audit_pid = NULL; + audit_sock = NULL; } /* we might get lucky and get this in the next auditd */ @@ -787,7 +789,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) memset(&s, 0, sizeof(s)); s.enabled = audit_enabled; s.failure = audit_failure; - s.pid = audit_pid; + s.pid = pid_vnr(audit_pid); s.rate_limit = audit_rate_limit; s.backlog_limit = audit_backlog_limit; s.lost = atomic_read(&audit_lost); @@ -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; + + /* check that non-zero pid it is trying to set is its + * own*/ + if (s.pid && (s.pid != task_pid_vnr(current))) + return -EPERM; + + /* check that it isn't orphaning another process */ + if ((!new_pid) && + (task_tgid_vnr(current) != pid_vnr(audit_pid))) return -EACCES; + if (audit_enabled != AUDIT_OFF) - audit_log_config_change("audit_pid", new_pid, audit_pid, 1); + audit_log_config_change("audit_pid", + pid_nr(new_pid), + pid_nr(audit_pid), + 1); + audit_pid = new_pid; audit_nlk_portid = NETLINK_CB(skb).portid; audit_sock = NETLINK_CB(skb).sk; @@ -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)) + //if (pid_task(audit_pid, PIDTYPE_PID) == current) gfp_mask &= ~__GFP_WAIT; else reserve = 0; diff --git a/kernel/audit.h b/kernel/audit.h index 0719b45..e6d48f4 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -221,7 +221,7 @@ extern void audit_log_name(struct audit_context *context, struct audit_names *n, struct path *path, int record_num, int *call_panic); -extern int audit_pid; +extern struct pid *audit_pid; #define AUDIT_INODE_BUCKETS 32 extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; @@ -318,7 +318,7 @@ extern u32 audit_sig_sid; extern int __audit_signal_info(int sig, struct task_struct *t); static inline int audit_signal_info(int sig, struct task_struct *t) { - if (unlikely((audit_pid && t->tgid == audit_pid) || + if (unlikely((audit_pid && task_tgid(t) == audit_pid) || (audit_signals && !audit_dummy_context()))) return __audit_signal_info(sig, t); return 0; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index d396c8b..db3cb4f 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -732,7 +732,7 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, struct audit_entry *e; enum audit_state state; - if (audit_pid && tsk->tgid == audit_pid) + if (audit_pid && task_tgid(tsk) == audit_pid) return AUDIT_DISABLED; rcu_read_lock(); @@ -793,7 +793,7 @@ void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx) { struct audit_names *n; - if (audit_pid && tsk->tgid == audit_pid) + if (audit_pid && task_tgid(tsk) == audit_pid) return; rcu_read_lock(); @@ -2231,7 +2231,7 @@ int __audit_signal_info(int sig, struct task_struct *t) struct audit_context *ctx = tsk->audit_context; kuid_t uid = current_uid(), t_uid = task_uid(t); - if (audit_pid && t->tgid == audit_pid) { + if (audit_pid && task_tgid(t) == audit_pid) { if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) { audit_sig_pid = tsk->pid; if (uid_valid(tsk->loginuid)) -- 1.7.1
|  |