Merge branch 'stable-4.11' of git://git.infradead.org/users/pcmoore/audit
Pull audit fix from Paul Moore: "One more small audit fix, this should be the last for v4.11. Seth Forshee noticed a problem where the audit retry queue wasn't being flushed properly when audit was enabled and the audit daemon wasn't running; this patches fixes the problem (see the commit description for more details on the change). Both Seth and I have tested this and everything looks good" * 'stable-4.11' of git://git.infradead.org/users/pcmoore/audit: audit: make sure we don't let the retry queue grow without bounds
This commit is contained in:
commit
b9b3322f13
|
@ -160,7 +160,6 @@ static LIST_HEAD(audit_freelist);
|
||||||
|
|
||||||
/* queue msgs to send via kauditd_task */
|
/* queue msgs to send via kauditd_task */
|
||||||
static struct sk_buff_head audit_queue;
|
static struct sk_buff_head audit_queue;
|
||||||
static void kauditd_hold_skb(struct sk_buff *skb);
|
|
||||||
/* queue msgs due to temporary unicast send problems */
|
/* queue msgs due to temporary unicast send problems */
|
||||||
static struct sk_buff_head audit_retry_queue;
|
static struct sk_buff_head audit_retry_queue;
|
||||||
/* queue msgs waiting for new auditd connection */
|
/* queue msgs waiting for new auditd connection */
|
||||||
|
@ -453,30 +452,6 @@ static void auditd_set(int pid, u32 portid, struct net *net)
|
||||||
spin_unlock_irqrestore(&auditd_conn.lock, flags);
|
spin_unlock_irqrestore(&auditd_conn.lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* auditd_reset - Disconnect the auditd connection
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Break the auditd/kauditd connection and move all the queued records into the
|
|
||||||
* hold queue in case auditd reconnects.
|
|
||||||
*/
|
|
||||||
static void auditd_reset(void)
|
|
||||||
{
|
|
||||||
struct sk_buff *skb;
|
|
||||||
|
|
||||||
/* if it isn't already broken, break the connection */
|
|
||||||
rcu_read_lock();
|
|
||||||
if (auditd_conn.pid)
|
|
||||||
auditd_set(0, 0, NULL);
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
/* flush all of the main and retry queues to the hold queue */
|
|
||||||
while ((skb = skb_dequeue(&audit_retry_queue)))
|
|
||||||
kauditd_hold_skb(skb);
|
|
||||||
while ((skb = skb_dequeue(&audit_queue)))
|
|
||||||
kauditd_hold_skb(skb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kauditd_print_skb - Print the audit record to the ring buffer
|
* kauditd_print_skb - Print the audit record to the ring buffer
|
||||||
* @skb: audit record
|
* @skb: audit record
|
||||||
|
@ -505,9 +480,6 @@ static void kauditd_rehold_skb(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
/* put the record back in the queue at the same place */
|
/* put the record back in the queue at the same place */
|
||||||
skb_queue_head(&audit_hold_queue, skb);
|
skb_queue_head(&audit_hold_queue, skb);
|
||||||
|
|
||||||
/* fail the auditd connection */
|
|
||||||
auditd_reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -544,9 +516,6 @@ static void kauditd_hold_skb(struct sk_buff *skb)
|
||||||
/* we have no other options - drop the message */
|
/* we have no other options - drop the message */
|
||||||
audit_log_lost("kauditd hold queue overflow");
|
audit_log_lost("kauditd hold queue overflow");
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
|
||||||
/* fail the auditd connection */
|
|
||||||
auditd_reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -566,6 +535,30 @@ static void kauditd_retry_skb(struct sk_buff *skb)
|
||||||
skb_queue_tail(&audit_retry_queue, skb);
|
skb_queue_tail(&audit_retry_queue, skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* auditd_reset - Disconnect the auditd connection
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Break the auditd/kauditd connection and move all the queued records into the
|
||||||
|
* hold queue in case auditd reconnects.
|
||||||
|
*/
|
||||||
|
static void auditd_reset(void)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb;
|
||||||
|
|
||||||
|
/* if it isn't already broken, break the connection */
|
||||||
|
rcu_read_lock();
|
||||||
|
if (auditd_conn.pid)
|
||||||
|
auditd_set(0, 0, NULL);
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
/* flush all of the main and retry queues to the hold queue */
|
||||||
|
while ((skb = skb_dequeue(&audit_retry_queue)))
|
||||||
|
kauditd_hold_skb(skb);
|
||||||
|
while ((skb = skb_dequeue(&audit_queue)))
|
||||||
|
kauditd_hold_skb(skb);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* auditd_send_unicast_skb - Send a record via unicast to auditd
|
* auditd_send_unicast_skb - Send a record via unicast to auditd
|
||||||
* @skb: audit record
|
* @skb: audit record
|
||||||
|
@ -758,6 +751,7 @@ static int kauditd_thread(void *dummy)
|
||||||
NULL, kauditd_rehold_skb);
|
NULL, kauditd_rehold_skb);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
sk = NULL;
|
sk = NULL;
|
||||||
|
auditd_reset();
|
||||||
goto main_queue;
|
goto main_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,6 +761,7 @@ static int kauditd_thread(void *dummy)
|
||||||
NULL, kauditd_hold_skb);
|
NULL, kauditd_hold_skb);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
sk = NULL;
|
sk = NULL;
|
||||||
|
auditd_reset();
|
||||||
goto main_queue;
|
goto main_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,16 +770,18 @@ main_queue:
|
||||||
* unicast, dump failed record sends to the retry queue; if
|
* unicast, dump failed record sends to the retry queue; if
|
||||||
* sk == NULL due to previous failures we will just do the
|
* sk == NULL due to previous failures we will just do the
|
||||||
* multicast send and move the record to the retry queue */
|
* multicast send and move the record to the retry queue */
|
||||||
kauditd_send_queue(sk, portid, &audit_queue, 1,
|
rc = kauditd_send_queue(sk, portid, &audit_queue, 1,
|
||||||
kauditd_send_multicast_skb,
|
kauditd_send_multicast_skb,
|
||||||
kauditd_retry_skb);
|
kauditd_retry_skb);
|
||||||
|
if (sk == NULL || rc < 0)
|
||||||
|
auditd_reset();
|
||||||
|
sk = NULL;
|
||||||
|
|
||||||
/* drop our netns reference, no auditd sends past this line */
|
/* drop our netns reference, no auditd sends past this line */
|
||||||
if (net) {
|
if (net) {
|
||||||
put_net(net);
|
put_net(net);
|
||||||
net = NULL;
|
net = NULL;
|
||||||
}
|
}
|
||||||
sk = NULL;
|
|
||||||
|
|
||||||
/* we have processed all the queues so wake everyone */
|
/* we have processed all the queues so wake everyone */
|
||||||
wake_up(&audit_backlog_wait);
|
wake_up(&audit_backlog_wait);
|
||||||
|
|
Loading…
Reference in New Issue