@@ -94,7 +94,6 @@ struct audit_net {
/**
* struct auditd_connection - kernel/auditd connection state
- * @pid: auditd PID
* @portid: netlink portid
* @net: the associated network namespace
* @rcu: RCU head
@@ -104,7 +103,6 @@ struct audit_net {
* or the associated spinlock for writing.
*/
struct auditd_connection {
- struct pid *pid;
u32 portid;
struct net *net;
struct rcu_head rcu;
@@ -248,15 +246,11 @@ static bool audit_ctl_owner_current(void)
static pid_t auditd_pid_vnr(void)
{
pid_t pid;
- const struct auditd_connection *ac;
+ unsigned long flags;
- rcu_read_lock();
- ac = rcu_dereference(auditd_conn);
- if (!ac || !ac->pid)
- pid = 0;
- else
- pid = pid_vnr(ac->pid);
- rcu_read_unlock();
+ spin_lock_irqsave(&auditd_conn_lock, flags);
+ pid = auditd_pid ? pid_vnr(auditd_pid) : 0;
+ spin_unlock_irqrestore(&auditd_conn_lock, flags);
return pid;
}
@@ -459,7 +453,6 @@ static void auditd_conn_free(struct rcu_head *rcu)
struct auditd_connection *ac;
ac = container_of(rcu, struct auditd_connection, rcu);
- put_pid(ac->pid);
put_net(ac->net);
kfree(ac);
}
@@ -478,6 +471,7 @@ static int auditd_set(struct pid *pid, u32 portid, struct net *net)
{
unsigned long flags;
struct auditd_connection *ac_old, *ac_new;
+ struct pid *auditd_pid_old;
if (!pid || !net)
return -EINVAL;
@@ -485,7 +479,6 @@ static int auditd_set(struct pid *pid, u32 portid, struct net *net)
ac_new = kzalloc(sizeof(*ac_new), GFP_KERNEL);
if (!ac_new)
return -ENOMEM;
- ac_new->pid = get_pid(pid);
ac_new->portid = portid;
ac_new->net = get_net(net);
@@ -493,9 +486,11 @@ static int auditd_set(struct pid *pid, u32 portid, struct net *net)
ac_old = rcu_dereference_protected(auditd_conn,
lockdep_is_held(&auditd_conn_lock));
rcu_assign_pointer(auditd_conn, ac_new);
- WRITE_ONCE(auditd_pid, ac_new->pid);
+ auditd_pid_old = auditd_pid;
+ WRITE_ONCE(auditd_pid, get_pid(pid));
spin_unlock_irqrestore(&auditd_conn_lock, flags);
+ put_pid(auditd_pid_old);
if (ac_old)
call_rcu(&ac_old->rcu, auditd_conn_free);
@@ -623,6 +618,7 @@ static void auditd_reset(const struct auditd_connection *ac)
unsigned long flags;
struct sk_buff *skb;
struct auditd_connection *ac_old;
+ struct pid *auditd_pid_old;
/* if it isn't already broken, break the connection */
spin_lock_irqsave(&auditd_conn_lock, flags);
@@ -634,9 +630,11 @@ static void auditd_reset(const struct auditd_connection *ac)
return;
}
rcu_assign_pointer(auditd_conn, NULL);
+ auditd_pid_old = auditd_pid;
WRITE_ONCE(auditd_pid, NULL);
spin_unlock_irqrestore(&auditd_conn_lock, flags);
+ put_pid(auditd_pid_old);
if (ac_old)
call_rcu(&ac_old->rcu, auditd_conn_free);
auditd_conn.pid is redundant. Replace it with auditd_pid. Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com> --- kernel/audit.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)