-/* Move data from tmp buffer into an skb. This is an extra copy, and
- * that is unfortunate. However, the copy will only occur when a record
- * is being written to user space, which is already a high-overhead
- * operation. (Elimination of the copy is possible, for example, by
- * writing directly into a pre-allocated skb, at the cost of wasting
- * memory. */
-static void audit_log_move(struct audit_buffer *ab)
-{
- struct sk_buff *skb;
- struct nlmsghdr *nlh;
- char *start;
- int len = NLMSG_SPACE(0) + ab->len + 1;
-
- /* possible resubmission */
- if (ab->skb)
- return;
-
- skb = alloc_skb(len, GFP_ATOMIC);
- if (!skb) {
- /* Lose information in ab->tmp */
- audit_log_lost("out of memory in audit_log_move");
- return;
- }
- ab->skb = skb;
- nlh = (struct nlmsghdr *)skb_put(skb, NLMSG_SPACE(0));
- nlh->nlmsg_type = ab->type;
- nlh->nlmsg_len = ab->len;
- nlh->nlmsg_flags = 0;
- nlh->nlmsg_pid = ab->pid;
- nlh->nlmsg_seq = 0;
- start = skb_put(skb, ab->len);
- memcpy(start, ab->tmp, ab->len);
-}
-
-/* Iterate over the skbuff in the audit_buffer, sending their contents
- * to user space. */
-static inline int audit_log_drain(struct audit_buffer *ab)
-{
- struct sk_buff *skb = ab->skb;
-
- if (skb) {
- int retval = 0;
-
- if (audit_pid) {
- skb_get(skb); /* because netlink_* frees */
- retval = netlink_unicast(audit_sock, skb, audit_pid,
- MSG_DONTWAIT);
- }
- if (retval == -EAGAIN &&
- (atomic_read(&audit_backlog)) < audit_backlog_limit) {
- audit_log_end_irq(ab);
- return 1;
- }
- if (retval < 0) {
- if (retval == -ECONNREFUSED) {
- printk(KERN_ERR
- "audit: *NO* daemon at audit_pid=%d\n",
- audit_pid);
- audit_pid = 0;
- } else
- audit_log_lost("netlink socket too busy");
- }
- if (!audit_pid) { /* No daemon */
- int offset = NLMSG_SPACE(0);
- int len = skb->len - offset;
- skb->data[offset + len] = '\0';
- printk(KERN_ERR "%s\n", skb->data + offset);
- }
- kfree_skb(skb);
- }
- return 0;
-}