diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 16 | ||||
-rw-r--r-- | MAINTAINERS | 3 | ||||
-rw-r--r-- | drivers/tty/tty_audit.c | 2 | ||||
-rw-r--r-- | include/asm-generic/audit_change_attr.h | 4 | ||||
-rw-r--r-- | include/asm-generic/audit_write.h | 6 | ||||
-rw-r--r-- | include/linux/audit.h | 22 | ||||
-rw-r--r-- | include/linux/init_task.h | 2 | ||||
-rw-r--r-- | include/net/netlabel.h | 2 | ||||
-rw-r--r-- | include/net/xfrm.h | 20 | ||||
-rw-r--r-- | include/uapi/linux/audit.h | 8 | ||||
-rw-r--r-- | kernel/audit.c | 365 | ||||
-rw-r--r-- | kernel/audit.h | 15 | ||||
-rw-r--r-- | kernel/auditfilter.c | 93 | ||||
-rw-r--r-- | kernel/auditsc.c | 44 | ||||
-rw-r--r-- | kernel/capability.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 8 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 6 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 12 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 12 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 5 |
20 files changed, 404 insertions, 243 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index f085a61a1edd..d4762d7ebd14 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -463,6 +463,22 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
463 | atkbd.softrepeat= [HW] | 463 | atkbd.softrepeat= [HW] |
464 | Use software keyboard repeat | 464 | Use software keyboard repeat |
465 | 465 | ||
466 | audit= [KNL] Enable the audit sub-system | ||
467 | Format: { "0" | "1" } (0 = disabled, 1 = enabled) | ||
468 | 0 - kernel audit is disabled and can not be enabled | ||
469 | until the next reboot | ||
470 | unset - kernel audit is initialized but disabled and | ||
471 | will be fully enabled by the userspace auditd. | ||
472 | 1 - kernel audit is initialized and partially enabled, | ||
473 | storing at most audit_backlog_limit messages in | ||
474 | RAM until it is fully enabled by the userspace | ||
475 | auditd. | ||
476 | Default: unset | ||
477 | |||
478 | audit_backlog_limit= [KNL] Set the audit queue size limit. | ||
479 | Format: <int> (must be >=0) | ||
480 | Default: 64 | ||
481 | |||
466 | baycom_epp= [HW,AX25] | 482 | baycom_epp= [HW,AX25] |
467 | Format: <io>,<mode> | 483 | Format: <io>,<mode> |
468 | 484 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 671047620dbb..3229945a96b3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1597,11 +1597,10 @@ S: Supported | |||
1597 | F: drivers/scsi/esas2r | 1597 | F: drivers/scsi/esas2r |
1598 | 1598 | ||
1599 | AUDIT SUBSYSTEM | 1599 | AUDIT SUBSYSTEM |
1600 | M: Al Viro <viro@zeniv.linux.org.uk> | ||
1601 | M: Eric Paris <eparis@redhat.com> | 1600 | M: Eric Paris <eparis@redhat.com> |
1602 | L: linux-audit@redhat.com (subscribers-only) | 1601 | L: linux-audit@redhat.com (subscribers-only) |
1603 | W: http://people.redhat.com/sgrubb/audit/ | 1602 | W: http://people.redhat.com/sgrubb/audit/ |
1604 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current.git | 1603 | T: git git://git.infradead.org/users/eparis/audit.git |
1605 | S: Maintained | 1604 | S: Maintained |
1606 | F: include/linux/audit.h | 1605 | F: include/linux/audit.h |
1607 | F: include/uapi/linux/audit.h | 1606 | F: include/uapi/linux/audit.h |
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index a4fdce74f883..b0e540137e39 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c | |||
@@ -67,7 +67,7 @@ static void tty_audit_log(const char *description, int major, int minor, | |||
67 | struct task_struct *tsk = current; | 67 | struct task_struct *tsk = current; |
68 | uid_t uid = from_kuid(&init_user_ns, task_uid(tsk)); | 68 | uid_t uid = from_kuid(&init_user_ns, task_uid(tsk)); |
69 | uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(tsk)); | 69 | uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(tsk)); |
70 | u32 sessionid = audit_get_sessionid(tsk); | 70 | unsigned int sessionid = audit_get_sessionid(tsk); |
71 | 71 | ||
72 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY); | 72 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY); |
73 | if (ab) { | 73 | if (ab) { |
diff --git a/include/asm-generic/audit_change_attr.h b/include/asm-generic/audit_change_attr.h index 89b73e5d0fd0..a1865537339b 100644 --- a/include/asm-generic/audit_change_attr.h +++ b/include/asm-generic/audit_change_attr.h | |||
@@ -4,9 +4,11 @@ __NR_chmod, | |||
4 | __NR_fchmod, | 4 | __NR_fchmod, |
5 | #ifdef __NR_chown | 5 | #ifdef __NR_chown |
6 | __NR_chown, | 6 | __NR_chown, |
7 | __NR_fchown, | ||
8 | __NR_lchown, | 7 | __NR_lchown, |
9 | #endif | 8 | #endif |
9 | #ifdef __NR_fchown | ||
10 | __NR_fchown, | ||
11 | #endif | ||
10 | __NR_setxattr, | 12 | __NR_setxattr, |
11 | __NR_lsetxattr, | 13 | __NR_lsetxattr, |
12 | __NR_fsetxattr, | 14 | __NR_fsetxattr, |
diff --git a/include/asm-generic/audit_write.h b/include/asm-generic/audit_write.h index e7020c57b13b..274575d7129f 100644 --- a/include/asm-generic/audit_write.h +++ b/include/asm-generic/audit_write.h | |||
@@ -10,6 +10,12 @@ __NR_truncate, | |||
10 | #ifdef __NR_truncate64 | 10 | #ifdef __NR_truncate64 |
11 | __NR_truncate64, | 11 | __NR_truncate64, |
12 | #endif | 12 | #endif |
13 | #ifdef __NR_ftruncate | ||
14 | __NR_ftruncate, | ||
15 | #endif | ||
16 | #ifdef __NR_ftruncate64 | ||
17 | __NR_ftruncate64, | ||
18 | #endif | ||
13 | #ifdef __NR_bind | 19 | #ifdef __NR_bind |
14 | __NR_bind, /* bind can affect fs object only in one way... */ | 20 | __NR_bind, /* bind can affect fs object only in one way... */ |
15 | #endif | 21 | #endif |
diff --git a/include/linux/audit.h b/include/linux/audit.h index a40641954c29..aa865a9a4c4f 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -137,7 +137,7 @@ static inline void audit_syscall_exit(void *pt_regs) | |||
137 | { | 137 | { |
138 | if (unlikely(current->audit_context)) { | 138 | if (unlikely(current->audit_context)) { |
139 | int success = is_syscall_success(pt_regs); | 139 | int success = is_syscall_success(pt_regs); |
140 | int return_code = regs_return_value(pt_regs); | 140 | long return_code = regs_return_value(pt_regs); |
141 | 141 | ||
142 | __audit_syscall_exit(success, return_code); | 142 | __audit_syscall_exit(success, return_code); |
143 | } | 143 | } |
@@ -202,7 +202,7 @@ static inline kuid_t audit_get_loginuid(struct task_struct *tsk) | |||
202 | return tsk->loginuid; | 202 | return tsk->loginuid; |
203 | } | 203 | } |
204 | 204 | ||
205 | static inline int audit_get_sessionid(struct task_struct *tsk) | 205 | static inline unsigned int audit_get_sessionid(struct task_struct *tsk) |
206 | { | 206 | { |
207 | return tsk->sessionid; | 207 | return tsk->sessionid; |
208 | } | 208 | } |
@@ -220,7 +220,7 @@ extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat); | |||
220 | extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, | 220 | extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, |
221 | const struct cred *new, | 221 | const struct cred *new, |
222 | const struct cred *old); | 222 | const struct cred *old); |
223 | extern void __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old); | 223 | extern void __audit_log_capset(const struct cred *new, const struct cred *old); |
224 | extern void __audit_mmap_fd(int fd, int flags); | 224 | extern void __audit_mmap_fd(int fd, int flags); |
225 | 225 | ||
226 | static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) | 226 | static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) |
@@ -285,11 +285,11 @@ static inline int audit_log_bprm_fcaps(struct linux_binprm *bprm, | |||
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
287 | 287 | ||
288 | static inline void audit_log_capset(pid_t pid, const struct cred *new, | 288 | static inline void audit_log_capset(const struct cred *new, |
289 | const struct cred *old) | 289 | const struct cred *old) |
290 | { | 290 | { |
291 | if (unlikely(!audit_dummy_context())) | 291 | if (unlikely(!audit_dummy_context())) |
292 | __audit_log_capset(pid, new, old); | 292 | __audit_log_capset(new, old); |
293 | } | 293 | } |
294 | 294 | ||
295 | static inline void audit_mmap_fd(int fd, int flags) | 295 | static inline void audit_mmap_fd(int fd, int flags) |
@@ -359,7 +359,7 @@ static inline kuid_t audit_get_loginuid(struct task_struct *tsk) | |||
359 | { | 359 | { |
360 | return INVALID_UID; | 360 | return INVALID_UID; |
361 | } | 361 | } |
362 | static inline int audit_get_sessionid(struct task_struct *tsk) | 362 | static inline unsigned int audit_get_sessionid(struct task_struct *tsk) |
363 | { | 363 | { |
364 | return -1; | 364 | return -1; |
365 | } | 365 | } |
@@ -397,8 +397,8 @@ static inline int audit_log_bprm_fcaps(struct linux_binprm *bprm, | |||
397 | { | 397 | { |
398 | return 0; | 398 | return 0; |
399 | } | 399 | } |
400 | static inline void audit_log_capset(pid_t pid, const struct cred *new, | 400 | static inline void audit_log_capset(const struct cred *new, |
401 | const struct cred *old) | 401 | const struct cred *old) |
402 | { } | 402 | { } |
403 | static inline void audit_mmap_fd(int fd, int flags) | 403 | static inline void audit_mmap_fd(int fd, int flags) |
404 | { } | 404 | { } |
@@ -461,9 +461,11 @@ extern int audit_update_lsm_rules(void); | |||
461 | /* Private API (for audit.c only) */ | 461 | /* Private API (for audit.c only) */ |
462 | extern int audit_filter_user(int type); | 462 | extern int audit_filter_user(int type); |
463 | extern int audit_filter_type(int type); | 463 | extern int audit_filter_type(int type); |
464 | extern int audit_receive_filter(int type, int pid, int seq, | 464 | extern int audit_rule_change(int type, __u32 portid, int seq, |
465 | void *data, size_t datasz); | 465 | void *data, size_t datasz); |
466 | extern int audit_enabled; | 466 | extern int audit_list_rules_send(__u32 portid, int seq); |
467 | |||
468 | extern u32 audit_enabled; | ||
467 | #else /* CONFIG_AUDIT */ | 469 | #else /* CONFIG_AUDIT */ |
468 | static inline __printf(4, 5) | 470 | static inline __printf(4, 5) |
469 | void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, | 471 | void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, |
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 1516a8ff8f92..6df7f9fe0d01 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -97,7 +97,7 @@ extern struct group_info init_groups; | |||
97 | #ifdef CONFIG_AUDITSYSCALL | 97 | #ifdef CONFIG_AUDITSYSCALL |
98 | #define INIT_IDS \ | 98 | #define INIT_IDS \ |
99 | .loginuid = INVALID_UID, \ | 99 | .loginuid = INVALID_UID, \ |
100 | .sessionid = -1, | 100 | .sessionid = (unsigned int)-1, |
101 | #else | 101 | #else |
102 | #define INIT_IDS | 102 | #define INIT_IDS |
103 | #endif | 103 | #endif |
diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 2c95d55f7914..97e6dcaf12bb 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h | |||
@@ -111,7 +111,7 @@ struct cipso_v4_doi; | |||
111 | struct netlbl_audit { | 111 | struct netlbl_audit { |
112 | u32 secid; | 112 | u32 secid; |
113 | kuid_t loginuid; | 113 | kuid_t loginuid; |
114 | u32 sessionid; | 114 | unsigned int sessionid; |
115 | }; | 115 | }; |
116 | 116 | ||
117 | /* | 117 | /* |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 6b82fdf4ba71..1d535f4d3873 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -681,7 +681,7 @@ struct xfrm_spi_skb_cb { | |||
681 | struct xfrm_audit { | 681 | struct xfrm_audit { |
682 | u32 secid; | 682 | u32 secid; |
683 | kuid_t loginuid; | 683 | kuid_t loginuid; |
684 | u32 sessionid; | 684 | unsigned int sessionid; |
685 | }; | 685 | }; |
686 | 686 | ||
687 | #ifdef CONFIG_AUDITSYSCALL | 687 | #ifdef CONFIG_AUDITSYSCALL |
@@ -699,7 +699,7 @@ static inline struct audit_buffer *xfrm_audit_start(const char *op) | |||
699 | return audit_buf; | 699 | return audit_buf; |
700 | } | 700 | } |
701 | 701 | ||
702 | static inline void xfrm_audit_helper_usrinfo(kuid_t auid, u32 ses, u32 secid, | 702 | static inline void xfrm_audit_helper_usrinfo(kuid_t auid, unsigned int ses, u32 secid, |
703 | struct audit_buffer *audit_buf) | 703 | struct audit_buffer *audit_buf) |
704 | { | 704 | { |
705 | char *secctx; | 705 | char *secctx; |
@@ -716,13 +716,13 @@ static inline void xfrm_audit_helper_usrinfo(kuid_t auid, u32 ses, u32 secid, | |||
716 | } | 716 | } |
717 | 717 | ||
718 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, kuid_t auid, | 718 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, kuid_t auid, |
719 | u32 ses, u32 secid); | 719 | unsigned int ses, u32 secid); |
720 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, kuid_t auid, | 720 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, kuid_t auid, |
721 | u32 ses, u32 secid); | 721 | unsigned int ses, u32 secid); |
722 | void xfrm_audit_state_add(struct xfrm_state *x, int result, kuid_t auid, | 722 | void xfrm_audit_state_add(struct xfrm_state *x, int result, kuid_t auid, |
723 | u32 ses, u32 secid); | 723 | unsigned int ses, u32 secid); |
724 | void xfrm_audit_state_delete(struct xfrm_state *x, int result, kuid_t auid, | 724 | void xfrm_audit_state_delete(struct xfrm_state *x, int result, kuid_t auid, |
725 | u32 ses, u32 secid); | 725 | unsigned int ses, u32 secid); |
726 | void xfrm_audit_state_replay_overflow(struct xfrm_state *x, | 726 | void xfrm_audit_state_replay_overflow(struct xfrm_state *x, |
727 | struct sk_buff *skb); | 727 | struct sk_buff *skb); |
728 | void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb, | 728 | void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb, |
@@ -735,22 +735,22 @@ void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb, | |||
735 | #else | 735 | #else |
736 | 736 | ||
737 | static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | 737 | static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, |
738 | kuid_t auid, u32 ses, u32 secid) | 738 | kuid_t auid, unsigned int ses, u32 secid) |
739 | { | 739 | { |
740 | } | 740 | } |
741 | 741 | ||
742 | static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, | 742 | static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, |
743 | kuid_t auid, u32 ses, u32 secid) | 743 | kuid_t auid, unsigned int ses, u32 secid) |
744 | { | 744 | { |
745 | } | 745 | } |
746 | 746 | ||
747 | static inline void xfrm_audit_state_add(struct xfrm_state *x, int result, | 747 | static inline void xfrm_audit_state_add(struct xfrm_state *x, int result, |
748 | kuid_t auid, u32 ses, u32 secid) | 748 | kuid_t auid, unsigned int ses, u32 secid) |
749 | { | 749 | { |
750 | } | 750 | } |
751 | 751 | ||
752 | static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result, | 752 | static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result, |
753 | kuid_t auid, u32 ses, u32 secid) | 753 | kuid_t auid, unsigned int ses, u32 secid) |
754 | { | 754 | { |
755 | } | 755 | } |
756 | 756 | ||
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index 44b05a09f193..2d48fe1274ca 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h | |||
@@ -319,6 +319,12 @@ 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 | ||
323 | |||
324 | #define AUDIT_VERSION_BACKLOG_LIMIT 1 | ||
325 | #define AUDIT_VERSION_BACKLOG_WAIT_TIME 2 | ||
326 | #define AUDIT_VERSION_LATEST AUDIT_VERSION_BACKLOG_WAIT_TIME | ||
327 | |||
322 | /* Failure-to-log actions */ | 328 | /* Failure-to-log actions */ |
323 | #define AUDIT_FAIL_SILENT 0 | 329 | #define AUDIT_FAIL_SILENT 0 |
324 | #define AUDIT_FAIL_PRINTK 1 | 330 | #define AUDIT_FAIL_PRINTK 1 |
@@ -375,6 +381,8 @@ struct audit_status { | |||
375 | __u32 backlog_limit; /* waiting messages limit */ | 381 | __u32 backlog_limit; /* waiting messages limit */ |
376 | __u32 lost; /* messages lost */ | 382 | __u32 lost; /* messages lost */ |
377 | __u32 backlog; /* messages waiting in queue */ | 383 | __u32 backlog; /* messages waiting in queue */ |
384 | __u32 version; /* audit api version number */ | ||
385 | __u32 backlog_wait_time;/* message queue wait timeout */ | ||
378 | }; | 386 | }; |
379 | 387 | ||
380 | struct audit_features { | 388 | struct audit_features { |
diff --git a/kernel/audit.c b/kernel/audit.c index 906ae5a0233a..34c5a2310fbf 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -41,6 +41,8 @@ | |||
41 | * Example user-space utilities: http://people.redhat.com/sgrubb/audit/ | 41 | * Example user-space utilities: http://people.redhat.com/sgrubb/audit/ |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
45 | |||
44 | #include <linux/init.h> | 46 | #include <linux/init.h> |
45 | #include <asm/types.h> | 47 | #include <asm/types.h> |
46 | #include <linux/atomic.h> | 48 | #include <linux/atomic.h> |
@@ -63,6 +65,7 @@ | |||
63 | #include <linux/freezer.h> | 65 | #include <linux/freezer.h> |
64 | #include <linux/tty.h> | 66 | #include <linux/tty.h> |
65 | #include <linux/pid_namespace.h> | 67 | #include <linux/pid_namespace.h> |
68 | #include <net/netns/generic.h> | ||
66 | 69 | ||
67 | #include "audit.h" | 70 | #include "audit.h" |
68 | 71 | ||
@@ -76,16 +79,16 @@ static int audit_initialized; | |||
76 | #define AUDIT_OFF 0 | 79 | #define AUDIT_OFF 0 |
77 | #define AUDIT_ON 1 | 80 | #define AUDIT_ON 1 |
78 | #define AUDIT_LOCKED 2 | 81 | #define AUDIT_LOCKED 2 |
79 | int audit_enabled; | 82 | u32 audit_enabled; |
80 | int audit_ever_enabled; | 83 | u32 audit_ever_enabled; |
81 | 84 | ||
82 | EXPORT_SYMBOL_GPL(audit_enabled); | 85 | EXPORT_SYMBOL_GPL(audit_enabled); |
83 | 86 | ||
84 | /* Default state when kernel boots without any parameters. */ | 87 | /* Default state when kernel boots without any parameters. */ |
85 | static int audit_default; | 88 | static u32 audit_default; |
86 | 89 | ||
87 | /* If auditing cannot proceed, audit_failure selects what happens. */ | 90 | /* If auditing cannot proceed, audit_failure selects what happens. */ |
88 | static int audit_failure = AUDIT_FAIL_PRINTK; | 91 | static u32 audit_failure = AUDIT_FAIL_PRINTK; |
89 | 92 | ||
90 | /* | 93 | /* |
91 | * If audit records are to be written to the netlink socket, audit_pid | 94 | * If audit records are to be written to the netlink socket, audit_pid |
@@ -93,17 +96,19 @@ static int audit_failure = AUDIT_FAIL_PRINTK; | |||
93 | * the portid to use to send netlink messages to that process. | 96 | * the portid to use to send netlink messages to that process. |
94 | */ | 97 | */ |
95 | int audit_pid; | 98 | int audit_pid; |
96 | static int audit_nlk_portid; | 99 | static __u32 audit_nlk_portid; |
97 | 100 | ||
98 | /* If audit_rate_limit is non-zero, limit the rate of sending audit records | 101 | /* If audit_rate_limit is non-zero, limit the rate of sending audit records |
99 | * to that number per second. This prevents DoS attacks, but results in | 102 | * to that number per second. This prevents DoS attacks, but results in |
100 | * audit records being dropped. */ | 103 | * audit records being dropped. */ |
101 | static int audit_rate_limit; | 104 | static u32 audit_rate_limit; |
102 | 105 | ||
103 | /* Number of outstanding audit_buffers allowed. */ | 106 | /* Number of outstanding audit_buffers allowed. |
104 | static int audit_backlog_limit = 64; | 107 | * When set to zero, this means unlimited. */ |
105 | static int audit_backlog_wait_time = 60 * HZ; | 108 | static u32 audit_backlog_limit = 64; |
106 | static int audit_backlog_wait_overflow = 0; | 109 | #define AUDIT_BACKLOG_WAIT_TIME (60 * HZ) |
110 | static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; | ||
111 | static u32 audit_backlog_wait_overflow = 0; | ||
107 | 112 | ||
108 | /* The identity of the user shutting down the audit system. */ | 113 | /* The identity of the user shutting down the audit system. */ |
109 | kuid_t audit_sig_uid = INVALID_UID; | 114 | kuid_t audit_sig_uid = INVALID_UID; |
@@ -121,6 +126,7 @@ static atomic_t audit_lost = ATOMIC_INIT(0); | |||
121 | 126 | ||
122 | /* The netlink socket. */ | 127 | /* The netlink socket. */ |
123 | static struct sock *audit_sock; | 128 | static struct sock *audit_sock; |
129 | int audit_net_id; | ||
124 | 130 | ||
125 | /* Hash for inode-based rules */ | 131 | /* Hash for inode-based rules */ |
126 | struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; | 132 | struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; |
@@ -175,27 +181,27 @@ struct audit_buffer { | |||
175 | }; | 181 | }; |
176 | 182 | ||
177 | struct audit_reply { | 183 | struct audit_reply { |
178 | int pid; | 184 | __u32 portid; |
185 | pid_t pid; | ||
179 | struct sk_buff *skb; | 186 | struct sk_buff *skb; |
180 | }; | 187 | }; |
181 | 188 | ||
182 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) | 189 | static void audit_set_portid(struct audit_buffer *ab, __u32 portid) |
183 | { | 190 | { |
184 | if (ab) { | 191 | if (ab) { |
185 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); | 192 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); |
186 | nlh->nlmsg_pid = pid; | 193 | nlh->nlmsg_pid = portid; |
187 | } | 194 | } |
188 | } | 195 | } |
189 | 196 | ||
190 | void audit_panic(const char *message) | 197 | void audit_panic(const char *message) |
191 | { | 198 | { |
192 | switch (audit_failure) | 199 | switch (audit_failure) { |
193 | { | ||
194 | case AUDIT_FAIL_SILENT: | 200 | case AUDIT_FAIL_SILENT: |
195 | break; | 201 | break; |
196 | case AUDIT_FAIL_PRINTK: | 202 | case AUDIT_FAIL_PRINTK: |
197 | if (printk_ratelimit()) | 203 | if (printk_ratelimit()) |
198 | printk(KERN_ERR "audit: %s\n", message); | 204 | pr_err("%s\n", message); |
199 | break; | 205 | break; |
200 | case AUDIT_FAIL_PANIC: | 206 | case AUDIT_FAIL_PANIC: |
201 | /* test audit_pid since printk is always losey, why bother? */ | 207 | /* test audit_pid since printk is always losey, why bother? */ |
@@ -266,9 +272,7 @@ void audit_log_lost(const char *message) | |||
266 | 272 | ||
267 | if (print) { | 273 | if (print) { |
268 | if (printk_ratelimit()) | 274 | if (printk_ratelimit()) |
269 | printk(KERN_WARNING | 275 | pr_warn("audit_lost=%u audit_rate_limit=%u audit_backlog_limit=%u\n", |
270 | "audit: audit_lost=%d audit_rate_limit=%d " | ||
271 | "audit_backlog_limit=%d\n", | ||
272 | atomic_read(&audit_lost), | 276 | atomic_read(&audit_lost), |
273 | audit_rate_limit, | 277 | audit_rate_limit, |
274 | audit_backlog_limit); | 278 | audit_backlog_limit); |
@@ -276,7 +280,7 @@ void audit_log_lost(const char *message) | |||
276 | } | 280 | } |
277 | } | 281 | } |
278 | 282 | ||
279 | static int audit_log_config_change(char *function_name, int new, int old, | 283 | static int audit_log_config_change(char *function_name, u32 new, u32 old, |
280 | int allow_changes) | 284 | int allow_changes) |
281 | { | 285 | { |
282 | struct audit_buffer *ab; | 286 | struct audit_buffer *ab; |
@@ -285,7 +289,7 @@ static int audit_log_config_change(char *function_name, int new, int old, | |||
285 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 289 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
286 | if (unlikely(!ab)) | 290 | if (unlikely(!ab)) |
287 | return rc; | 291 | return rc; |
288 | audit_log_format(ab, "%s=%d old=%d", function_name, new, old); | 292 | audit_log_format(ab, "%s=%u old=%u", function_name, new, old); |
289 | audit_log_session_info(ab); | 293 | audit_log_session_info(ab); |
290 | rc = audit_log_task_context(ab); | 294 | rc = audit_log_task_context(ab); |
291 | if (rc) | 295 | if (rc) |
@@ -295,9 +299,10 @@ static int audit_log_config_change(char *function_name, int new, int old, | |||
295 | return rc; | 299 | return rc; |
296 | } | 300 | } |
297 | 301 | ||
298 | static int audit_do_config_change(char *function_name, int *to_change, int new) | 302 | static int audit_do_config_change(char *function_name, u32 *to_change, u32 new) |
299 | { | 303 | { |
300 | int allow_changes, rc = 0, old = *to_change; | 304 | int allow_changes, rc = 0; |
305 | u32 old = *to_change; | ||
301 | 306 | ||
302 | /* check if we are locked */ | 307 | /* check if we are locked */ |
303 | if (audit_enabled == AUDIT_LOCKED) | 308 | if (audit_enabled == AUDIT_LOCKED) |
@@ -320,17 +325,23 @@ static int audit_do_config_change(char *function_name, int *to_change, int new) | |||
320 | return rc; | 325 | return rc; |
321 | } | 326 | } |
322 | 327 | ||
323 | static int audit_set_rate_limit(int limit) | 328 | static int audit_set_rate_limit(u32 limit) |
324 | { | 329 | { |
325 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, limit); | 330 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, limit); |
326 | } | 331 | } |
327 | 332 | ||
328 | static int audit_set_backlog_limit(int limit) | 333 | static int audit_set_backlog_limit(u32 limit) |
329 | { | 334 | { |
330 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, limit); | 335 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, limit); |
331 | } | 336 | } |
332 | 337 | ||
333 | static int audit_set_enabled(int state) | 338 | static int audit_set_backlog_wait_time(u32 timeout) |
339 | { | ||
340 | return audit_do_config_change("audit_backlog_wait_time", | ||
341 | &audit_backlog_wait_time, timeout); | ||
342 | } | ||
343 | |||
344 | static int audit_set_enabled(u32 state) | ||
334 | { | 345 | { |
335 | int rc; | 346 | int rc; |
336 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) | 347 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) |
@@ -343,7 +354,7 @@ static int audit_set_enabled(int state) | |||
343 | return rc; | 354 | return rc; |
344 | } | 355 | } |
345 | 356 | ||
346 | static int audit_set_failure(int state) | 357 | static int audit_set_failure(u32 state) |
347 | { | 358 | { |
348 | if (state != AUDIT_FAIL_SILENT | 359 | if (state != AUDIT_FAIL_SILENT |
349 | && state != AUDIT_FAIL_PRINTK | 360 | && state != AUDIT_FAIL_PRINTK |
@@ -365,7 +376,8 @@ static int audit_set_failure(int state) | |||
365 | static void audit_hold_skb(struct sk_buff *skb) | 376 | static void audit_hold_skb(struct sk_buff *skb) |
366 | { | 377 | { |
367 | if (audit_default && | 378 | if (audit_default && |
368 | skb_queue_len(&audit_skb_hold_queue) < audit_backlog_limit) | 379 | (!audit_backlog_limit || |
380 | skb_queue_len(&audit_skb_hold_queue) < audit_backlog_limit)) | ||
369 | skb_queue_tail(&audit_skb_hold_queue, skb); | 381 | skb_queue_tail(&audit_skb_hold_queue, skb); |
370 | else | 382 | else |
371 | kfree_skb(skb); | 383 | kfree_skb(skb); |
@@ -382,7 +394,7 @@ static void audit_printk_skb(struct sk_buff *skb) | |||
382 | 394 | ||
383 | if (nlh->nlmsg_type != AUDIT_EOE) { | 395 | if (nlh->nlmsg_type != AUDIT_EOE) { |
384 | if (printk_ratelimit()) | 396 | if (printk_ratelimit()) |
385 | printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, data); | 397 | pr_notice("type=%d %s\n", nlh->nlmsg_type, data); |
386 | else | 398 | else |
387 | audit_log_lost("printk limit exceeded\n"); | 399 | audit_log_lost("printk limit exceeded\n"); |
388 | } | 400 | } |
@@ -398,9 +410,12 @@ static void kauditd_send_skb(struct sk_buff *skb) | |||
398 | err = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0); | 410 | err = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0); |
399 | if (err < 0) { | 411 | if (err < 0) { |
400 | BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */ | 412 | BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */ |
401 | printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid); | 413 | if (audit_pid) { |
402 | audit_log_lost("auditd disappeared\n"); | 414 | pr_err("*NO* daemon at audit_pid=%d\n", audit_pid); |
403 | audit_pid = 0; | 415 | audit_log_lost("auditd disappeared\n"); |
416 | audit_pid = 0; | ||
417 | audit_sock = NULL; | ||
418 | } | ||
404 | /* we might get lucky and get this in the next auditd */ | 419 | /* we might get lucky and get this in the next auditd */ |
405 | audit_hold_skb(skb); | 420 | audit_hold_skb(skb); |
406 | } else | 421 | } else |
@@ -457,8 +472,10 @@ static int kauditd_thread(void *dummy) | |||
457 | flush_hold_queue(); | 472 | flush_hold_queue(); |
458 | 473 | ||
459 | skb = skb_dequeue(&audit_skb_queue); | 474 | skb = skb_dequeue(&audit_skb_queue); |
460 | wake_up(&audit_backlog_wait); | 475 | |
461 | if (skb) { | 476 | if (skb) { |
477 | if (skb_queue_len(&audit_skb_queue) <= audit_backlog_limit) | ||
478 | wake_up(&audit_backlog_wait); | ||
462 | if (audit_pid) | 479 | if (audit_pid) |
463 | kauditd_send_skb(skb); | 480 | kauditd_send_skb(skb); |
464 | else | 481 | else |
@@ -482,22 +499,23 @@ static int kauditd_thread(void *dummy) | |||
482 | int audit_send_list(void *_dest) | 499 | int audit_send_list(void *_dest) |
483 | { | 500 | { |
484 | struct audit_netlink_list *dest = _dest; | 501 | struct audit_netlink_list *dest = _dest; |
485 | int pid = dest->pid; | ||
486 | struct sk_buff *skb; | 502 | struct sk_buff *skb; |
503 | struct net *net = get_net_ns_by_pid(dest->pid); | ||
504 | struct audit_net *aunet = net_generic(net, audit_net_id); | ||
487 | 505 | ||
488 | /* wait for parent to finish and send an ACK */ | 506 | /* wait for parent to finish and send an ACK */ |
489 | mutex_lock(&audit_cmd_mutex); | 507 | mutex_lock(&audit_cmd_mutex); |
490 | mutex_unlock(&audit_cmd_mutex); | 508 | mutex_unlock(&audit_cmd_mutex); |
491 | 509 | ||
492 | while ((skb = __skb_dequeue(&dest->q)) != NULL) | 510 | while ((skb = __skb_dequeue(&dest->q)) != NULL) |
493 | netlink_unicast(audit_sock, skb, pid, 0); | 511 | netlink_unicast(aunet->nlsk, skb, dest->portid, 0); |
494 | 512 | ||
495 | kfree(dest); | 513 | kfree(dest); |
496 | 514 | ||
497 | return 0; | 515 | return 0; |
498 | } | 516 | } |
499 | 517 | ||
500 | struct sk_buff *audit_make_reply(int pid, int seq, int type, int done, | 518 | struct sk_buff *audit_make_reply(__u32 portid, int seq, int type, int done, |
501 | int multi, const void *payload, int size) | 519 | int multi, const void *payload, int size) |
502 | { | 520 | { |
503 | struct sk_buff *skb; | 521 | struct sk_buff *skb; |
@@ -510,7 +528,7 @@ struct sk_buff *audit_make_reply(int pid, int seq, int type, int done, | |||
510 | if (!skb) | 528 | if (!skb) |
511 | return NULL; | 529 | return NULL; |
512 | 530 | ||
513 | nlh = nlmsg_put(skb, pid, seq, t, size, flags); | 531 | nlh = nlmsg_put(skb, portid, seq, t, size, flags); |
514 | if (!nlh) | 532 | if (!nlh) |
515 | goto out_kfree_skb; | 533 | goto out_kfree_skb; |
516 | data = nlmsg_data(nlh); | 534 | data = nlmsg_data(nlh); |
@@ -525,19 +543,21 @@ out_kfree_skb: | |||
525 | static int audit_send_reply_thread(void *arg) | 543 | static int audit_send_reply_thread(void *arg) |
526 | { | 544 | { |
527 | struct audit_reply *reply = (struct audit_reply *)arg; | 545 | struct audit_reply *reply = (struct audit_reply *)arg; |
546 | struct net *net = get_net_ns_by_pid(reply->pid); | ||
547 | struct audit_net *aunet = net_generic(net, audit_net_id); | ||
528 | 548 | ||
529 | mutex_lock(&audit_cmd_mutex); | 549 | mutex_lock(&audit_cmd_mutex); |
530 | mutex_unlock(&audit_cmd_mutex); | 550 | mutex_unlock(&audit_cmd_mutex); |
531 | 551 | ||
532 | /* Ignore failure. It'll only happen if the sender goes away, | 552 | /* Ignore failure. It'll only happen if the sender goes away, |
533 | because our timeout is set to infinite. */ | 553 | because our timeout is set to infinite. */ |
534 | netlink_unicast(audit_sock, reply->skb, reply->pid, 0); | 554 | netlink_unicast(aunet->nlsk , reply->skb, reply->portid, 0); |
535 | kfree(reply); | 555 | kfree(reply); |
536 | return 0; | 556 | return 0; |
537 | } | 557 | } |
538 | /** | 558 | /** |
539 | * audit_send_reply - send an audit reply message via netlink | 559 | * audit_send_reply - send an audit reply message via netlink |
540 | * @pid: process id to send reply to | 560 | * @portid: netlink port to which to send reply |
541 | * @seq: sequence number | 561 | * @seq: sequence number |
542 | * @type: audit message type | 562 | * @type: audit message type |
543 | * @done: done (last) flag | 563 | * @done: done (last) flag |
@@ -545,11 +565,11 @@ static int audit_send_reply_thread(void *arg) | |||
545 | * @payload: payload data | 565 | * @payload: payload data |
546 | * @size: payload size | 566 | * @size: payload size |
547 | * | 567 | * |
548 | * Allocates an skb, builds the netlink message, and sends it to the pid. | 568 | * Allocates an skb, builds the netlink message, and sends it to the port id. |
549 | * No failure notifications. | 569 | * No failure notifications. |
550 | */ | 570 | */ |
551 | static void audit_send_reply(int pid, int seq, int type, int done, int multi, | 571 | static void audit_send_reply(__u32 portid, int seq, int type, int done, |
552 | const void *payload, int size) | 572 | int multi, const void *payload, int size) |
553 | { | 573 | { |
554 | struct sk_buff *skb; | 574 | struct sk_buff *skb; |
555 | struct task_struct *tsk; | 575 | struct task_struct *tsk; |
@@ -559,11 +579,12 @@ static void audit_send_reply(int pid, int seq, int type, int done, int multi, | |||
559 | if (!reply) | 579 | if (!reply) |
560 | return; | 580 | return; |
561 | 581 | ||
562 | skb = audit_make_reply(pid, seq, type, done, multi, payload, size); | 582 | skb = audit_make_reply(portid, seq, type, done, multi, payload, size); |
563 | if (!skb) | 583 | if (!skb) |
564 | goto out; | 584 | goto out; |
565 | 585 | ||
566 | reply->pid = pid; | 586 | reply->portid = portid; |
587 | reply->pid = task_pid_vnr(current); | ||
567 | reply->skb = skb; | 588 | reply->skb = skb; |
568 | 589 | ||
569 | tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply"); | 590 | tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply"); |
@@ -663,8 +684,12 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature | |||
663 | { | 684 | { |
664 | struct audit_buffer *ab; | 685 | struct audit_buffer *ab; |
665 | 686 | ||
687 | if (audit_enabled == AUDIT_OFF) | ||
688 | return; | ||
689 | |||
666 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE); | 690 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE); |
667 | audit_log_format(ab, "feature=%s new=%d old=%d old_lock=%d new_lock=%d res=%d", | 691 | audit_log_task_info(ab, current); |
692 | audit_log_format(ab, "feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", | ||
668 | audit_feature_names[which], !!old_feature, !!new_feature, | 693 | audit_feature_names[which], !!old_feature, !!new_feature, |
669 | !!old_lock, !!new_lock, res); | 694 | !!old_lock, !!new_lock, res); |
670 | audit_log_end(ab); | 695 | audit_log_end(ab); |
@@ -694,7 +719,7 @@ static int audit_set_feature(struct sk_buff *skb) | |||
694 | old_lock = af.lock & feature; | 719 | old_lock = af.lock & feature; |
695 | 720 | ||
696 | /* are we changing a locked feature? */ | 721 | /* are we changing a locked feature? */ |
697 | if ((af.lock & feature) && (new_feature != old_feature)) { | 722 | if (old_lock && (new_feature != old_feature)) { |
698 | audit_log_feature_change(i, old_feature, new_feature, | 723 | audit_log_feature_change(i, old_feature, new_feature, |
699 | old_lock, new_lock, 0); | 724 | old_lock, new_lock, 0); |
700 | return -EPERM; | 725 | return -EPERM; |
@@ -732,7 +757,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
732 | { | 757 | { |
733 | u32 seq; | 758 | u32 seq; |
734 | void *data; | 759 | void *data; |
735 | struct audit_status *status_get, status_set; | ||
736 | int err; | 760 | int err; |
737 | struct audit_buffer *ab; | 761 | struct audit_buffer *ab; |
738 | u16 msg_type = nlh->nlmsg_type; | 762 | u16 msg_type = nlh->nlmsg_type; |
@@ -758,48 +782,70 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
758 | data = nlmsg_data(nlh); | 782 | data = nlmsg_data(nlh); |
759 | 783 | ||
760 | switch (msg_type) { | 784 | switch (msg_type) { |
761 | case AUDIT_GET: | 785 | case AUDIT_GET: { |
762 | memset(&status_set, 0, sizeof(status_set)); | 786 | struct audit_status s; |
763 | status_set.enabled = audit_enabled; | 787 | memset(&s, 0, sizeof(s)); |
764 | status_set.failure = audit_failure; | 788 | s.enabled = audit_enabled; |
765 | status_set.pid = audit_pid; | 789 | s.failure = audit_failure; |
766 | status_set.rate_limit = audit_rate_limit; | 790 | s.pid = audit_pid; |
767 | status_set.backlog_limit = audit_backlog_limit; | 791 | s.rate_limit = audit_rate_limit; |
768 | status_set.lost = atomic_read(&audit_lost); | 792 | s.backlog_limit = audit_backlog_limit; |
769 | status_set.backlog = skb_queue_len(&audit_skb_queue); | 793 | s.lost = atomic_read(&audit_lost); |
794 | s.backlog = skb_queue_len(&audit_skb_queue); | ||
795 | s.version = AUDIT_VERSION_LATEST; | ||
796 | s.backlog_wait_time = audit_backlog_wait_time; | ||
770 | audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, | 797 | audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, |
771 | &status_set, sizeof(status_set)); | 798 | &s, sizeof(s)); |
772 | break; | 799 | break; |
773 | case AUDIT_SET: | 800 | } |
774 | if (nlmsg_len(nlh) < sizeof(struct audit_status)) | 801 | case AUDIT_SET: { |
775 | return -EINVAL; | 802 | struct audit_status s; |
776 | status_get = (struct audit_status *)data; | 803 | memset(&s, 0, sizeof(s)); |
777 | if (status_get->mask & AUDIT_STATUS_ENABLED) { | 804 | /* guard against past and future API changes */ |
778 | err = audit_set_enabled(status_get->enabled); | 805 | memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); |
806 | if (s.mask & AUDIT_STATUS_ENABLED) { | ||
807 | err = audit_set_enabled(s.enabled); | ||
779 | if (err < 0) | 808 | if (err < 0) |
780 | return err; | 809 | return err; |
781 | } | 810 | } |
782 | if (status_get->mask & AUDIT_STATUS_FAILURE) { | 811 | if (s.mask & AUDIT_STATUS_FAILURE) { |
783 | err = audit_set_failure(status_get->failure); | 812 | err = audit_set_failure(s.failure); |
784 | if (err < 0) | 813 | if (err < 0) |
785 | return err; | 814 | return err; |
786 | } | 815 | } |
787 | if (status_get->mask & AUDIT_STATUS_PID) { | 816 | if (s.mask & AUDIT_STATUS_PID) { |
788 | int new_pid = status_get->pid; | 817 | int new_pid = s.pid; |
789 | 818 | ||
819 | if ((!new_pid) && (task_tgid_vnr(current) != audit_pid)) | ||
820 | return -EACCES; | ||
790 | if (audit_enabled != AUDIT_OFF) | 821 | if (audit_enabled != AUDIT_OFF) |
791 | audit_log_config_change("audit_pid", new_pid, audit_pid, 1); | 822 | audit_log_config_change("audit_pid", new_pid, audit_pid, 1); |
792 | audit_pid = new_pid; | 823 | audit_pid = new_pid; |
793 | audit_nlk_portid = NETLINK_CB(skb).portid; | 824 | audit_nlk_portid = NETLINK_CB(skb).portid; |
825 | audit_sock = skb->sk; | ||
794 | } | 826 | } |
795 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) { | 827 | if (s.mask & AUDIT_STATUS_RATE_LIMIT) { |
796 | err = audit_set_rate_limit(status_get->rate_limit); | 828 | err = audit_set_rate_limit(s.rate_limit); |
829 | if (err < 0) | ||
830 | return err; | ||
831 | } | ||
832 | if (s.mask & AUDIT_STATUS_BACKLOG_LIMIT) { | ||
833 | err = audit_set_backlog_limit(s.backlog_limit); | ||
834 | if (err < 0) | ||
835 | return err; | ||
836 | } | ||
837 | if (s.mask & AUDIT_STATUS_BACKLOG_WAIT_TIME) { | ||
838 | if (sizeof(s) > (size_t)nlh->nlmsg_len) | ||
839 | return -EINVAL; | ||
840 | if (s.backlog_wait_time < 0 || | ||
841 | s.backlog_wait_time > 10*AUDIT_BACKLOG_WAIT_TIME) | ||
842 | return -EINVAL; | ||
843 | err = audit_set_backlog_wait_time(s.backlog_wait_time); | ||
797 | if (err < 0) | 844 | if (err < 0) |
798 | return err; | 845 | return err; |
799 | } | 846 | } |
800 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) | ||
801 | err = audit_set_backlog_limit(status_get->backlog_limit); | ||
802 | break; | 847 | break; |
848 | } | ||
803 | case AUDIT_GET_FEATURE: | 849 | case AUDIT_GET_FEATURE: |
804 | err = audit_get_feature(skb); | 850 | err = audit_get_feature(skb); |
805 | if (err) | 851 | if (err) |
@@ -817,13 +863,14 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
817 | return 0; | 863 | return 0; |
818 | 864 | ||
819 | err = audit_filter_user(msg_type); | 865 | err = audit_filter_user(msg_type); |
820 | if (err == 1) { | 866 | if (err == 1) { /* match or error */ |
821 | err = 0; | 867 | err = 0; |
822 | if (msg_type == AUDIT_USER_TTY) { | 868 | if (msg_type == AUDIT_USER_TTY) { |
823 | err = tty_audit_push_current(); | 869 | err = tty_audit_push_current(); |
824 | if (err) | 870 | if (err) |
825 | break; | 871 | break; |
826 | } | 872 | } |
873 | mutex_unlock(&audit_cmd_mutex); | ||
827 | audit_log_common_recv_msg(&ab, msg_type); | 874 | audit_log_common_recv_msg(&ab, msg_type); |
828 | if (msg_type != AUDIT_USER_TTY) | 875 | if (msg_type != AUDIT_USER_TTY) |
829 | audit_log_format(ab, " msg='%.*s'", | 876 | audit_log_format(ab, " msg='%.*s'", |
@@ -839,8 +886,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
839 | size--; | 886 | size--; |
840 | audit_log_n_untrustedstring(ab, data, size); | 887 | audit_log_n_untrustedstring(ab, data, size); |
841 | } | 888 | } |
842 | audit_set_pid(ab, NETLINK_CB(skb).portid); | 889 | audit_set_portid(ab, NETLINK_CB(skb).portid); |
843 | audit_log_end(ab); | 890 | audit_log_end(ab); |
891 | mutex_lock(&audit_cmd_mutex); | ||
844 | } | 892 | } |
845 | break; | 893 | break; |
846 | case AUDIT_ADD_RULE: | 894 | case AUDIT_ADD_RULE: |
@@ -853,11 +901,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
853 | audit_log_end(ab); | 901 | audit_log_end(ab); |
854 | return -EPERM; | 902 | return -EPERM; |
855 | } | 903 | } |
856 | /* fallthrough */ | 904 | err = audit_rule_change(msg_type, NETLINK_CB(skb).portid, |
857 | case AUDIT_LIST_RULES: | ||
858 | err = audit_receive_filter(msg_type, NETLINK_CB(skb).portid, | ||
859 | seq, data, nlmsg_len(nlh)); | 905 | seq, data, nlmsg_len(nlh)); |
860 | break; | 906 | break; |
907 | case AUDIT_LIST_RULES: | ||
908 | err = audit_list_rules_send(NETLINK_CB(skb).portid, seq); | ||
909 | break; | ||
861 | case AUDIT_TRIM: | 910 | case AUDIT_TRIM: |
862 | audit_trim_trees(); | 911 | audit_trim_trees(); |
863 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); | 912 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); |
@@ -939,20 +988,33 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
939 | break; | 988 | break; |
940 | } | 989 | } |
941 | case AUDIT_TTY_SET: { | 990 | case AUDIT_TTY_SET: { |
942 | struct audit_tty_status s; | 991 | struct audit_tty_status s, old; |
943 | struct task_struct *tsk = current; | 992 | struct task_struct *tsk = current; |
993 | struct audit_buffer *ab; | ||
944 | 994 | ||
945 | memset(&s, 0, sizeof(s)); | 995 | memset(&s, 0, sizeof(s)); |
946 | /* guard against past and future API changes */ | 996 | /* guard against past and future API changes */ |
947 | memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); | 997 | memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); |
998 | /* check if new data is valid */ | ||
948 | if ((s.enabled != 0 && s.enabled != 1) || | 999 | if ((s.enabled != 0 && s.enabled != 1) || |
949 | (s.log_passwd != 0 && s.log_passwd != 1)) | 1000 | (s.log_passwd != 0 && s.log_passwd != 1)) |
950 | return -EINVAL; | 1001 | err = -EINVAL; |
951 | 1002 | ||
952 | spin_lock(&tsk->sighand->siglock); | 1003 | spin_lock(&tsk->sighand->siglock); |
953 | tsk->signal->audit_tty = s.enabled; | 1004 | old.enabled = tsk->signal->audit_tty; |
954 | tsk->signal->audit_tty_log_passwd = s.log_passwd; | 1005 | old.log_passwd = tsk->signal->audit_tty_log_passwd; |
1006 | if (!err) { | ||
1007 | tsk->signal->audit_tty = s.enabled; | ||
1008 | tsk->signal->audit_tty_log_passwd = s.log_passwd; | ||
1009 | } | ||
955 | spin_unlock(&tsk->sighand->siglock); | 1010 | spin_unlock(&tsk->sighand->siglock); |
1011 | |||
1012 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); | ||
1013 | audit_log_format(ab, " op=tty_set old-enabled=%d new-enabled=%d" | ||
1014 | " old-log_passwd=%d new-log_passwd=%d res=%d", | ||
1015 | old.enabled, s.enabled, old.log_passwd, | ||
1016 | s.log_passwd, !err); | ||
1017 | audit_log_end(ab); | ||
956 | break; | 1018 | break; |
957 | } | 1019 | } |
958 | default: | 1020 | default: |
@@ -998,24 +1060,55 @@ static void audit_receive(struct sk_buff *skb) | |||
998 | mutex_unlock(&audit_cmd_mutex); | 1060 | mutex_unlock(&audit_cmd_mutex); |
999 | } | 1061 | } |
1000 | 1062 | ||
1001 | /* Initialize audit support at boot time. */ | 1063 | static int __net_init audit_net_init(struct net *net) |
1002 | static int __init audit_init(void) | ||
1003 | { | 1064 | { |
1004 | int i; | ||
1005 | struct netlink_kernel_cfg cfg = { | 1065 | struct netlink_kernel_cfg cfg = { |
1006 | .input = audit_receive, | 1066 | .input = audit_receive, |
1007 | }; | 1067 | }; |
1008 | 1068 | ||
1069 | struct audit_net *aunet = net_generic(net, audit_net_id); | ||
1070 | |||
1071 | aunet->nlsk = netlink_kernel_create(net, NETLINK_AUDIT, &cfg); | ||
1072 | if (aunet->nlsk == NULL) { | ||
1073 | audit_panic("cannot initialize netlink socket in namespace"); | ||
1074 | return -ENOMEM; | ||
1075 | } | ||
1076 | aunet->nlsk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; | ||
1077 | return 0; | ||
1078 | } | ||
1079 | |||
1080 | static void __net_exit audit_net_exit(struct net *net) | ||
1081 | { | ||
1082 | struct audit_net *aunet = net_generic(net, audit_net_id); | ||
1083 | struct sock *sock = aunet->nlsk; | ||
1084 | if (sock == audit_sock) { | ||
1085 | audit_pid = 0; | ||
1086 | audit_sock = NULL; | ||
1087 | } | ||
1088 | |||
1089 | rcu_assign_pointer(aunet->nlsk, NULL); | ||
1090 | synchronize_net(); | ||
1091 | netlink_kernel_release(sock); | ||
1092 | } | ||
1093 | |||
1094 | static struct pernet_operations audit_net_ops __net_initdata = { | ||
1095 | .init = audit_net_init, | ||
1096 | .exit = audit_net_exit, | ||
1097 | .id = &audit_net_id, | ||
1098 | .size = sizeof(struct audit_net), | ||
1099 | }; | ||
1100 | |||
1101 | /* Initialize audit support at boot time. */ | ||
1102 | static int __init audit_init(void) | ||
1103 | { | ||
1104 | int i; | ||
1105 | |||
1009 | if (audit_initialized == AUDIT_DISABLED) | 1106 | if (audit_initialized == AUDIT_DISABLED) |
1010 | return 0; | 1107 | return 0; |
1011 | 1108 | ||
1012 | printk(KERN_INFO "audit: initializing netlink socket (%s)\n", | 1109 | pr_info("initializing netlink subsys (%s)\n", |
1013 | audit_default ? "enabled" : "disabled"); | 1110 | audit_default ? "enabled" : "disabled"); |
1014 | audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, &cfg); | 1111 | register_pernet_subsys(&audit_net_ops); |
1015 | if (!audit_sock) | ||
1016 | audit_panic("cannot initialize netlink socket"); | ||
1017 | else | ||
1018 | audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; | ||
1019 | 1112 | ||
1020 | skb_queue_head_init(&audit_skb_queue); | 1113 | skb_queue_head_init(&audit_skb_queue); |
1021 | skb_queue_head_init(&audit_skb_hold_queue); | 1114 | skb_queue_head_init(&audit_skb_hold_queue); |
@@ -1039,22 +1132,32 @@ static int __init audit_enable(char *str) | |||
1039 | if (!audit_default) | 1132 | if (!audit_default) |
1040 | audit_initialized = AUDIT_DISABLED; | 1133 | audit_initialized = AUDIT_DISABLED; |
1041 | 1134 | ||
1042 | printk(KERN_INFO "audit: %s", audit_default ? "enabled" : "disabled"); | 1135 | pr_info("%s\n", audit_default ? |
1136 | "enabled (after initialization)" : "disabled (until reboot)"); | ||
1043 | 1137 | ||
1044 | if (audit_initialized == AUDIT_INITIALIZED) { | 1138 | return 1; |
1045 | audit_enabled = audit_default; | 1139 | } |
1046 | audit_ever_enabled |= !!audit_default; | 1140 | __setup("audit=", audit_enable); |
1047 | } else if (audit_initialized == AUDIT_UNINITIALIZED) { | 1141 | |
1048 | printk(" (after initialization)"); | 1142 | /* Process kernel command-line parameter at boot time. |
1049 | } else { | 1143 | * audit_backlog_limit=<n> */ |
1050 | printk(" (until reboot)"); | 1144 | static int __init audit_backlog_limit_set(char *str) |
1145 | { | ||
1146 | u32 audit_backlog_limit_arg; | ||
1147 | |||
1148 | pr_info("audit_backlog_limit: "); | ||
1149 | if (kstrtouint(str, 0, &audit_backlog_limit_arg)) { | ||
1150 | pr_cont("using default of %u, unable to parse %s\n", | ||
1151 | audit_backlog_limit, str); | ||
1152 | return 1; | ||
1051 | } | 1153 | } |
1052 | printk("\n"); | 1154 | |
1155 | audit_backlog_limit = audit_backlog_limit_arg; | ||
1156 | pr_cont("%d\n", audit_backlog_limit); | ||
1053 | 1157 | ||
1054 | return 1; | 1158 | return 1; |
1055 | } | 1159 | } |
1056 | 1160 | __setup("audit_backlog_limit=", audit_backlog_limit_set); | |
1057 | __setup("audit=", audit_enable); | ||
1058 | 1161 | ||
1059 | static void audit_buffer_free(struct audit_buffer *ab) | 1162 | static void audit_buffer_free(struct audit_buffer *ab) |
1060 | { | 1163 | { |
@@ -1165,18 +1268,20 @@ static inline void audit_get_stamp(struct audit_context *ctx, | |||
1165 | /* | 1268 | /* |
1166 | * Wait for auditd to drain the queue a little | 1269 | * Wait for auditd to drain the queue a little |
1167 | */ | 1270 | */ |
1168 | static void wait_for_auditd(unsigned long sleep_time) | 1271 | static long wait_for_auditd(long sleep_time) |
1169 | { | 1272 | { |
1170 | DECLARE_WAITQUEUE(wait, current); | 1273 | DECLARE_WAITQUEUE(wait, current); |
1171 | set_current_state(TASK_UNINTERRUPTIBLE); | 1274 | set_current_state(TASK_UNINTERRUPTIBLE); |
1172 | add_wait_queue(&audit_backlog_wait, &wait); | 1275 | add_wait_queue_exclusive(&audit_backlog_wait, &wait); |
1173 | 1276 | ||
1174 | if (audit_backlog_limit && | 1277 | if (audit_backlog_limit && |
1175 | skb_queue_len(&audit_skb_queue) > audit_backlog_limit) | 1278 | skb_queue_len(&audit_skb_queue) > audit_backlog_limit) |
1176 | schedule_timeout(sleep_time); | 1279 | sleep_time = schedule_timeout(sleep_time); |
1177 | 1280 | ||
1178 | __set_current_state(TASK_RUNNING); | 1281 | __set_current_state(TASK_RUNNING); |
1179 | remove_wait_queue(&audit_backlog_wait, &wait); | 1282 | remove_wait_queue(&audit_backlog_wait, &wait); |
1283 | |||
1284 | return sleep_time; | ||
1180 | } | 1285 | } |
1181 | 1286 | ||
1182 | /** | 1287 | /** |
@@ -1200,7 +1305,8 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, | |||
1200 | struct audit_buffer *ab = NULL; | 1305 | struct audit_buffer *ab = NULL; |
1201 | struct timespec t; | 1306 | struct timespec t; |
1202 | unsigned int uninitialized_var(serial); | 1307 | unsigned int uninitialized_var(serial); |
1203 | int reserve; | 1308 | int reserve = 5; /* Allow atomic callers to go up to five |
1309 | entries over the normal backlog limit */ | ||
1204 | unsigned long timeout_start = jiffies; | 1310 | unsigned long timeout_start = jiffies; |
1205 | 1311 | ||
1206 | if (audit_initialized != AUDIT_INITIALIZED) | 1312 | if (audit_initialized != AUDIT_INITIALIZED) |
@@ -1209,36 +1315,37 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, | |||
1209 | if (unlikely(audit_filter_type(type))) | 1315 | if (unlikely(audit_filter_type(type))) |
1210 | return NULL; | 1316 | return NULL; |
1211 | 1317 | ||
1212 | if (gfp_mask & __GFP_WAIT) | 1318 | if (gfp_mask & __GFP_WAIT) { |
1213 | reserve = 0; | 1319 | if (audit_pid && audit_pid == current->pid) |
1214 | else | 1320 | gfp_mask &= ~__GFP_WAIT; |
1215 | reserve = 5; /* Allow atomic callers to go up to five | 1321 | else |
1216 | entries over the normal backlog limit */ | 1322 | reserve = 0; |
1323 | } | ||
1217 | 1324 | ||
1218 | while (audit_backlog_limit | 1325 | while (audit_backlog_limit |
1219 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { | 1326 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { |
1220 | if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time) { | 1327 | if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time) { |
1221 | unsigned long sleep_time; | 1328 | long sleep_time; |
1222 | 1329 | ||
1223 | sleep_time = timeout_start + audit_backlog_wait_time - | 1330 | sleep_time = timeout_start + audit_backlog_wait_time - jiffies; |
1224 | jiffies; | 1331 | if (sleep_time > 0) { |
1225 | if ((long)sleep_time > 0) { | 1332 | sleep_time = wait_for_auditd(sleep_time); |
1226 | wait_for_auditd(sleep_time); | 1333 | if (sleep_time > 0) |
1227 | continue; | 1334 | continue; |
1228 | } | 1335 | } |
1229 | } | 1336 | } |
1230 | if (audit_rate_check() && printk_ratelimit()) | 1337 | if (audit_rate_check() && printk_ratelimit()) |
1231 | printk(KERN_WARNING | 1338 | pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n", |
1232 | "audit: audit_backlog=%d > " | 1339 | skb_queue_len(&audit_skb_queue), |
1233 | "audit_backlog_limit=%d\n", | 1340 | audit_backlog_limit); |
1234 | skb_queue_len(&audit_skb_queue), | ||
1235 | audit_backlog_limit); | ||
1236 | audit_log_lost("backlog limit exceeded"); | 1341 | audit_log_lost("backlog limit exceeded"); |
1237 | audit_backlog_wait_time = audit_backlog_wait_overflow; | 1342 | audit_backlog_wait_time = audit_backlog_wait_overflow; |
1238 | wake_up(&audit_backlog_wait); | 1343 | wake_up(&audit_backlog_wait); |
1239 | return NULL; | 1344 | return NULL; |
1240 | } | 1345 | } |
1241 | 1346 | ||
1347 | audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; | ||
1348 | |||
1242 | ab = audit_buffer_alloc(ctx, gfp_mask, type); | 1349 | ab = audit_buffer_alloc(ctx, gfp_mask, type); |
1243 | if (!ab) { | 1350 | if (!ab) { |
1244 | audit_log_lost("out of memory in audit_log_start"); | 1351 | audit_log_lost("out of memory in audit_log_start"); |
@@ -1356,7 +1463,6 @@ void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf, | |||
1356 | int i, avail, new_len; | 1463 | int i, avail, new_len; |
1357 | unsigned char *ptr; | 1464 | unsigned char *ptr; |
1358 | struct sk_buff *skb; | 1465 | struct sk_buff *skb; |
1359 | static const unsigned char *hex = "0123456789ABCDEF"; | ||
1360 | 1466 | ||
1361 | if (!ab) | 1467 | if (!ab) |
1362 | return; | 1468 | return; |
@@ -1374,10 +1480,8 @@ void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf, | |||
1374 | } | 1480 | } |
1375 | 1481 | ||
1376 | ptr = skb_tail_pointer(skb); | 1482 | ptr = skb_tail_pointer(skb); |
1377 | for (i=0; i<len; i++) { | 1483 | for (i = 0; i < len; i++) |
1378 | *ptr++ = hex[(buf[i] & 0xF0)>>4]; /* Upper nibble */ | 1484 | ptr = hex_byte_pack_upper(ptr, buf[i]); |
1379 | *ptr++ = hex[buf[i] & 0x0F]; /* Lower nibble */ | ||
1380 | } | ||
1381 | *ptr = 0; | 1485 | *ptr = 0; |
1382 | skb_put(skb, len << 1); /* new string is twice the old string */ | 1486 | skb_put(skb, len << 1); /* new string is twice the old string */ |
1383 | } | 1487 | } |
@@ -1491,7 +1595,7 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix, | |||
1491 | 1595 | ||
1492 | void audit_log_session_info(struct audit_buffer *ab) | 1596 | void audit_log_session_info(struct audit_buffer *ab) |
1493 | { | 1597 | { |
1494 | u32 sessionid = audit_get_sessionid(current); | 1598 | unsigned int sessionid = audit_get_sessionid(current); |
1495 | uid_t auid = from_kuid(&init_user_ns, audit_get_loginuid(current)); | 1599 | uid_t auid = from_kuid(&init_user_ns, audit_get_loginuid(current)); |
1496 | 1600 | ||
1497 | audit_log_format(ab, " auid=%u ses=%u", auid, sessionid); | 1601 | audit_log_format(ab, " auid=%u ses=%u", auid, sessionid); |
@@ -1716,7 +1820,7 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) | |||
1716 | audit_log_format(ab, | 1820 | audit_log_format(ab, |
1717 | " ppid=%ld pid=%d auid=%u uid=%u gid=%u" | 1821 | " ppid=%ld pid=%d auid=%u uid=%u gid=%u" |
1718 | " euid=%u suid=%u fsuid=%u" | 1822 | " euid=%u suid=%u fsuid=%u" |
1719 | " egid=%u sgid=%u fsgid=%u ses=%u tty=%s", | 1823 | " egid=%u sgid=%u fsgid=%u tty=%s ses=%u", |
1720 | sys_getppid(), | 1824 | sys_getppid(), |
1721 | tsk->pid, | 1825 | tsk->pid, |
1722 | from_kuid(&init_user_ns, audit_get_loginuid(tsk)), | 1826 | from_kuid(&init_user_ns, audit_get_loginuid(tsk)), |
@@ -1728,7 +1832,7 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) | |||
1728 | from_kgid(&init_user_ns, cred->egid), | 1832 | from_kgid(&init_user_ns, cred->egid), |
1729 | from_kgid(&init_user_ns, cred->sgid), | 1833 | from_kgid(&init_user_ns, cred->sgid), |
1730 | from_kgid(&init_user_ns, cred->fsgid), | 1834 | from_kgid(&init_user_ns, cred->fsgid), |
1731 | audit_get_sessionid(tsk), tty); | 1835 | tty, audit_get_sessionid(tsk)); |
1732 | 1836 | ||
1733 | get_task_comm(name, tsk); | 1837 | get_task_comm(name, tsk); |
1734 | audit_log_format(ab, " comm="); | 1838 | audit_log_format(ab, " comm="); |
@@ -1739,7 +1843,8 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) | |||
1739 | if (mm->exe_file) | 1843 | if (mm->exe_file) |
1740 | audit_log_d_path(ab, " exe=", &mm->exe_file->f_path); | 1844 | audit_log_d_path(ab, " exe=", &mm->exe_file->f_path); |
1741 | up_read(&mm->mmap_sem); | 1845 | up_read(&mm->mmap_sem); |
1742 | } | 1846 | } else |
1847 | audit_log_format(ab, " exe=(null)"); | ||
1743 | audit_log_task_context(ab); | 1848 | audit_log_task_context(ab); |
1744 | } | 1849 | } |
1745 | EXPORT_SYMBOL(audit_log_task_info); | 1850 | EXPORT_SYMBOL(audit_log_task_info); |
diff --git a/kernel/audit.h b/kernel/audit.h index b779642b29af..57cc64d67718 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
@@ -209,7 +209,7 @@ struct audit_context { | |||
209 | #endif | 209 | #endif |
210 | }; | 210 | }; |
211 | 211 | ||
212 | extern int audit_ever_enabled; | 212 | extern u32 audit_ever_enabled; |
213 | 213 | ||
214 | extern void audit_copy_inode(struct audit_names *name, | 214 | extern void audit_copy_inode(struct audit_names *name, |
215 | const struct dentry *dentry, | 215 | const struct dentry *dentry, |
@@ -240,18 +240,23 @@ extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right); | |||
240 | extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right); | 240 | extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right); |
241 | extern int parent_len(const char *path); | 241 | extern int parent_len(const char *path); |
242 | extern int audit_compare_dname_path(const char *dname, const char *path, int plen); | 242 | extern int audit_compare_dname_path(const char *dname, const char *path, int plen); |
243 | extern struct sk_buff * audit_make_reply(int pid, int seq, int type, | 243 | extern struct sk_buff *audit_make_reply(__u32 portid, int seq, int type, |
244 | int done, int multi, | 244 | int done, int multi, |
245 | const void *payload, int size); | 245 | const void *payload, int size); |
246 | extern void audit_panic(const char *message); | 246 | extern void audit_panic(const char *message); |
247 | 247 | ||
248 | struct audit_netlink_list { | 248 | struct audit_netlink_list { |
249 | int pid; | 249 | __u32 portid; |
250 | pid_t pid; | ||
250 | struct sk_buff_head q; | 251 | struct sk_buff_head q; |
251 | }; | 252 | }; |
252 | 253 | ||
253 | int audit_send_list(void *); | 254 | int audit_send_list(void *); |
254 | 255 | ||
256 | struct audit_net { | ||
257 | struct sock *nlsk; | ||
258 | }; | ||
259 | |||
255 | extern int selinux_audit_rule_update(void); | 260 | extern int selinux_audit_rule_update(void); |
256 | 261 | ||
257 | extern struct mutex audit_filter_mutex; | 262 | extern struct mutex audit_filter_mutex; |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 51f3fd4c1ed3..14a78cca384e 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -972,7 +972,7 @@ out: | |||
972 | } | 972 | } |
973 | 973 | ||
974 | /* List rules using struct audit_rule_data. */ | 974 | /* List rules using struct audit_rule_data. */ |
975 | static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) | 975 | static void audit_list_rules(__u32 portid, int seq, struct sk_buff_head *q) |
976 | { | 976 | { |
977 | struct sk_buff *skb; | 977 | struct sk_buff *skb; |
978 | struct audit_krule *r; | 978 | struct audit_krule *r; |
@@ -987,14 +987,15 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) | |||
987 | data = audit_krule_to_data(r); | 987 | data = audit_krule_to_data(r); |
988 | if (unlikely(!data)) | 988 | if (unlikely(!data)) |
989 | break; | 989 | break; |
990 | skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1, | 990 | skb = audit_make_reply(portid, seq, AUDIT_LIST_RULES, |
991 | data, sizeof(*data) + data->buflen); | 991 | 0, 1, data, |
992 | sizeof(*data) + data->buflen); | ||
992 | if (skb) | 993 | if (skb) |
993 | skb_queue_tail(q, skb); | 994 | skb_queue_tail(q, skb); |
994 | kfree(data); | 995 | kfree(data); |
995 | } | 996 | } |
996 | } | 997 | } |
997 | skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0); | 998 | skb = audit_make_reply(portid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0); |
998 | if (skb) | 999 | if (skb) |
999 | skb_queue_tail(q, skb); | 1000 | skb_queue_tail(q, skb); |
1000 | } | 1001 | } |
@@ -1004,7 +1005,7 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re | |||
1004 | { | 1005 | { |
1005 | struct audit_buffer *ab; | 1006 | struct audit_buffer *ab; |
1006 | uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(current)); | 1007 | uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(current)); |
1007 | u32 sessionid = audit_get_sessionid(current); | 1008 | unsigned int sessionid = audit_get_sessionid(current); |
1008 | 1009 | ||
1009 | if (!audit_enabled) | 1010 | if (!audit_enabled) |
1010 | return; | 1011 | return; |
@@ -1022,45 +1023,20 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re | |||
1022 | } | 1023 | } |
1023 | 1024 | ||
1024 | /** | 1025 | /** |
1025 | * audit_receive_filter - apply all rules to the specified message type | 1026 | * audit_rule_change - apply all rules to the specified message type |
1026 | * @type: audit message type | 1027 | * @type: audit message type |
1027 | * @pid: target pid for netlink audit messages | 1028 | * @portid: target port id for netlink audit messages |
1028 | * @seq: netlink audit message sequence (serial) number | 1029 | * @seq: netlink audit message sequence (serial) number |
1029 | * @data: payload data | 1030 | * @data: payload data |
1030 | * @datasz: size of payload data | 1031 | * @datasz: size of payload data |
1031 | */ | 1032 | */ |
1032 | int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz) | 1033 | int audit_rule_change(int type, __u32 portid, int seq, void *data, |
1034 | size_t datasz) | ||
1033 | { | 1035 | { |
1034 | struct task_struct *tsk; | ||
1035 | struct audit_netlink_list *dest; | ||
1036 | int err = 0; | 1036 | int err = 0; |
1037 | struct audit_entry *entry; | 1037 | struct audit_entry *entry; |
1038 | 1038 | ||
1039 | switch (type) { | 1039 | switch (type) { |
1040 | case AUDIT_LIST_RULES: | ||
1041 | /* We can't just spew out the rules here because we might fill | ||
1042 | * the available socket buffer space and deadlock waiting for | ||
1043 | * auditctl to read from it... which isn't ever going to | ||
1044 | * happen if we're actually running in the context of auditctl | ||
1045 | * trying to _send_ the stuff */ | ||
1046 | |||
1047 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); | ||
1048 | if (!dest) | ||
1049 | return -ENOMEM; | ||
1050 | dest->pid = pid; | ||
1051 | skb_queue_head_init(&dest->q); | ||
1052 | |||
1053 | mutex_lock(&audit_filter_mutex); | ||
1054 | audit_list_rules(pid, seq, &dest->q); | ||
1055 | mutex_unlock(&audit_filter_mutex); | ||
1056 | |||
1057 | tsk = kthread_run(audit_send_list, dest, "audit_send_list"); | ||
1058 | if (IS_ERR(tsk)) { | ||
1059 | skb_queue_purge(&dest->q); | ||
1060 | kfree(dest); | ||
1061 | err = PTR_ERR(tsk); | ||
1062 | } | ||
1063 | break; | ||
1064 | case AUDIT_ADD_RULE: | 1040 | case AUDIT_ADD_RULE: |
1065 | entry = audit_data_to_entry(data, datasz); | 1041 | entry = audit_data_to_entry(data, datasz); |
1066 | if (IS_ERR(entry)) | 1042 | if (IS_ERR(entry)) |
@@ -1087,6 +1063,44 @@ int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz) | |||
1087 | return err; | 1063 | return err; |
1088 | } | 1064 | } |
1089 | 1065 | ||
1066 | /** | ||
1067 | * audit_list_rules_send - list the audit rules | ||
1068 | * @portid: target portid for netlink audit messages | ||
1069 | * @seq: netlink audit message sequence (serial) number | ||
1070 | */ | ||
1071 | int audit_list_rules_send(__u32 portid, int seq) | ||
1072 | { | ||
1073 | struct task_struct *tsk; | ||
1074 | struct audit_netlink_list *dest; | ||
1075 | int err = 0; | ||
1076 | |||
1077 | /* We can't just spew out the rules here because we might fill | ||
1078 | * the available socket buffer space and deadlock waiting for | ||
1079 | * auditctl to read from it... which isn't ever going to | ||
1080 | * happen if we're actually running in the context of auditctl | ||
1081 | * trying to _send_ the stuff */ | ||
1082 | |||
1083 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); | ||
1084 | if (!dest) | ||
1085 | return -ENOMEM; | ||
1086 | dest->portid = portid; | ||
1087 | dest->pid = task_pid_vnr(current); | ||
1088 | skb_queue_head_init(&dest->q); | ||
1089 | |||
1090 | mutex_lock(&audit_filter_mutex); | ||
1091 | audit_list_rules(portid, seq, &dest->q); | ||
1092 | mutex_unlock(&audit_filter_mutex); | ||
1093 | |||
1094 | tsk = kthread_run(audit_send_list, dest, "audit_send_list"); | ||
1095 | if (IS_ERR(tsk)) { | ||
1096 | skb_queue_purge(&dest->q); | ||
1097 | kfree(dest); | ||
1098 | err = PTR_ERR(tsk); | ||
1099 | } | ||
1100 | |||
1101 | return err; | ||
1102 | } | ||
1103 | |||
1090 | int audit_comparator(u32 left, u32 op, u32 right) | 1104 | int audit_comparator(u32 left, u32 op, u32 right) |
1091 | { | 1105 | { |
1092 | switch (op) { | 1106 | switch (op) { |
@@ -1276,19 +1290,22 @@ int audit_filter_user(int type) | |||
1276 | { | 1290 | { |
1277 | enum audit_state state = AUDIT_DISABLED; | 1291 | enum audit_state state = AUDIT_DISABLED; |
1278 | struct audit_entry *e; | 1292 | struct audit_entry *e; |
1279 | int ret = 1; | 1293 | int rc, ret; |
1294 | |||
1295 | ret = 1; /* Audit by default */ | ||
1280 | 1296 | ||
1281 | rcu_read_lock(); | 1297 | rcu_read_lock(); |
1282 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { | 1298 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { |
1283 | if (audit_filter_user_rules(&e->rule, type, &state)) { | 1299 | rc = audit_filter_user_rules(&e->rule, type, &state); |
1284 | if (state == AUDIT_DISABLED) | 1300 | if (rc) { |
1301 | if (rc > 0 && state == AUDIT_DISABLED) | ||
1285 | ret = 0; | 1302 | ret = 0; |
1286 | break; | 1303 | break; |
1287 | } | 1304 | } |
1288 | } | 1305 | } |
1289 | rcu_read_unlock(); | 1306 | rcu_read_unlock(); |
1290 | 1307 | ||
1291 | return ret; /* Audit by default */ | 1308 | return ret; |
1292 | } | 1309 | } |
1293 | 1310 | ||
1294 | int audit_filter_type(int type) | 1311 | int audit_filter_type(int type) |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 90594c9f7552..10176cd5956a 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -1969,18 +1969,24 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, | |||
1969 | int rc) | 1969 | int rc) |
1970 | { | 1970 | { |
1971 | struct audit_buffer *ab; | 1971 | struct audit_buffer *ab; |
1972 | uid_t uid, ologinuid, nloginuid; | 1972 | uid_t uid, oldloginuid, loginuid; |
1973 | |||
1974 | if (!audit_enabled) | ||
1975 | return; | ||
1973 | 1976 | ||
1974 | uid = from_kuid(&init_user_ns, task_uid(current)); | 1977 | uid = from_kuid(&init_user_ns, task_uid(current)); |
1975 | ologinuid = from_kuid(&init_user_ns, koldloginuid); | 1978 | oldloginuid = from_kuid(&init_user_ns, koldloginuid); |
1976 | nloginuid = from_kuid(&init_user_ns, kloginuid), | 1979 | loginuid = from_kuid(&init_user_ns, kloginuid), |
1977 | 1980 | ||
1978 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); | 1981 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); |
1979 | if (!ab) | 1982 | if (!ab) |
1980 | return; | 1983 | return; |
1981 | audit_log_format(ab, "pid=%d uid=%u old auid=%u new auid=%u old " | 1984 | audit_log_format(ab, "pid=%d uid=%u" |
1982 | "ses=%u new ses=%u res=%d", current->pid, uid, ologinuid, | 1985 | " old-auid=%u new-auid=%u old-ses=%u new-ses=%u" |
1983 | nloginuid, oldsessionid, sessionid, !rc); | 1986 | " res=%d", |
1987 | current->pid, uid, | ||
1988 | oldloginuid, loginuid, oldsessionid, sessionid, | ||
1989 | !rc); | ||
1984 | audit_log_end(ab); | 1990 | audit_log_end(ab); |
1985 | } | 1991 | } |
1986 | 1992 | ||
@@ -2008,7 +2014,7 @@ int audit_set_loginuid(kuid_t loginuid) | |||
2008 | 2014 | ||
2009 | /* are we setting or clearing? */ | 2015 | /* are we setting or clearing? */ |
2010 | if (uid_valid(loginuid)) | 2016 | if (uid_valid(loginuid)) |
2011 | sessionid = atomic_inc_return(&session_id); | 2017 | sessionid = (unsigned int)atomic_inc_return(&session_id); |
2012 | 2018 | ||
2013 | task->sessionid = sessionid; | 2019 | task->sessionid = sessionid; |
2014 | task->loginuid = loginuid; | 2020 | task->loginuid = loginuid; |
@@ -2321,18 +2327,16 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm, | |||
2321 | 2327 | ||
2322 | /** | 2328 | /** |
2323 | * __audit_log_capset - store information about the arguments to the capset syscall | 2329 | * __audit_log_capset - store information about the arguments to the capset syscall |
2324 | * @pid: target pid of the capset call | ||
2325 | * @new: the new credentials | 2330 | * @new: the new credentials |
2326 | * @old: the old (current) credentials | 2331 | * @old: the old (current) credentials |
2327 | * | 2332 | * |
2328 | * Record the aguments userspace sent to sys_capset for later printing by the | 2333 | * Record the aguments userspace sent to sys_capset for later printing by the |
2329 | * audit system if applicable | 2334 | * audit system if applicable |
2330 | */ | 2335 | */ |
2331 | void __audit_log_capset(pid_t pid, | 2336 | void __audit_log_capset(const struct cred *new, const struct cred *old) |
2332 | const struct cred *new, const struct cred *old) | ||
2333 | { | 2337 | { |
2334 | struct audit_context *context = current->audit_context; | 2338 | struct audit_context *context = current->audit_context; |
2335 | context->capset.pid = pid; | 2339 | context->capset.pid = task_pid_nr(current); |
2336 | context->capset.cap.effective = new->cap_effective; | 2340 | context->capset.cap.effective = new->cap_effective; |
2337 | context->capset.cap.inheritable = new->cap_effective; | 2341 | context->capset.cap.inheritable = new->cap_effective; |
2338 | context->capset.cap.permitted = new->cap_permitted; | 2342 | context->capset.cap.permitted = new->cap_permitted; |
@@ -2352,6 +2356,7 @@ static void audit_log_task(struct audit_buffer *ab) | |||
2352 | kuid_t auid, uid; | 2356 | kuid_t auid, uid; |
2353 | kgid_t gid; | 2357 | kgid_t gid; |
2354 | unsigned int sessionid; | 2358 | unsigned int sessionid; |
2359 | struct mm_struct *mm = current->mm; | ||
2355 | 2360 | ||
2356 | auid = audit_get_loginuid(current); | 2361 | auid = audit_get_loginuid(current); |
2357 | sessionid = audit_get_sessionid(current); | 2362 | sessionid = audit_get_sessionid(current); |
@@ -2365,15 +2370,15 @@ static void audit_log_task(struct audit_buffer *ab) | |||
2365 | audit_log_task_context(ab); | 2370 | audit_log_task_context(ab); |
2366 | audit_log_format(ab, " pid=%d comm=", current->pid); | 2371 | audit_log_format(ab, " pid=%d comm=", current->pid); |
2367 | audit_log_untrustedstring(ab, current->comm); | 2372 | audit_log_untrustedstring(ab, current->comm); |
2373 | if (mm) { | ||
2374 | down_read(&mm->mmap_sem); | ||
2375 | if (mm->exe_file) | ||
2376 | audit_log_d_path(ab, " exe=", &mm->exe_file->f_path); | ||
2377 | up_read(&mm->mmap_sem); | ||
2378 | } else | ||
2379 | audit_log_format(ab, " exe=(null)"); | ||
2368 | } | 2380 | } |
2369 | 2381 | ||
2370 | static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) | ||
2371 | { | ||
2372 | audit_log_task(ab); | ||
2373 | audit_log_format(ab, " reason="); | ||
2374 | audit_log_string(ab, reason); | ||
2375 | audit_log_format(ab, " sig=%ld", signr); | ||
2376 | } | ||
2377 | /** | 2382 | /** |
2378 | * audit_core_dumps - record information about processes that end abnormally | 2383 | * audit_core_dumps - record information about processes that end abnormally |
2379 | * @signr: signal value | 2384 | * @signr: signal value |
@@ -2394,7 +2399,8 @@ void audit_core_dumps(long signr) | |||
2394 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); | 2399 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); |
2395 | if (unlikely(!ab)) | 2400 | if (unlikely(!ab)) |
2396 | return; | 2401 | return; |
2397 | audit_log_abend(ab, "memory violation", signr); | 2402 | audit_log_task(ab); |
2403 | audit_log_format(ab, " sig=%ld", signr); | ||
2398 | audit_log_end(ab); | 2404 | audit_log_end(ab); |
2399 | } | 2405 | } |
2400 | 2406 | ||
diff --git a/kernel/capability.c b/kernel/capability.c index 4e66bf9275b0..34019c57888d 100644 --- a/kernel/capability.c +++ b/kernel/capability.c | |||
@@ -277,7 +277,7 @@ SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data) | |||
277 | if (ret < 0) | 277 | if (ret < 0) |
278 | goto error; | 278 | goto error; |
279 | 279 | ||
280 | audit_log_capset(pid, new, current_cred()); | 280 | audit_log_capset(new, current_cred()); |
281 | 281 | ||
282 | return commit_creds(new); | 282 | return commit_creds(new); |
283 | 283 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 9a91f7431c41..0d49945d0b9e 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -2906,12 +2906,12 @@ static void xfrm_policy_fini(struct net *net) | |||
2906 | flush_work(&net->xfrm.policy_hash_work); | 2906 | flush_work(&net->xfrm.policy_hash_work); |
2907 | #ifdef CONFIG_XFRM_SUB_POLICY | 2907 | #ifdef CONFIG_XFRM_SUB_POLICY |
2908 | audit_info.loginuid = INVALID_UID; | 2908 | audit_info.loginuid = INVALID_UID; |
2909 | audit_info.sessionid = -1; | 2909 | audit_info.sessionid = (unsigned int)-1; |
2910 | audit_info.secid = 0; | 2910 | audit_info.secid = 0; |
2911 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, &audit_info); | 2911 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, &audit_info); |
2912 | #endif | 2912 | #endif |
2913 | audit_info.loginuid = INVALID_UID; | 2913 | audit_info.loginuid = INVALID_UID; |
2914 | audit_info.sessionid = -1; | 2914 | audit_info.sessionid = (unsigned int)-1; |
2915 | audit_info.secid = 0; | 2915 | audit_info.secid = 0; |
2916 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); | 2916 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); |
2917 | 2917 | ||
@@ -3017,7 +3017,7 @@ static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp, | |||
3017 | } | 3017 | } |
3018 | 3018 | ||
3019 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | 3019 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, |
3020 | kuid_t auid, u32 sessionid, u32 secid) | 3020 | kuid_t auid, unsigned int sessionid, u32 secid) |
3021 | { | 3021 | { |
3022 | struct audit_buffer *audit_buf; | 3022 | struct audit_buffer *audit_buf; |
3023 | 3023 | ||
@@ -3032,7 +3032,7 @@ void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | |||
3032 | EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); | 3032 | EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); |
3033 | 3033 | ||
3034 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, | 3034 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, |
3035 | kuid_t auid, u32 sessionid, u32 secid) | 3035 | kuid_t auid, unsigned int sessionid, u32 secid) |
3036 | { | 3036 | { |
3037 | struct audit_buffer *audit_buf; | 3037 | struct audit_buffer *audit_buf; |
3038 | 3038 | ||
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 68c2f357a183..8ed9d0dd4566 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -2043,7 +2043,7 @@ void xfrm_state_fini(struct net *net) | |||
2043 | 2043 | ||
2044 | flush_work(&net->xfrm.state_hash_work); | 2044 | flush_work(&net->xfrm.state_hash_work); |
2045 | audit_info.loginuid = INVALID_UID; | 2045 | audit_info.loginuid = INVALID_UID; |
2046 | audit_info.sessionid = -1; | 2046 | audit_info.sessionid = (unsigned int)-1; |
2047 | audit_info.secid = 0; | 2047 | audit_info.secid = 0; |
2048 | xfrm_state_flush(net, IPSEC_PROTO_ANY, &audit_info); | 2048 | xfrm_state_flush(net, IPSEC_PROTO_ANY, &audit_info); |
2049 | flush_work(&net->xfrm.state_gc_work); | 2049 | flush_work(&net->xfrm.state_gc_work); |
@@ -2109,7 +2109,7 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family, | |||
2109 | } | 2109 | } |
2110 | 2110 | ||
2111 | void xfrm_audit_state_add(struct xfrm_state *x, int result, | 2111 | void xfrm_audit_state_add(struct xfrm_state *x, int result, |
2112 | kuid_t auid, u32 sessionid, u32 secid) | 2112 | kuid_t auid, unsigned int sessionid, u32 secid) |
2113 | { | 2113 | { |
2114 | struct audit_buffer *audit_buf; | 2114 | struct audit_buffer *audit_buf; |
2115 | 2115 | ||
@@ -2124,7 +2124,7 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result, | |||
2124 | EXPORT_SYMBOL_GPL(xfrm_audit_state_add); | 2124 | EXPORT_SYMBOL_GPL(xfrm_audit_state_add); |
2125 | 2125 | ||
2126 | void xfrm_audit_state_delete(struct xfrm_state *x, int result, | 2126 | void xfrm_audit_state_delete(struct xfrm_state *x, int result, |
2127 | kuid_t auid, u32 sessionid, u32 secid) | 2127 | kuid_t auid, unsigned int sessionid, u32 secid) |
2128 | { | 2128 | { |
2129 | struct audit_buffer *audit_buf; | 2129 | struct audit_buffer *audit_buf; |
2130 | 2130 | ||
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index f964d4c00ffb..ec97e13743e6 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -600,7 +600,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
600 | int err; | 600 | int err; |
601 | struct km_event c; | 601 | struct km_event c; |
602 | kuid_t loginuid = audit_get_loginuid(current); | 602 | kuid_t loginuid = audit_get_loginuid(current); |
603 | u32 sessionid = audit_get_sessionid(current); | 603 | unsigned int sessionid = audit_get_sessionid(current); |
604 | u32 sid; | 604 | u32 sid; |
605 | 605 | ||
606 | err = verify_newsa_info(p, attrs); | 606 | err = verify_newsa_info(p, attrs); |
@@ -679,7 +679,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
679 | struct km_event c; | 679 | struct km_event c; |
680 | struct xfrm_usersa_id *p = nlmsg_data(nlh); | 680 | struct xfrm_usersa_id *p = nlmsg_data(nlh); |
681 | kuid_t loginuid = audit_get_loginuid(current); | 681 | kuid_t loginuid = audit_get_loginuid(current); |
682 | u32 sessionid = audit_get_sessionid(current); | 682 | unsigned int sessionid = audit_get_sessionid(current); |
683 | u32 sid; | 683 | u32 sid; |
684 | 684 | ||
685 | x = xfrm_user_state_lookup(net, p, attrs, &err); | 685 | x = xfrm_user_state_lookup(net, p, attrs, &err); |
@@ -1405,7 +1405,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1405 | int err; | 1405 | int err; |
1406 | int excl; | 1406 | int excl; |
1407 | kuid_t loginuid = audit_get_loginuid(current); | 1407 | kuid_t loginuid = audit_get_loginuid(current); |
1408 | u32 sessionid = audit_get_sessionid(current); | 1408 | unsigned int sessionid = audit_get_sessionid(current); |
1409 | u32 sid; | 1409 | u32 sid; |
1410 | 1410 | ||
1411 | err = verify_newpolicy_info(p); | 1411 | err = verify_newpolicy_info(p); |
@@ -1663,7 +1663,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1663 | } | 1663 | } |
1664 | } else { | 1664 | } else { |
1665 | kuid_t loginuid = audit_get_loginuid(current); | 1665 | kuid_t loginuid = audit_get_loginuid(current); |
1666 | u32 sessionid = audit_get_sessionid(current); | 1666 | unsigned int sessionid = audit_get_sessionid(current); |
1667 | u32 sid; | 1667 | u32 sid; |
1668 | 1668 | ||
1669 | security_task_getsecid(current, &sid); | 1669 | security_task_getsecid(current, &sid); |
@@ -1959,7 +1959,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1959 | err = 0; | 1959 | err = 0; |
1960 | if (up->hard) { | 1960 | if (up->hard) { |
1961 | kuid_t loginuid = audit_get_loginuid(current); | 1961 | kuid_t loginuid = audit_get_loginuid(current); |
1962 | u32 sessionid = audit_get_sessionid(current); | 1962 | unsigned int sessionid = audit_get_sessionid(current); |
1963 | u32 sid; | 1963 | u32 sid; |
1964 | 1964 | ||
1965 | security_task_getsecid(current, &sid); | 1965 | security_task_getsecid(current, &sid); |
@@ -2002,7 +2002,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2002 | 2002 | ||
2003 | if (ue->hard) { | 2003 | if (ue->hard) { |
2004 | kuid_t loginuid = audit_get_loginuid(current); | 2004 | kuid_t loginuid = audit_get_loginuid(current); |
2005 | u32 sessionid = audit_get_sessionid(current); | 2005 | unsigned int sessionid = audit_get_sessionid(current); |
2006 | u32 sid; | 2006 | u32 sid; |
2007 | 2007 | ||
2008 | security_task_getsecid(current, &sid); | 2008 | security_task_getsecid(current, &sid); |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index fc5a63a05a1c..c93c21127f0c 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -2948,25 +2948,21 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | |||
2948 | struct selinux_audit_rule *rule = vrule; | 2948 | struct selinux_audit_rule *rule = vrule; |
2949 | int match = 0; | 2949 | int match = 0; |
2950 | 2950 | ||
2951 | if (!rule) { | 2951 | if (unlikely(!rule)) { |
2952 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | 2952 | WARN_ONCE(1, "selinux_audit_rule_match: missing rule\n"); |
2953 | "selinux_audit_rule_match: missing rule\n"); | ||
2954 | return -ENOENT; | 2953 | return -ENOENT; |
2955 | } | 2954 | } |
2956 | 2955 | ||
2957 | read_lock(&policy_rwlock); | 2956 | read_lock(&policy_rwlock); |
2958 | 2957 | ||
2959 | if (rule->au_seqno < latest_granting) { | 2958 | if (rule->au_seqno < latest_granting) { |
2960 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
2961 | "selinux_audit_rule_match: stale rule\n"); | ||
2962 | match = -ESTALE; | 2959 | match = -ESTALE; |
2963 | goto out; | 2960 | goto out; |
2964 | } | 2961 | } |
2965 | 2962 | ||
2966 | ctxt = sidtab_search(&sidtab, sid); | 2963 | ctxt = sidtab_search(&sidtab, sid); |
2967 | if (!ctxt) { | 2964 | if (unlikely(!ctxt)) { |
2968 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | 2965 | WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n", |
2969 | "selinux_audit_rule_match: unrecognized SID %d\n", | ||
2970 | sid); | 2966 | sid); |
2971 | match = -ENOENT; | 2967 | match = -ENOENT; |
2972 | goto out; | 2968 | goto out; |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index d814e35987be..14f52be78c75 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -3616,9 +3616,8 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, | |||
3616 | struct smack_known *skp; | 3616 | struct smack_known *skp; |
3617 | char *rule = vrule; | 3617 | char *rule = vrule; |
3618 | 3618 | ||
3619 | if (!rule) { | 3619 | if (unlikely(!rule)) { |
3620 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | 3620 | WARN_ONCE(1, "Smack: missing rule\n"); |
3621 | "Smack: missing rule\n"); | ||
3622 | return -ENOENT; | 3621 | return -ENOENT; |
3623 | } | 3622 | } |
3624 | 3623 | ||