diff options
-rw-r--r-- | include/uapi/linux/audit.h | 2 | ||||
-rw-r--r-- | kernel/audit.c | 31 |
2 files changed, 31 insertions, 2 deletions
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index 4fdedd4c88a1..14afb0d22902 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h | |||
@@ -319,6 +319,7 @@ enum { | |||
319 | #define AUDIT_STATUS_PID 0x0004 | 319 | #define AUDIT_STATUS_PID 0x0004 |
320 | #define AUDIT_STATUS_RATE_LIMIT 0x0008 | 320 | #define AUDIT_STATUS_RATE_LIMIT 0x0008 |
321 | #define AUDIT_STATUS_BACKLOG_LIMIT 0x0010 | 321 | #define AUDIT_STATUS_BACKLOG_LIMIT 0x0010 |
322 | #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020 | ||
322 | /* Failure-to-log actions */ | 323 | /* Failure-to-log actions */ |
323 | #define AUDIT_FAIL_SILENT 0 | 324 | #define AUDIT_FAIL_SILENT 0 |
324 | #define AUDIT_FAIL_PRINTK 1 | 325 | #define AUDIT_FAIL_PRINTK 1 |
@@ -377,6 +378,7 @@ struct audit_status { | |||
377 | __u32 lost; /* messages lost */ | 378 | __u32 lost; /* messages lost */ |
378 | __u32 backlog; /* messages waiting in queue */ | 379 | __u32 backlog; /* messages waiting in queue */ |
379 | __u32 version; /* audit api version number */ | 380 | __u32 version; /* audit api version number */ |
381 | __u32 backlog_wait_time;/* message queue wait timeout */ | ||
380 | }; | 382 | }; |
381 | 383 | ||
382 | struct audit_features { | 384 | struct audit_features { |
diff --git a/kernel/audit.c b/kernel/audit.c index 80b7de02947b..37ba59936dc5 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -334,6 +334,12 @@ static int audit_set_backlog_limit(int limit) | |||
334 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, limit); | 334 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, limit); |
335 | } | 335 | } |
336 | 336 | ||
337 | static int audit_set_backlog_wait_time(int timeout) | ||
338 | { | ||
339 | return audit_do_config_change("audit_backlog_wait_time", | ||
340 | &audit_backlog_wait_time, timeout); | ||
341 | } | ||
342 | |||
337 | static int audit_set_enabled(int state) | 343 | static int audit_set_enabled(int state) |
338 | { | 344 | { |
339 | int rc; | 345 | int rc; |
@@ -778,7 +784,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
778 | s.backlog_limit = audit_backlog_limit; | 784 | s.backlog_limit = audit_backlog_limit; |
779 | s.lost = atomic_read(&audit_lost); | 785 | s.lost = atomic_read(&audit_lost); |
780 | s.backlog = skb_queue_len(&audit_skb_queue); | 786 | s.backlog = skb_queue_len(&audit_skb_queue); |
781 | s.version = 1; | 787 | s.version = 2; |
788 | s.backlog_wait_time = audit_backlog_wait_time; | ||
782 | audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, | 789 | audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, |
783 | &s, sizeof(s)); | 790 | &s, sizeof(s)); |
784 | break; | 791 | break; |
@@ -812,8 +819,28 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
812 | if (err < 0) | 819 | if (err < 0) |
813 | return err; | 820 | return err; |
814 | } | 821 | } |
815 | if (s.mask & AUDIT_STATUS_BACKLOG_LIMIT) | 822 | if (s.mask & AUDIT_STATUS_BACKLOG_LIMIT) { |
816 | err = audit_set_backlog_limit(s.backlog_limit); | 823 | err = audit_set_backlog_limit(s.backlog_limit); |
824 | if (err < 0) | ||
825 | return err; | ||
826 | } | ||
827 | switch (s.version) { | ||
828 | /* add future vers # cases immediately below and allow | ||
829 | * to fall through */ | ||
830 | case 2: | ||
831 | if (s.mask & AUDIT_STATUS_BACKLOG_WAIT_TIME) { | ||
832 | if (sizeof(s) > (size_t)nlh->nlmsg_len) | ||
833 | return -EINVAL; | ||
834 | if (s.backlog_wait_time < 0 || | ||
835 | s.backlog_wait_time > 10*AUDIT_BACKLOG_WAIT_TIME) | ||
836 | return -EINVAL; | ||
837 | err = audit_set_backlog_wait_time(s.backlog_wait_time); | ||
838 | if (err < 0) | ||
839 | return err; | ||
840 | } | ||
841 | default: | ||
842 | break; | ||
843 | } | ||
817 | break; | 844 | break; |
818 | } | 845 | } |
819 | case AUDIT_GET_FEATURE: | 846 | case AUDIT_GET_FEATURE: |