[AUDIT] ratelimit printk messages audit

some printk messages from the audit system can become excessive. This
patch ratelimits those messages. It was found that messages, such as
the audit backlog lost printk message could flood the logs to the point
that a machine could take an nmi watchdog hit or otherwise become
unresponsive.

Signed-off-by: Eric Paris <eparis@redhat.com>

authored by Eric Paris and committed by Al Viro 320f1b1e 148b38dc

+18 -9
+18 -9
kernel/audit.c
··· 166 case AUDIT_FAIL_SILENT: 167 break; 168 case AUDIT_FAIL_PRINTK: 169 - printk(KERN_ERR "audit: %s\n", message); 170 break; 171 case AUDIT_FAIL_PANIC: 172 panic("audit: %s\n", message); ··· 235 } 236 237 if (print) { 238 - printk(KERN_WARNING 239 - "audit: audit_lost=%d audit_rate_limit=%d audit_backlog_limit=%d\n", 240 - atomic_read(&audit_lost), 241 - audit_rate_limit, 242 - audit_backlog_limit); 243 audit_panic(message); 244 } 245 } ··· 355 audit_pid = 0; 356 } 357 } else { 358 - printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0)); 359 kfree_skb(skb); 360 } 361 } else { ··· 1073 remove_wait_queue(&audit_backlog_wait, &wait); 1074 continue; 1075 } 1076 - if (audit_rate_check()) 1077 printk(KERN_WARNING 1078 "audit: audit_backlog=%d > " 1079 "audit_backlog_limit=%d\n", ··· 1356 skb_queue_tail(&audit_skb_queue, ab->skb); 1357 ab->skb = NULL; 1358 wake_up_interruptible(&kauditd_wait); 1359 - } else { 1360 struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); 1361 printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, ab->skb->data + NLMSG_SPACE(0)); 1362 } 1363 } 1364 audit_buffer_free(ab);
··· 166 case AUDIT_FAIL_SILENT: 167 break; 168 case AUDIT_FAIL_PRINTK: 169 + if (printk_ratelimit()) 170 + printk(KERN_ERR "audit: %s\n", message); 171 break; 172 case AUDIT_FAIL_PANIC: 173 panic("audit: %s\n", message); ··· 234 } 235 236 if (print) { 237 + if (printk_ratelimit()) 238 + printk(KERN_WARNING 239 + "audit: audit_lost=%d audit_rate_limit=%d " 240 + "audit_backlog_limit=%d\n", 241 + atomic_read(&audit_lost), 242 + audit_rate_limit, 243 + audit_backlog_limit); 244 audit_panic(message); 245 } 246 } ··· 352 audit_pid = 0; 353 } 354 } else { 355 + if (printk_ratelimit()) 356 + printk(KERN_NOTICE "%s\n", skb->data + 357 + NLMSG_SPACE(0)); 358 + else 359 + audit_log_lost("printk limit exceeded\n"); 360 kfree_skb(skb); 361 } 362 } else { ··· 1066 remove_wait_queue(&audit_backlog_wait, &wait); 1067 continue; 1068 } 1069 + if (audit_rate_check() && printk_ratelimit()) 1070 printk(KERN_WARNING 1071 "audit: audit_backlog=%d > " 1072 "audit_backlog_limit=%d\n", ··· 1349 skb_queue_tail(&audit_skb_queue, ab->skb); 1350 ab->skb = NULL; 1351 wake_up_interruptible(&kauditd_wait); 1352 + } else if (printk_ratelimit()) { 1353 struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); 1354 printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, ab->skb->data + NLMSG_SPACE(0)); 1355 + } else { 1356 + audit_log_lost("printk limit exceeded\n"); 1357 } 1358 } 1359 audit_buffer_free(ab);