- 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" <ebied...@xmission.com>
Signed-off-by: Richard Guy Briggs <r...@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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to