diff options
-rw-r--r-- | MAINTAINERS | 8 | ||||
-rw-r--r-- | drivers/char/tty_audit.c | 63 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 5 | ||||
-rw-r--r-- | include/linux/audit.h | 28 | ||||
-rw-r--r-- | include/linux/netlink.h | 1 | ||||
-rw-r--r-- | include/linux/tty.h | 9 | ||||
-rw-r--r-- | include/net/netlabel.h | 1 | ||||
-rw-r--r-- | include/net/xfrm.h | 23 | ||||
-rw-r--r-- | kernel/audit.c | 249 | ||||
-rw-r--r-- | kernel/audit.h | 13 | ||||
-rw-r--r-- | kernel/auditfilter.c | 45 | ||||
-rw-r--r-- | kernel/auditsc.c | 40 | ||||
-rw-r--r-- | net/key/af_key.c | 17 | ||||
-rw-r--r-- | net/netlabel/netlabel_unlabeled.c | 1 | ||||
-rw-r--r-- | net/netlabel/netlabel_user.c | 4 | ||||
-rw-r--r-- | net/netlabel/netlabel_user.h | 1 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 1 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 12 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 13 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 41 | ||||
-rw-r--r-- | security/selinux/avc.c | 2 | ||||
-rw-r--r-- | security/smack/smackfs.c | 2 |
22 files changed, 346 insertions, 233 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index c4e5b5dec154..bca09ed77029 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -752,11 +752,13 @@ W: http://atmelwlandriver.sourceforge.net/ | |||
752 | S: Maintained | 752 | S: Maintained |
753 | 753 | ||
754 | AUDIT SUBSYSTEM | 754 | AUDIT SUBSYSTEM |
755 | P: David Woodhouse | 755 | P: Al Viro |
756 | M: dwmw2@infradead.org | 756 | M: viro@zeniv.linux.org.uk |
757 | P: Eric Paris | ||
758 | M: eparis@redhat.com | ||
757 | L: linux-audit@redhat.com (subscribers-only) | 759 | L: linux-audit@redhat.com (subscribers-only) |
758 | W: http://people.redhat.com/sgrubb/audit/ | 760 | W: http://people.redhat.com/sgrubb/audit/ |
759 | T: git kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6.git | 761 | T: git git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current.git |
760 | S: Maintained | 762 | S: Maintained |
761 | 763 | ||
762 | AUXILIARY DISPLAY DRIVERS | 764 | AUXILIARY DISPLAY DRIVERS |
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c index 7722466e052f..6342b0534f4d 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/char/tty_audit.c | |||
@@ -92,7 +92,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid, | |||
92 | get_task_comm(name, tsk); | 92 | get_task_comm(name, tsk); |
93 | audit_log_untrustedstring(ab, name); | 93 | audit_log_untrustedstring(ab, name); |
94 | audit_log_format(ab, " data="); | 94 | audit_log_format(ab, " data="); |
95 | audit_log_n_untrustedstring(ab, buf->valid, buf->data); | 95 | audit_log_n_untrustedstring(ab, buf->data, buf->valid); |
96 | audit_log_end(ab); | 96 | audit_log_end(ab); |
97 | } | 97 | } |
98 | buf->valid = 0; | 98 | buf->valid = 0; |
@@ -151,14 +151,9 @@ void tty_audit_fork(struct signal_struct *sig) | |||
151 | /** | 151 | /** |
152 | * tty_audit_push_task - Flush task's pending audit data | 152 | * tty_audit_push_task - Flush task's pending audit data |
153 | */ | 153 | */ |
154 | void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid) | 154 | void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) |
155 | { | 155 | { |
156 | struct tty_audit_buf *buf; | 156 | struct tty_audit_buf *buf; |
157 | /* FIXME I think this is correct. Check against netlink once that is | ||
158 | * I really need to read this code more closely. But that's for | ||
159 | * another patch. | ||
160 | */ | ||
161 | unsigned int sessionid = audit_get_sessionid(tsk); | ||
162 | 157 | ||
163 | spin_lock_irq(&tsk->sighand->siglock); | 158 | spin_lock_irq(&tsk->sighand->siglock); |
164 | buf = tsk->signal->tty_audit_buf; | 159 | buf = tsk->signal->tty_audit_buf; |
@@ -238,6 +233,10 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, | |||
238 | if (unlikely(size == 0)) | 233 | if (unlikely(size == 0)) |
239 | return; | 234 | return; |
240 | 235 | ||
236 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY | ||
237 | && tty->driver->subtype == PTY_TYPE_MASTER) | ||
238 | return; | ||
239 | |||
241 | buf = tty_audit_buf_get(tty); | 240 | buf = tty_audit_buf_get(tty); |
242 | if (!buf) | 241 | if (!buf) |
243 | return; | 242 | return; |
@@ -300,53 +299,3 @@ void tty_audit_push(struct tty_struct *tty) | |||
300 | tty_audit_buf_put(buf); | 299 | tty_audit_buf_put(buf); |
301 | } | 300 | } |
302 | } | 301 | } |
303 | |||
304 | /** | ||
305 | * tty_audit_opening - A TTY is being opened. | ||
306 | * | ||
307 | * As a special hack, tasks that close all their TTYs and open new ones | ||
308 | * are assumed to be system daemons (e.g. getty) and auditing is | ||
309 | * automatically disabled for them. | ||
310 | */ | ||
311 | void tty_audit_opening(void) | ||
312 | { | ||
313 | int disable; | ||
314 | |||
315 | disable = 1; | ||
316 | spin_lock_irq(¤t->sighand->siglock); | ||
317 | if (current->signal->audit_tty == 0) | ||
318 | disable = 0; | ||
319 | spin_unlock_irq(¤t->sighand->siglock); | ||
320 | if (!disable) | ||
321 | return; | ||
322 | |||
323 | task_lock(current); | ||
324 | if (current->files) { | ||
325 | struct fdtable *fdt; | ||
326 | unsigned i; | ||
327 | |||
328 | /* | ||
329 | * We don't take a ref to the file, so we must hold ->file_lock | ||
330 | * instead. | ||
331 | */ | ||
332 | spin_lock(¤t->files->file_lock); | ||
333 | fdt = files_fdtable(current->files); | ||
334 | for (i = 0; i < fdt->max_fds; i++) { | ||
335 | struct file *filp; | ||
336 | |||
337 | filp = fcheck_files(current->files, i); | ||
338 | if (filp && is_tty(filp)) { | ||
339 | disable = 0; | ||
340 | break; | ||
341 | } | ||
342 | } | ||
343 | spin_unlock(¤t->files->file_lock); | ||
344 | } | ||
345 | task_unlock(current); | ||
346 | if (!disable) | ||
347 | return; | ||
348 | |||
349 | spin_lock_irq(¤t->sighand->siglock); | ||
350 | current->signal->audit_tty = 0; | ||
351 | spin_unlock_irq(¤t->sighand->siglock); | ||
352 | } | ||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 98b65a230994..2fa6856706ab 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -2755,7 +2755,6 @@ got_driver: | |||
2755 | __proc_set_tty(current, tty); | 2755 | __proc_set_tty(current, tty); |
2756 | spin_unlock_irq(¤t->sighand->siglock); | 2756 | spin_unlock_irq(¤t->sighand->siglock); |
2757 | mutex_unlock(&tty_mutex); | 2757 | mutex_unlock(&tty_mutex); |
2758 | tty_audit_opening(); | ||
2759 | return 0; | 2758 | return 0; |
2760 | } | 2759 | } |
2761 | 2760 | ||
@@ -2818,10 +2817,8 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
2818 | 2817 | ||
2819 | check_tty_count(tty, "tty_open"); | 2818 | check_tty_count(tty, "tty_open"); |
2820 | retval = ptm_driver->open(tty, filp); | 2819 | retval = ptm_driver->open(tty, filp); |
2821 | if (!retval) { | 2820 | if (!retval) |
2822 | tty_audit_opening(); | ||
2823 | return 0; | 2821 | return 0; |
2824 | } | ||
2825 | out1: | 2822 | out1: |
2826 | release_dev(filp); | 2823 | release_dev(filp); |
2827 | return retval; | 2824 | return retval; |
diff --git a/include/linux/audit.h b/include/linux/audit.h index 4ccb048cae1d..63c3bb98558f 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -146,7 +146,7 @@ | |||
146 | /* Rule structure sizes -- if these change, different AUDIT_ADD and | 146 | /* Rule structure sizes -- if these change, different AUDIT_ADD and |
147 | * AUDIT_LIST commands must be implemented. */ | 147 | * AUDIT_LIST commands must be implemented. */ |
148 | #define AUDIT_MAX_FIELDS 64 | 148 | #define AUDIT_MAX_FIELDS 64 |
149 | #define AUDIT_MAX_KEY_LEN 32 | 149 | #define AUDIT_MAX_KEY_LEN 256 |
150 | #define AUDIT_BITMASK_SIZE 64 | 150 | #define AUDIT_BITMASK_SIZE 64 |
151 | #define AUDIT_WORD(nr) ((__u32)((nr)/32)) | 151 | #define AUDIT_WORD(nr) ((__u32)((nr)/32)) |
152 | #define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32)) | 152 | #define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32)) |
@@ -209,6 +209,7 @@ | |||
209 | #define AUDIT_WATCH 105 | 209 | #define AUDIT_WATCH 105 |
210 | #define AUDIT_PERM 106 | 210 | #define AUDIT_PERM 106 |
211 | #define AUDIT_DIR 107 | 211 | #define AUDIT_DIR 107 |
212 | #define AUDIT_FILETYPE 108 | ||
212 | 213 | ||
213 | #define AUDIT_ARG0 200 | 214 | #define AUDIT_ARG0 200 |
214 | #define AUDIT_ARG1 (AUDIT_ARG0+1) | 215 | #define AUDIT_ARG1 (AUDIT_ARG0+1) |
@@ -549,16 +550,20 @@ extern void audit_log_format(struct audit_buffer *ab, | |||
549 | const char *fmt, ...) | 550 | const char *fmt, ...) |
550 | __attribute__((format(printf,2,3))); | 551 | __attribute__((format(printf,2,3))); |
551 | extern void audit_log_end(struct audit_buffer *ab); | 552 | extern void audit_log_end(struct audit_buffer *ab); |
552 | extern void audit_log_hex(struct audit_buffer *ab, | ||
553 | const unsigned char *buf, | ||
554 | size_t len); | ||
555 | extern int audit_string_contains_control(const char *string, | 553 | extern int audit_string_contains_control(const char *string, |
556 | size_t len); | 554 | size_t len); |
555 | extern void audit_log_n_hex(struct audit_buffer *ab, | ||
556 | const unsigned char *buf, | ||
557 | size_t len); | ||
558 | extern void audit_log_n_string(struct audit_buffer *ab, | ||
559 | const char *buf, | ||
560 | size_t n); | ||
561 | #define audit_log_string(a,b) audit_log_n_string(a, b, strlen(b)); | ||
562 | extern void audit_log_n_untrustedstring(struct audit_buffer *ab, | ||
563 | const char *string, | ||
564 | size_t n); | ||
557 | extern void audit_log_untrustedstring(struct audit_buffer *ab, | 565 | extern void audit_log_untrustedstring(struct audit_buffer *ab, |
558 | const char *string); | 566 | const char *string); |
559 | extern void audit_log_n_untrustedstring(struct audit_buffer *ab, | ||
560 | size_t n, | ||
561 | const char *string); | ||
562 | extern void audit_log_d_path(struct audit_buffer *ab, | 567 | extern void audit_log_d_path(struct audit_buffer *ab, |
563 | const char *prefix, | 568 | const char *prefix, |
564 | struct path *path); | 569 | struct path *path); |
@@ -569,7 +574,8 @@ extern int audit_update_lsm_rules(void); | |||
569 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); | 574 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); |
570 | extern int audit_filter_type(int type); | 575 | extern int audit_filter_type(int type); |
571 | extern int audit_receive_filter(int type, int pid, int uid, int seq, | 576 | extern int audit_receive_filter(int type, int pid, int uid, int seq, |
572 | void *data, size_t datasz, uid_t loginuid, u32 sid); | 577 | void *data, size_t datasz, uid_t loginuid, |
578 | u32 sessionid, u32 sid); | ||
573 | extern int audit_enabled; | 579 | extern int audit_enabled; |
574 | #else | 580 | #else |
575 | #define audit_log(c,g,t,f,...) do { ; } while (0) | 581 | #define audit_log(c,g,t,f,...) do { ; } while (0) |
@@ -577,9 +583,11 @@ extern int audit_enabled; | |||
577 | #define audit_log_vformat(b,f,a) do { ; } while (0) | 583 | #define audit_log_vformat(b,f,a) do { ; } while (0) |
578 | #define audit_log_format(b,f,...) do { ; } while (0) | 584 | #define audit_log_format(b,f,...) do { ; } while (0) |
579 | #define audit_log_end(b) do { ; } while (0) | 585 | #define audit_log_end(b) do { ; } while (0) |
580 | #define audit_log_hex(a,b,l) do { ; } while (0) | 586 | #define audit_log_n_hex(a,b,l) do { ; } while (0) |
581 | #define audit_log_untrustedstring(a,s) do { ; } while (0) | 587 | #define audit_log_n_string(a,c,l) do { ; } while (0) |
588 | #define audit_log_string(a,c) do { ; } while (0) | ||
582 | #define audit_log_n_untrustedstring(a,n,s) do { ; } while (0) | 589 | #define audit_log_n_untrustedstring(a,n,s) do { ; } while (0) |
590 | #define audit_log_untrustedstring(a,s) do { ; } while (0) | ||
583 | #define audit_log_d_path(b, p, d) do { ; } while (0) | 591 | #define audit_log_d_path(b, p, d) do { ; } while (0) |
584 | #define audit_enabled 0 | 592 | #define audit_enabled 0 |
585 | #endif | 593 | #endif |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index fb0713b6ffaf..bec1062a25a1 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
@@ -166,6 +166,7 @@ struct netlink_skb_parms | |||
166 | __u32 dst_group; | 166 | __u32 dst_group; |
167 | kernel_cap_t eff_cap; | 167 | kernel_cap_t eff_cap; |
168 | __u32 loginuid; /* Login (audit) uid */ | 168 | __u32 loginuid; /* Login (audit) uid */ |
169 | __u32 sessionid; /* Session id (audit) */ | ||
169 | __u32 sid; /* SELinux security id */ | 170 | __u32 sid; /* SELinux security id */ |
170 | }; | 171 | }; |
171 | 172 | ||
diff --git a/include/linux/tty.h b/include/linux/tty.h index dd8e08fe8855..265831ccaa88 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -300,7 +300,6 @@ extern void tty_hangup(struct tty_struct * tty); | |||
300 | extern void tty_vhangup(struct tty_struct * tty); | 300 | extern void tty_vhangup(struct tty_struct * tty); |
301 | extern void tty_unhangup(struct file *filp); | 301 | extern void tty_unhangup(struct file *filp); |
302 | extern int tty_hung_up_p(struct file * filp); | 302 | extern int tty_hung_up_p(struct file * filp); |
303 | extern int is_tty(struct file *filp); | ||
304 | extern void do_SAK(struct tty_struct *tty); | 303 | extern void do_SAK(struct tty_struct *tty); |
305 | extern void __do_SAK(struct tty_struct *tty); | 304 | extern void __do_SAK(struct tty_struct *tty); |
306 | extern void disassociate_ctty(int priv); | 305 | extern void disassociate_ctty(int priv); |
@@ -351,8 +350,7 @@ extern void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, | |||
351 | extern void tty_audit_exit(void); | 350 | extern void tty_audit_exit(void); |
352 | extern void tty_audit_fork(struct signal_struct *sig); | 351 | extern void tty_audit_fork(struct signal_struct *sig); |
353 | extern void tty_audit_push(struct tty_struct *tty); | 352 | extern void tty_audit_push(struct tty_struct *tty); |
354 | extern void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid); | 353 | extern void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid); |
355 | extern void tty_audit_opening(void); | ||
356 | #else | 354 | #else |
357 | static inline void tty_audit_add_data(struct tty_struct *tty, | 355 | static inline void tty_audit_add_data(struct tty_struct *tty, |
358 | unsigned char *data, size_t size) | 356 | unsigned char *data, size_t size) |
@@ -367,10 +365,7 @@ static inline void tty_audit_fork(struct signal_struct *sig) | |||
367 | static inline void tty_audit_push(struct tty_struct *tty) | 365 | static inline void tty_audit_push(struct tty_struct *tty) |
368 | { | 366 | { |
369 | } | 367 | } |
370 | static inline void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid) | 368 | static inline void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) |
371 | { | ||
372 | } | ||
373 | static inline void tty_audit_opening(void) | ||
374 | { | 369 | { |
375 | } | 370 | } |
376 | #endif | 371 | #endif |
diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 5e53a85b5ca1..e4d2d6baa983 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h | |||
@@ -103,6 +103,7 @@ struct cipso_v4_doi; | |||
103 | struct netlbl_audit { | 103 | struct netlbl_audit { |
104 | u32 secid; | 104 | u32 secid; |
105 | uid_t loginuid; | 105 | uid_t loginuid; |
106 | u32 sessionid; | ||
106 | }; | 107 | }; |
107 | 108 | ||
108 | /* | 109 | /* |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index baa9f372cfd1..d1350bcccb03 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -597,8 +597,9 @@ struct xfrm_spi_skb_cb { | |||
597 | /* Audit Information */ | 597 | /* Audit Information */ |
598 | struct xfrm_audit | 598 | struct xfrm_audit |
599 | { | 599 | { |
600 | u32 loginuid; | ||
601 | u32 secid; | 600 | u32 secid; |
601 | uid_t loginuid; | ||
602 | u32 sessionid; | ||
602 | }; | 603 | }; |
603 | 604 | ||
604 | #ifdef CONFIG_AUDITSYSCALL | 605 | #ifdef CONFIG_AUDITSYSCALL |
@@ -616,13 +617,13 @@ static inline struct audit_buffer *xfrm_audit_start(const char *op) | |||
616 | return audit_buf; | 617 | return audit_buf; |
617 | } | 618 | } |
618 | 619 | ||
619 | static inline void xfrm_audit_helper_usrinfo(u32 auid, u32 secid, | 620 | static inline void xfrm_audit_helper_usrinfo(uid_t auid, u32 ses, u32 secid, |
620 | struct audit_buffer *audit_buf) | 621 | struct audit_buffer *audit_buf) |
621 | { | 622 | { |
622 | char *secctx; | 623 | char *secctx; |
623 | u32 secctx_len; | 624 | u32 secctx_len; |
624 | 625 | ||
625 | audit_log_format(audit_buf, " auid=%u", auid); | 626 | audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses); |
626 | if (secid != 0 && | 627 | if (secid != 0 && |
627 | security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) { | 628 | security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) { |
628 | audit_log_format(audit_buf, " subj=%s", secctx); | 629 | audit_log_format(audit_buf, " subj=%s", secctx); |
@@ -632,13 +633,13 @@ static inline void xfrm_audit_helper_usrinfo(u32 auid, u32 secid, | |||
632 | } | 633 | } |
633 | 634 | ||
634 | extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | 635 | extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, |
635 | u32 auid, u32 secid); | 636 | u32 auid, u32 ses, u32 secid); |
636 | extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, | 637 | extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, |
637 | u32 auid, u32 secid); | 638 | u32 auid, u32 ses, u32 secid); |
638 | extern void xfrm_audit_state_add(struct xfrm_state *x, int result, | 639 | extern void xfrm_audit_state_add(struct xfrm_state *x, int result, |
639 | u32 auid, u32 secid); | 640 | u32 auid, u32 ses, u32 secid); |
640 | extern void xfrm_audit_state_delete(struct xfrm_state *x, int result, | 641 | extern void xfrm_audit_state_delete(struct xfrm_state *x, int result, |
641 | u32 auid, u32 secid); | 642 | u32 auid, u32 ses, u32 secid); |
642 | extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x, | 643 | extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x, |
643 | struct sk_buff *skb); | 644 | struct sk_buff *skb); |
644 | extern void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family); | 645 | extern void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family); |
@@ -647,10 +648,10 @@ extern void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, | |||
647 | extern void xfrm_audit_state_icvfail(struct xfrm_state *x, | 648 | extern void xfrm_audit_state_icvfail(struct xfrm_state *x, |
648 | struct sk_buff *skb, u8 proto); | 649 | struct sk_buff *skb, u8 proto); |
649 | #else | 650 | #else |
650 | #define xfrm_audit_policy_add(x, r, a, s) do { ; } while (0) | 651 | #define xfrm_audit_policy_add(x, r, a, se, s) do { ; } while (0) |
651 | #define xfrm_audit_policy_delete(x, r, a, s) do { ; } while (0) | 652 | #define xfrm_audit_policy_delete(x, r, a, se, s) do { ; } while (0) |
652 | #define xfrm_audit_state_add(x, r, a, s) do { ; } while (0) | 653 | #define xfrm_audit_state_add(x, r, a, se, s) do { ; } while (0) |
653 | #define xfrm_audit_state_delete(x, r, a, s) do { ; } while (0) | 654 | #define xfrm_audit_state_delete(x, r, a, se, s) do { ; } while (0) |
654 | #define xfrm_audit_state_replay_overflow(x, s) do { ; } while (0) | 655 | #define xfrm_audit_state_replay_overflow(x, s) do { ; } while (0) |
655 | #define xfrm_audit_state_notfound_simple(s, f) do { ; } while (0) | 656 | #define xfrm_audit_state_notfound_simple(s, f) do { ; } while (0) |
656 | #define xfrm_audit_state_notfound(s, f, sp, sq) do { ; } while (0) | 657 | #define xfrm_audit_state_notfound(s, f, sp, sq) do { ; } while (0) |
diff --git a/kernel/audit.c b/kernel/audit.c index a7b16086d36f..b7d3709cc452 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -126,6 +126,8 @@ static int audit_freelist_count; | |||
126 | static LIST_HEAD(audit_freelist); | 126 | static LIST_HEAD(audit_freelist); |
127 | 127 | ||
128 | static struct sk_buff_head audit_skb_queue; | 128 | static struct sk_buff_head audit_skb_queue; |
129 | /* queue of skbs to send to auditd when/if it comes back */ | ||
130 | static struct sk_buff_head audit_skb_hold_queue; | ||
129 | static struct task_struct *kauditd_task; | 131 | static struct task_struct *kauditd_task; |
130 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); | 132 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); |
131 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); | 133 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); |
@@ -154,6 +156,11 @@ struct audit_buffer { | |||
154 | gfp_t gfp_mask; | 156 | gfp_t gfp_mask; |
155 | }; | 157 | }; |
156 | 158 | ||
159 | struct audit_reply { | ||
160 | int pid; | ||
161 | struct sk_buff *skb; | ||
162 | }; | ||
163 | |||
157 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) | 164 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) |
158 | { | 165 | { |
159 | if (ab) { | 166 | if (ab) { |
@@ -252,14 +259,15 @@ void audit_log_lost(const char *message) | |||
252 | } | 259 | } |
253 | 260 | ||
254 | static int audit_log_config_change(char *function_name, int new, int old, | 261 | static int audit_log_config_change(char *function_name, int new, int old, |
255 | uid_t loginuid, u32 sid, int allow_changes) | 262 | uid_t loginuid, u32 sessionid, u32 sid, |
263 | int allow_changes) | ||
256 | { | 264 | { |
257 | struct audit_buffer *ab; | 265 | struct audit_buffer *ab; |
258 | int rc = 0; | 266 | int rc = 0; |
259 | 267 | ||
260 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 268 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
261 | audit_log_format(ab, "%s=%d old=%d by auid=%u", function_name, new, | 269 | audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, |
262 | old, loginuid); | 270 | old, loginuid, sessionid); |
263 | if (sid) { | 271 | if (sid) { |
264 | char *ctx = NULL; | 272 | char *ctx = NULL; |
265 | u32 len; | 273 | u32 len; |
@@ -279,7 +287,8 @@ static int audit_log_config_change(char *function_name, int new, int old, | |||
279 | } | 287 | } |
280 | 288 | ||
281 | static int audit_do_config_change(char *function_name, int *to_change, | 289 | static int audit_do_config_change(char *function_name, int *to_change, |
282 | int new, uid_t loginuid, u32 sid) | 290 | int new, uid_t loginuid, u32 sessionid, |
291 | u32 sid) | ||
283 | { | 292 | { |
284 | int allow_changes, rc = 0, old = *to_change; | 293 | int allow_changes, rc = 0, old = *to_change; |
285 | 294 | ||
@@ -290,8 +299,8 @@ static int audit_do_config_change(char *function_name, int *to_change, | |||
290 | allow_changes = 1; | 299 | allow_changes = 1; |
291 | 300 | ||
292 | if (audit_enabled != AUDIT_OFF) { | 301 | if (audit_enabled != AUDIT_OFF) { |
293 | rc = audit_log_config_change(function_name, new, old, | 302 | rc = audit_log_config_change(function_name, new, old, loginuid, |
294 | loginuid, sid, allow_changes); | 303 | sessionid, sid, allow_changes); |
295 | if (rc) | 304 | if (rc) |
296 | allow_changes = 0; | 305 | allow_changes = 0; |
297 | } | 306 | } |
@@ -305,26 +314,28 @@ static int audit_do_config_change(char *function_name, int *to_change, | |||
305 | return rc; | 314 | return rc; |
306 | } | 315 | } |
307 | 316 | ||
308 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid) | 317 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sessionid, |
318 | u32 sid) | ||
309 | { | 319 | { |
310 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, | 320 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, |
311 | limit, loginuid, sid); | 321 | limit, loginuid, sessionid, sid); |
312 | } | 322 | } |
313 | 323 | ||
314 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) | 324 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sessionid, |
325 | u32 sid) | ||
315 | { | 326 | { |
316 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, | 327 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, |
317 | limit, loginuid, sid); | 328 | limit, loginuid, sessionid, sid); |
318 | } | 329 | } |
319 | 330 | ||
320 | static int audit_set_enabled(int state, uid_t loginuid, u32 sid) | 331 | static int audit_set_enabled(int state, uid_t loginuid, u32 sessionid, u32 sid) |
321 | { | 332 | { |
322 | int rc; | 333 | int rc; |
323 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) | 334 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) |
324 | return -EINVAL; | 335 | return -EINVAL; |
325 | 336 | ||
326 | rc = audit_do_config_change("audit_enabled", &audit_enabled, state, | 337 | rc = audit_do_config_change("audit_enabled", &audit_enabled, state, |
327 | loginuid, sid); | 338 | loginuid, sessionid, sid); |
328 | 339 | ||
329 | if (!rc) | 340 | if (!rc) |
330 | audit_ever_enabled |= !!state; | 341 | audit_ever_enabled |= !!state; |
@@ -332,7 +343,7 @@ static int audit_set_enabled(int state, uid_t loginuid, u32 sid) | |||
332 | return rc; | 343 | return rc; |
333 | } | 344 | } |
334 | 345 | ||
335 | static int audit_set_failure(int state, uid_t loginuid, u32 sid) | 346 | static int audit_set_failure(int state, uid_t loginuid, u32 sessionid, u32 sid) |
336 | { | 347 | { |
337 | if (state != AUDIT_FAIL_SILENT | 348 | if (state != AUDIT_FAIL_SILENT |
338 | && state != AUDIT_FAIL_PRINTK | 349 | && state != AUDIT_FAIL_PRINTK |
@@ -340,7 +351,43 @@ static int audit_set_failure(int state, uid_t loginuid, u32 sid) | |||
340 | return -EINVAL; | 351 | return -EINVAL; |
341 | 352 | ||
342 | return audit_do_config_change("audit_failure", &audit_failure, state, | 353 | return audit_do_config_change("audit_failure", &audit_failure, state, |
343 | loginuid, sid); | 354 | loginuid, sessionid, sid); |
355 | } | ||
356 | |||
357 | /* | ||
358 | * Queue skbs to be sent to auditd when/if it comes back. These skbs should | ||
359 | * already have been sent via prink/syslog and so if these messages are dropped | ||
360 | * it is not a huge concern since we already passed the audit_log_lost() | ||
361 | * notification and stuff. This is just nice to get audit messages during | ||
362 | * boot before auditd is running or messages generated while auditd is stopped. | ||
363 | * This only holds messages is audit_default is set, aka booting with audit=1 | ||
364 | * or building your kernel that way. | ||
365 | */ | ||
366 | static void audit_hold_skb(struct sk_buff *skb) | ||
367 | { | ||
368 | if (audit_default && | ||
369 | skb_queue_len(&audit_skb_hold_queue) < audit_backlog_limit) | ||
370 | skb_queue_tail(&audit_skb_hold_queue, skb); | ||
371 | else | ||
372 | kfree_skb(skb); | ||
373 | } | ||
374 | |||
375 | static void kauditd_send_skb(struct sk_buff *skb) | ||
376 | { | ||
377 | int err; | ||
378 | /* take a reference in case we can't send it and we want to hold it */ | ||
379 | skb_get(skb); | ||
380 | err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0); | ||
381 | if (err < 0) { | ||
382 | BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */ | ||
383 | printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid); | ||
384 | audit_log_lost("auditd dissapeared\n"); | ||
385 | audit_pid = 0; | ||
386 | /* we might get lucky and get this in the next auditd */ | ||
387 | audit_hold_skb(skb); | ||
388 | } else | ||
389 | /* drop the extra reference if sent ok */ | ||
390 | kfree_skb(skb); | ||
344 | } | 391 | } |
345 | 392 | ||
346 | static int kauditd_thread(void *dummy) | 393 | static int kauditd_thread(void *dummy) |
@@ -349,24 +396,41 @@ static int kauditd_thread(void *dummy) | |||
349 | 396 | ||
350 | set_freezable(); | 397 | set_freezable(); |
351 | while (!kthread_should_stop()) { | 398 | while (!kthread_should_stop()) { |
399 | /* | ||
400 | * if auditd just started drain the queue of messages already | ||
401 | * sent to syslog/printk. remember loss here is ok. we already | ||
402 | * called audit_log_lost() if it didn't go out normally. so the | ||
403 | * race between the skb_dequeue and the next check for audit_pid | ||
404 | * doesn't matter. | ||
405 | * | ||
406 | * if you ever find kauditd to be too slow we can get a perf win | ||
407 | * by doing our own locking and keeping better track if there | ||
408 | * are messages in this queue. I don't see the need now, but | ||
409 | * in 5 years when I want to play with this again I'll see this | ||
410 | * note and still have no friggin idea what i'm thinking today. | ||
411 | */ | ||
412 | if (audit_default && audit_pid) { | ||
413 | skb = skb_dequeue(&audit_skb_hold_queue); | ||
414 | if (unlikely(skb)) { | ||
415 | while (skb && audit_pid) { | ||
416 | kauditd_send_skb(skb); | ||
417 | skb = skb_dequeue(&audit_skb_hold_queue); | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | |||
352 | skb = skb_dequeue(&audit_skb_queue); | 422 | skb = skb_dequeue(&audit_skb_queue); |
353 | wake_up(&audit_backlog_wait); | 423 | wake_up(&audit_backlog_wait); |
354 | if (skb) { | 424 | if (skb) { |
355 | if (audit_pid) { | 425 | if (audit_pid) |
356 | int err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0); | 426 | kauditd_send_skb(skb); |
357 | if (err < 0) { | 427 | else { |
358 | BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */ | ||
359 | printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid); | ||
360 | audit_log_lost("auditd dissapeared\n"); | ||
361 | audit_pid = 0; | ||
362 | } | ||
363 | } else { | ||
364 | if (printk_ratelimit()) | 428 | if (printk_ratelimit()) |
365 | printk(KERN_NOTICE "%s\n", skb->data + | 429 | printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0)); |
366 | NLMSG_SPACE(0)); | ||
367 | else | 430 | else |
368 | audit_log_lost("printk limit exceeded\n"); | 431 | audit_log_lost("printk limit exceeded\n"); |
369 | kfree_skb(skb); | 432 | |
433 | audit_hold_skb(skb); | ||
370 | } | 434 | } |
371 | } else { | 435 | } else { |
372 | DECLARE_WAITQUEUE(wait, current); | 436 | DECLARE_WAITQUEUE(wait, current); |
@@ -385,13 +449,13 @@ static int kauditd_thread(void *dummy) | |||
385 | return 0; | 449 | return 0; |
386 | } | 450 | } |
387 | 451 | ||
388 | static int audit_prepare_user_tty(pid_t pid, uid_t loginuid) | 452 | static int audit_prepare_user_tty(pid_t pid, uid_t loginuid, u32 sessionid) |
389 | { | 453 | { |
390 | struct task_struct *tsk; | 454 | struct task_struct *tsk; |
391 | int err; | 455 | int err; |
392 | 456 | ||
393 | read_lock(&tasklist_lock); | 457 | read_lock(&tasklist_lock); |
394 | tsk = find_task_by_pid(pid); | 458 | tsk = find_task_by_vpid(pid); |
395 | err = -ESRCH; | 459 | err = -ESRCH; |
396 | if (!tsk) | 460 | if (!tsk) |
397 | goto out; | 461 | goto out; |
@@ -404,7 +468,7 @@ static int audit_prepare_user_tty(pid_t pid, uid_t loginuid) | |||
404 | if (err) | 468 | if (err) |
405 | goto out; | 469 | goto out; |
406 | 470 | ||
407 | tty_audit_push_task(tsk, loginuid); | 471 | tty_audit_push_task(tsk, loginuid, sessionid); |
408 | out: | 472 | out: |
409 | read_unlock(&tasklist_lock); | 473 | read_unlock(&tasklist_lock); |
410 | return err; | 474 | return err; |
@@ -469,6 +533,19 @@ nlmsg_failure: /* Used by NLMSG_PUT */ | |||
469 | return NULL; | 533 | return NULL; |
470 | } | 534 | } |
471 | 535 | ||
536 | static int audit_send_reply_thread(void *arg) | ||
537 | { | ||
538 | struct audit_reply *reply = (struct audit_reply *)arg; | ||
539 | |||
540 | mutex_lock(&audit_cmd_mutex); | ||
541 | mutex_unlock(&audit_cmd_mutex); | ||
542 | |||
543 | /* Ignore failure. It'll only happen if the sender goes away, | ||
544 | because our timeout is set to infinite. */ | ||
545 | netlink_unicast(audit_sock, reply->skb, reply->pid, 0); | ||
546 | kfree(reply); | ||
547 | return 0; | ||
548 | } | ||
472 | /** | 549 | /** |
473 | * audit_send_reply - send an audit reply message via netlink | 550 | * audit_send_reply - send an audit reply message via netlink |
474 | * @pid: process id to send reply to | 551 | * @pid: process id to send reply to |
@@ -485,14 +562,26 @@ nlmsg_failure: /* Used by NLMSG_PUT */ | |||
485 | void audit_send_reply(int pid, int seq, int type, int done, int multi, | 562 | void audit_send_reply(int pid, int seq, int type, int done, int multi, |
486 | void *payload, int size) | 563 | void *payload, int size) |
487 | { | 564 | { |
488 | struct sk_buff *skb; | 565 | struct sk_buff *skb; |
566 | struct task_struct *tsk; | ||
567 | struct audit_reply *reply = kmalloc(sizeof(struct audit_reply), | ||
568 | GFP_KERNEL); | ||
569 | |||
570 | if (!reply) | ||
571 | return; | ||
572 | |||
489 | skb = audit_make_reply(pid, seq, type, done, multi, payload, size); | 573 | skb = audit_make_reply(pid, seq, type, done, multi, payload, size); |
490 | if (!skb) | 574 | if (!skb) |
491 | return; | 575 | return; |
492 | /* Ignore failure. It'll only happen if the sender goes away, | 576 | |
493 | because our timeout is set to infinite. */ | 577 | reply->pid = pid; |
494 | netlink_unicast(audit_sock, skb, pid, 0); | 578 | reply->skb = skb; |
495 | return; | 579 | |
580 | tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply"); | ||
581 | if (IS_ERR(tsk)) { | ||
582 | kfree(reply); | ||
583 | kfree_skb(skb); | ||
584 | } | ||
496 | } | 585 | } |
497 | 586 | ||
498 | /* | 587 | /* |
@@ -534,7 +623,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
534 | } | 623 | } |
535 | 624 | ||
536 | static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | 625 | static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, |
537 | u32 pid, u32 uid, uid_t auid, u32 sid) | 626 | u32 pid, u32 uid, uid_t auid, u32 ses, |
627 | u32 sid) | ||
538 | { | 628 | { |
539 | int rc = 0; | 629 | int rc = 0; |
540 | char *ctx = NULL; | 630 | char *ctx = NULL; |
@@ -546,8 +636,8 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | |||
546 | } | 636 | } |
547 | 637 | ||
548 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | 638 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
549 | audit_log_format(*ab, "user pid=%d uid=%u auid=%u", | 639 | audit_log_format(*ab, "user pid=%d uid=%u auid=%u ses=%u", |
550 | pid, uid, auid); | 640 | pid, uid, auid, ses); |
551 | if (sid) { | 641 | if (sid) { |
552 | rc = security_secid_to_secctx(sid, &ctx, &len); | 642 | rc = security_secid_to_secctx(sid, &ctx, &len); |
553 | if (rc) | 643 | if (rc) |
@@ -570,6 +660,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
570 | struct audit_buffer *ab; | 660 | struct audit_buffer *ab; |
571 | u16 msg_type = nlh->nlmsg_type; | 661 | u16 msg_type = nlh->nlmsg_type; |
572 | uid_t loginuid; /* loginuid of sender */ | 662 | uid_t loginuid; /* loginuid of sender */ |
663 | u32 sessionid; | ||
573 | struct audit_sig_info *sig_data; | 664 | struct audit_sig_info *sig_data; |
574 | char *ctx = NULL; | 665 | char *ctx = NULL; |
575 | u32 len; | 666 | u32 len; |
@@ -591,6 +682,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
591 | pid = NETLINK_CREDS(skb)->pid; | 682 | pid = NETLINK_CREDS(skb)->pid; |
592 | uid = NETLINK_CREDS(skb)->uid; | 683 | uid = NETLINK_CREDS(skb)->uid; |
593 | loginuid = NETLINK_CB(skb).loginuid; | 684 | loginuid = NETLINK_CB(skb).loginuid; |
685 | sessionid = NETLINK_CB(skb).sessionid; | ||
594 | sid = NETLINK_CB(skb).sid; | 686 | sid = NETLINK_CB(skb).sid; |
595 | seq = nlh->nlmsg_seq; | 687 | seq = nlh->nlmsg_seq; |
596 | data = NLMSG_DATA(nlh); | 688 | data = NLMSG_DATA(nlh); |
@@ -613,12 +705,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
613 | status_get = (struct audit_status *)data; | 705 | status_get = (struct audit_status *)data; |
614 | if (status_get->mask & AUDIT_STATUS_ENABLED) { | 706 | if (status_get->mask & AUDIT_STATUS_ENABLED) { |
615 | err = audit_set_enabled(status_get->enabled, | 707 | err = audit_set_enabled(status_get->enabled, |
616 | loginuid, sid); | 708 | loginuid, sessionid, sid); |
617 | if (err < 0) return err; | 709 | if (err < 0) return err; |
618 | } | 710 | } |
619 | if (status_get->mask & AUDIT_STATUS_FAILURE) { | 711 | if (status_get->mask & AUDIT_STATUS_FAILURE) { |
620 | err = audit_set_failure(status_get->failure, | 712 | err = audit_set_failure(status_get->failure, |
621 | loginuid, sid); | 713 | loginuid, sessionid, sid); |
622 | if (err < 0) return err; | 714 | if (err < 0) return err; |
623 | } | 715 | } |
624 | if (status_get->mask & AUDIT_STATUS_PID) { | 716 | if (status_get->mask & AUDIT_STATUS_PID) { |
@@ -627,17 +719,17 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
627 | if (audit_enabled != AUDIT_OFF) | 719 | if (audit_enabled != AUDIT_OFF) |
628 | audit_log_config_change("audit_pid", new_pid, | 720 | audit_log_config_change("audit_pid", new_pid, |
629 | audit_pid, loginuid, | 721 | audit_pid, loginuid, |
630 | sid, 1); | 722 | sessionid, sid, 1); |
631 | 723 | ||
632 | audit_pid = new_pid; | 724 | audit_pid = new_pid; |
633 | audit_nlk_pid = NETLINK_CB(skb).pid; | 725 | audit_nlk_pid = NETLINK_CB(skb).pid; |
634 | } | 726 | } |
635 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) | 727 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) |
636 | err = audit_set_rate_limit(status_get->rate_limit, | 728 | err = audit_set_rate_limit(status_get->rate_limit, |
637 | loginuid, sid); | 729 | loginuid, sessionid, sid); |
638 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) | 730 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) |
639 | err = audit_set_backlog_limit(status_get->backlog_limit, | 731 | err = audit_set_backlog_limit(status_get->backlog_limit, |
640 | loginuid, sid); | 732 | loginuid, sessionid, sid); |
641 | break; | 733 | break; |
642 | case AUDIT_USER: | 734 | case AUDIT_USER: |
643 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: | 735 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: |
@@ -649,12 +741,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
649 | if (err == 1) { | 741 | if (err == 1) { |
650 | err = 0; | 742 | err = 0; |
651 | if (msg_type == AUDIT_USER_TTY) { | 743 | if (msg_type == AUDIT_USER_TTY) { |
652 | err = audit_prepare_user_tty(pid, loginuid); | 744 | err = audit_prepare_user_tty(pid, loginuid, |
745 | sessionid); | ||
653 | if (err) | 746 | if (err) |
654 | break; | 747 | break; |
655 | } | 748 | } |
656 | audit_log_common_recv_msg(&ab, msg_type, pid, uid, | 749 | audit_log_common_recv_msg(&ab, msg_type, pid, uid, |
657 | loginuid, sid); | 750 | loginuid, sessionid, sid); |
658 | 751 | ||
659 | if (msg_type != AUDIT_USER_TTY) | 752 | if (msg_type != AUDIT_USER_TTY) |
660 | audit_log_format(ab, " msg='%.1024s'", | 753 | audit_log_format(ab, " msg='%.1024s'", |
@@ -664,8 +757,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
664 | 757 | ||
665 | audit_log_format(ab, " msg="); | 758 | audit_log_format(ab, " msg="); |
666 | size = nlmsg_len(nlh); | 759 | size = nlmsg_len(nlh); |
667 | audit_log_n_untrustedstring(ab, size, | 760 | audit_log_n_untrustedstring(ab, data, size); |
668 | data); | ||
669 | } | 761 | } |
670 | audit_set_pid(ab, pid); | 762 | audit_set_pid(ab, pid); |
671 | audit_log_end(ab); | 763 | audit_log_end(ab); |
@@ -677,7 +769,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
677 | return -EINVAL; | 769 | return -EINVAL; |
678 | if (audit_enabled == AUDIT_LOCKED) { | 770 | if (audit_enabled == AUDIT_LOCKED) { |
679 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 771 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
680 | uid, loginuid, sid); | 772 | uid, loginuid, sessionid, sid); |
681 | 773 | ||
682 | audit_log_format(ab, " audit_enabled=%d res=0", | 774 | audit_log_format(ab, " audit_enabled=%d res=0", |
683 | audit_enabled); | 775 | audit_enabled); |
@@ -688,7 +780,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
688 | case AUDIT_LIST: | 780 | case AUDIT_LIST: |
689 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 781 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
690 | uid, seq, data, nlmsg_len(nlh), | 782 | uid, seq, data, nlmsg_len(nlh), |
691 | loginuid, sid); | 783 | loginuid, sessionid, sid); |
692 | break; | 784 | break; |
693 | case AUDIT_ADD_RULE: | 785 | case AUDIT_ADD_RULE: |
694 | case AUDIT_DEL_RULE: | 786 | case AUDIT_DEL_RULE: |
@@ -696,7 +788,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
696 | return -EINVAL; | 788 | return -EINVAL; |
697 | if (audit_enabled == AUDIT_LOCKED) { | 789 | if (audit_enabled == AUDIT_LOCKED) { |
698 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 790 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
699 | uid, loginuid, sid); | 791 | uid, loginuid, sessionid, sid); |
700 | 792 | ||
701 | audit_log_format(ab, " audit_enabled=%d res=0", | 793 | audit_log_format(ab, " audit_enabled=%d res=0", |
702 | audit_enabled); | 794 | audit_enabled); |
@@ -707,13 +799,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
707 | case AUDIT_LIST_RULES: | 799 | case AUDIT_LIST_RULES: |
708 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 800 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
709 | uid, seq, data, nlmsg_len(nlh), | 801 | uid, seq, data, nlmsg_len(nlh), |
710 | loginuid, sid); | 802 | loginuid, sessionid, sid); |
711 | break; | 803 | break; |
712 | case AUDIT_TRIM: | 804 | case AUDIT_TRIM: |
713 | audit_trim_trees(); | 805 | audit_trim_trees(); |
714 | 806 | ||
715 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 807 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
716 | uid, loginuid, sid); | 808 | uid, loginuid, sessionid, sid); |
717 | 809 | ||
718 | audit_log_format(ab, " op=trim res=1"); | 810 | audit_log_format(ab, " op=trim res=1"); |
719 | audit_log_end(ab); | 811 | audit_log_end(ab); |
@@ -721,21 +813,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
721 | case AUDIT_MAKE_EQUIV: { | 813 | case AUDIT_MAKE_EQUIV: { |
722 | void *bufp = data; | 814 | void *bufp = data; |
723 | u32 sizes[2]; | 815 | u32 sizes[2]; |
724 | size_t len = nlmsg_len(nlh); | 816 | size_t msglen = nlmsg_len(nlh); |
725 | char *old, *new; | 817 | char *old, *new; |
726 | 818 | ||
727 | err = -EINVAL; | 819 | err = -EINVAL; |
728 | if (len < 2 * sizeof(u32)) | 820 | if (msglen < 2 * sizeof(u32)) |
729 | break; | 821 | break; |
730 | memcpy(sizes, bufp, 2 * sizeof(u32)); | 822 | memcpy(sizes, bufp, 2 * sizeof(u32)); |
731 | bufp += 2 * sizeof(u32); | 823 | bufp += 2 * sizeof(u32); |
732 | len -= 2 * sizeof(u32); | 824 | msglen -= 2 * sizeof(u32); |
733 | old = audit_unpack_string(&bufp, &len, sizes[0]); | 825 | old = audit_unpack_string(&bufp, &msglen, sizes[0]); |
734 | if (IS_ERR(old)) { | 826 | if (IS_ERR(old)) { |
735 | err = PTR_ERR(old); | 827 | err = PTR_ERR(old); |
736 | break; | 828 | break; |
737 | } | 829 | } |
738 | new = audit_unpack_string(&bufp, &len, sizes[1]); | 830 | new = audit_unpack_string(&bufp, &msglen, sizes[1]); |
739 | if (IS_ERR(new)) { | 831 | if (IS_ERR(new)) { |
740 | err = PTR_ERR(new); | 832 | err = PTR_ERR(new); |
741 | kfree(old); | 833 | kfree(old); |
@@ -745,7 +837,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
745 | err = audit_tag_tree(old, new); | 837 | err = audit_tag_tree(old, new); |
746 | 838 | ||
747 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 839 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
748 | uid, loginuid, sid); | 840 | uid, loginuid, sessionid, sid); |
749 | 841 | ||
750 | audit_log_format(ab, " op=make_equiv old="); | 842 | audit_log_format(ab, " op=make_equiv old="); |
751 | audit_log_untrustedstring(ab, old); | 843 | audit_log_untrustedstring(ab, old); |
@@ -779,7 +871,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
779 | struct task_struct *tsk; | 871 | struct task_struct *tsk; |
780 | 872 | ||
781 | read_lock(&tasklist_lock); | 873 | read_lock(&tasklist_lock); |
782 | tsk = find_task_by_pid(pid); | 874 | tsk = find_task_by_vpid(pid); |
783 | if (!tsk) | 875 | if (!tsk) |
784 | err = -ESRCH; | 876 | err = -ESRCH; |
785 | else { | 877 | else { |
@@ -802,7 +894,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
802 | if (s->enabled != 0 && s->enabled != 1) | 894 | if (s->enabled != 0 && s->enabled != 1) |
803 | return -EINVAL; | 895 | return -EINVAL; |
804 | read_lock(&tasklist_lock); | 896 | read_lock(&tasklist_lock); |
805 | tsk = find_task_by_pid(pid); | 897 | tsk = find_task_by_vpid(pid); |
806 | if (!tsk) | 898 | if (!tsk) |
807 | err = -ESRCH; | 899 | err = -ESRCH; |
808 | else { | 900 | else { |
@@ -877,6 +969,7 @@ static int __init audit_init(void) | |||
877 | audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; | 969 | audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; |
878 | 970 | ||
879 | skb_queue_head_init(&audit_skb_queue); | 971 | skb_queue_head_init(&audit_skb_queue); |
972 | skb_queue_head_init(&audit_skb_hold_queue); | ||
880 | audit_initialized = 1; | 973 | audit_initialized = 1; |
881 | audit_enabled = audit_default; | 974 | audit_enabled = audit_default; |
882 | audit_ever_enabled |= !!audit_default; | 975 | audit_ever_enabled |= !!audit_default; |
@@ -1199,7 +1292,7 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) | |||
1199 | * This function will take the passed buf and convert it into a string of | 1292 | * This function will take the passed buf and convert it into a string of |
1200 | * ascii hex digits. The new string is placed onto the skb. | 1293 | * ascii hex digits. The new string is placed onto the skb. |
1201 | */ | 1294 | */ |
1202 | void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, | 1295 | void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf, |
1203 | size_t len) | 1296 | size_t len) |
1204 | { | 1297 | { |
1205 | int i, avail, new_len; | 1298 | int i, avail, new_len; |
@@ -1235,8 +1328,8 @@ void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, | |||
1235 | * Format a string of no more than slen characters into the audit buffer, | 1328 | * Format a string of no more than slen characters into the audit buffer, |
1236 | * enclosed in quote marks. | 1329 | * enclosed in quote marks. |
1237 | */ | 1330 | */ |
1238 | static void audit_log_n_string(struct audit_buffer *ab, size_t slen, | 1331 | void audit_log_n_string(struct audit_buffer *ab, const char *string, |
1239 | const char *string) | 1332 | size_t slen) |
1240 | { | 1333 | { |
1241 | int avail, new_len; | 1334 | int avail, new_len; |
1242 | unsigned char *ptr; | 1335 | unsigned char *ptr; |
@@ -1292,13 +1385,13 @@ int audit_string_contains_control(const char *string, size_t len) | |||
1292 | * The caller specifies the number of characters in the string to log, which may | 1385 | * The caller specifies the number of characters in the string to log, which may |
1293 | * or may not be the entire string. | 1386 | * or may not be the entire string. |
1294 | */ | 1387 | */ |
1295 | void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len, | 1388 | void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string, |
1296 | const char *string) | 1389 | size_t len) |
1297 | { | 1390 | { |
1298 | if (audit_string_contains_control(string, len)) | 1391 | if (audit_string_contains_control(string, len)) |
1299 | audit_log_hex(ab, string, len); | 1392 | audit_log_n_hex(ab, string, len); |
1300 | else | 1393 | else |
1301 | audit_log_n_string(ab, len, string); | 1394 | audit_log_n_string(ab, string, len); |
1302 | } | 1395 | } |
1303 | 1396 | ||
1304 | /** | 1397 | /** |
@@ -1311,7 +1404,7 @@ void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len, | |||
1311 | */ | 1404 | */ |
1312 | void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) | 1405 | void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) |
1313 | { | 1406 | { |
1314 | audit_log_n_untrustedstring(ab, strlen(string), string); | 1407 | audit_log_n_untrustedstring(ab, string, strlen(string)); |
1315 | } | 1408 | } |
1316 | 1409 | ||
1317 | /* This is a helper-function to print the escaped d_path */ | 1410 | /* This is a helper-function to print the escaped d_path */ |
@@ -1355,19 +1448,23 @@ void audit_log_end(struct audit_buffer *ab) | |||
1355 | audit_log_lost("rate limit exceeded"); | 1448 | audit_log_lost("rate limit exceeded"); |
1356 | } else { | 1449 | } else { |
1357 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); | 1450 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); |
1451 | nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0); | ||
1452 | |||
1358 | if (audit_pid) { | 1453 | if (audit_pid) { |
1359 | nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0); | ||
1360 | skb_queue_tail(&audit_skb_queue, ab->skb); | 1454 | skb_queue_tail(&audit_skb_queue, ab->skb); |
1361 | ab->skb = NULL; | ||
1362 | wake_up_interruptible(&kauditd_wait); | 1455 | wake_up_interruptible(&kauditd_wait); |
1363 | } else if (nlh->nlmsg_type != AUDIT_EOE) { | 1456 | } else { |
1364 | if (printk_ratelimit()) { | 1457 | if (nlh->nlmsg_type != AUDIT_EOE) { |
1365 | printk(KERN_NOTICE "type=%d %s\n", | 1458 | if (printk_ratelimit()) { |
1366 | nlh->nlmsg_type, | 1459 | printk(KERN_NOTICE "type=%d %s\n", |
1367 | ab->skb->data + NLMSG_SPACE(0)); | 1460 | nlh->nlmsg_type, |
1368 | } else | 1461 | ab->skb->data + NLMSG_SPACE(0)); |
1369 | audit_log_lost("printk limit exceeded\n"); | 1462 | } else |
1463 | audit_log_lost("printk limit exceeded\n"); | ||
1464 | } | ||
1465 | audit_hold_skb(ab->skb); | ||
1370 | } | 1466 | } |
1467 | ab->skb = NULL; | ||
1371 | } | 1468 | } |
1372 | audit_buffer_free(ab); | 1469 | audit_buffer_free(ab); |
1373 | } | 1470 | } |
diff --git a/kernel/audit.h b/kernel/audit.h index 3cfc54ee3e1f..9d6717412fec 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
@@ -74,6 +74,11 @@ struct audit_entry { | |||
74 | struct audit_krule rule; | 74 | struct audit_krule rule; |
75 | }; | 75 | }; |
76 | 76 | ||
77 | #ifdef CONFIG_AUDIT | ||
78 | extern int audit_enabled; | ||
79 | extern int audit_ever_enabled; | ||
80 | #endif | ||
81 | |||
77 | extern int audit_pid; | 82 | extern int audit_pid; |
78 | 83 | ||
79 | #define AUDIT_INODE_BUCKETS 32 | 84 | #define AUDIT_INODE_BUCKETS 32 |
@@ -104,6 +109,9 @@ struct audit_netlink_list { | |||
104 | int audit_send_list(void *); | 109 | int audit_send_list(void *); |
105 | 110 | ||
106 | struct inotify_watch; | 111 | struct inotify_watch; |
112 | /* Inotify handle */ | ||
113 | extern struct inotify_handle *audit_ih; | ||
114 | |||
107 | extern void audit_free_parent(struct inotify_watch *); | 115 | extern void audit_free_parent(struct inotify_watch *); |
108 | extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32, | 116 | extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32, |
109 | const char *, struct inode *); | 117 | const char *, struct inode *); |
@@ -111,6 +119,7 @@ extern int selinux_audit_rule_update(void); | |||
111 | 119 | ||
112 | extern struct mutex audit_filter_mutex; | 120 | extern struct mutex audit_filter_mutex; |
113 | extern void audit_free_rule_rcu(struct rcu_head *); | 121 | extern void audit_free_rule_rcu(struct rcu_head *); |
122 | extern struct list_head audit_filter_list[]; | ||
114 | 123 | ||
115 | #ifdef CONFIG_AUDIT_TREE | 124 | #ifdef CONFIG_AUDIT_TREE |
116 | extern struct audit_chunk *audit_tree_lookup(const struct inode *); | 125 | extern struct audit_chunk *audit_tree_lookup(const struct inode *); |
@@ -137,6 +146,10 @@ extern void audit_put_tree(struct audit_tree *); | |||
137 | 146 | ||
138 | extern char *audit_unpack_string(void **, size_t *, size_t); | 147 | extern char *audit_unpack_string(void **, size_t *, size_t); |
139 | 148 | ||
149 | extern pid_t audit_sig_pid; | ||
150 | extern uid_t audit_sig_uid; | ||
151 | extern u32 audit_sig_sid; | ||
152 | |||
140 | #ifdef CONFIG_AUDITSYSCALL | 153 | #ifdef CONFIG_AUDITSYSCALL |
141 | extern int __audit_signal_info(int sig, struct task_struct *t); | 154 | extern int __audit_signal_info(int sig, struct task_struct *t); |
142 | static inline int audit_signal_info(int sig, struct task_struct *t) | 155 | static inline int audit_signal_info(int sig, struct task_struct *t) |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 13430176b3c9..0e0bd27e6512 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -89,14 +89,9 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = { | |||
89 | 89 | ||
90 | DEFINE_MUTEX(audit_filter_mutex); | 90 | DEFINE_MUTEX(audit_filter_mutex); |
91 | 91 | ||
92 | /* Inotify handle */ | ||
93 | extern struct inotify_handle *audit_ih; | ||
94 | |||
95 | /* Inotify events we care about. */ | 92 | /* Inotify events we care about. */ |
96 | #define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF | 93 | #define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF |
97 | 94 | ||
98 | extern int audit_enabled; | ||
99 | |||
100 | void audit_free_parent(struct inotify_watch *i_watch) | 95 | void audit_free_parent(struct inotify_watch *i_watch) |
101 | { | 96 | { |
102 | struct audit_parent *parent; | 97 | struct audit_parent *parent; |
@@ -422,7 +417,7 @@ exit_err: | |||
422 | static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | 417 | static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) |
423 | { | 418 | { |
424 | struct audit_entry *entry; | 419 | struct audit_entry *entry; |
425 | struct audit_field *f; | 420 | struct audit_field *ino_f; |
426 | int err = 0; | 421 | int err = 0; |
427 | int i; | 422 | int i; |
428 | 423 | ||
@@ -483,6 +478,10 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | |||
483 | if (f->val & ~15) | 478 | if (f->val & ~15) |
484 | goto exit_free; | 479 | goto exit_free; |
485 | break; | 480 | break; |
481 | case AUDIT_FILETYPE: | ||
482 | if ((f->val & ~S_IFMT) > S_IFMT) | ||
483 | goto exit_free; | ||
484 | break; | ||
486 | case AUDIT_INODE: | 485 | case AUDIT_INODE: |
487 | err = audit_to_inode(&entry->rule, f); | 486 | err = audit_to_inode(&entry->rule, f); |
488 | if (err) | 487 | if (err) |
@@ -504,9 +503,9 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | |||
504 | } | 503 | } |
505 | } | 504 | } |
506 | 505 | ||
507 | f = entry->rule.inode_f; | 506 | ino_f = entry->rule.inode_f; |
508 | if (f) { | 507 | if (ino_f) { |
509 | switch(f->op) { | 508 | switch(ino_f->op) { |
510 | case AUDIT_NOT_EQUAL: | 509 | case AUDIT_NOT_EQUAL: |
511 | entry->rule.inode_f = NULL; | 510 | entry->rule.inode_f = NULL; |
512 | case AUDIT_EQUAL: | 511 | case AUDIT_EQUAL: |
@@ -531,7 +530,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
531 | { | 530 | { |
532 | int err = 0; | 531 | int err = 0; |
533 | struct audit_entry *entry; | 532 | struct audit_entry *entry; |
534 | struct audit_field *f; | 533 | struct audit_field *ino_f; |
535 | void *bufp; | 534 | void *bufp; |
536 | size_t remain = datasz - sizeof(struct audit_rule_data); | 535 | size_t remain = datasz - sizeof(struct audit_rule_data); |
537 | int i; | 536 | int i; |
@@ -654,14 +653,18 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
654 | if (f->val & ~15) | 653 | if (f->val & ~15) |
655 | goto exit_free; | 654 | goto exit_free; |
656 | break; | 655 | break; |
656 | case AUDIT_FILETYPE: | ||
657 | if ((f->val & ~S_IFMT) > S_IFMT) | ||
658 | goto exit_free; | ||
659 | break; | ||
657 | default: | 660 | default: |
658 | goto exit_free; | 661 | goto exit_free; |
659 | } | 662 | } |
660 | } | 663 | } |
661 | 664 | ||
662 | f = entry->rule.inode_f; | 665 | ino_f = entry->rule.inode_f; |
663 | if (f) { | 666 | if (ino_f) { |
664 | switch(f->op) { | 667 | switch(ino_f->op) { |
665 | case AUDIT_NOT_EQUAL: | 668 | case AUDIT_NOT_EQUAL: |
666 | entry->rule.inode_f = NULL; | 669 | entry->rule.inode_f = NULL; |
667 | case AUDIT_EQUAL: | 670 | case AUDIT_EQUAL: |
@@ -1500,8 +1503,9 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) | |||
1500 | } | 1503 | } |
1501 | 1504 | ||
1502 | /* Log rule additions and removals */ | 1505 | /* Log rule additions and removals */ |
1503 | static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | 1506 | static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid, |
1504 | struct audit_krule *rule, int res) | 1507 | char *action, struct audit_krule *rule, |
1508 | int res) | ||
1505 | { | 1509 | { |
1506 | struct audit_buffer *ab; | 1510 | struct audit_buffer *ab; |
1507 | 1511 | ||
@@ -1511,7 +1515,7 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | |||
1511 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 1515 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
1512 | if (!ab) | 1516 | if (!ab) |
1513 | return; | 1517 | return; |
1514 | audit_log_format(ab, "auid=%u", loginuid); | 1518 | audit_log_format(ab, "auid=%u ses=%u", loginuid, sessionid); |
1515 | if (sid) { | 1519 | if (sid) { |
1516 | char *ctx = NULL; | 1520 | char *ctx = NULL; |
1517 | u32 len; | 1521 | u32 len; |
@@ -1543,7 +1547,7 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | |||
1543 | * @sid: SE Linux Security ID of sender | 1547 | * @sid: SE Linux Security ID of sender |
1544 | */ | 1548 | */ |
1545 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | 1549 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, |
1546 | size_t datasz, uid_t loginuid, u32 sid) | 1550 | size_t datasz, uid_t loginuid, u32 sessionid, u32 sid) |
1547 | { | 1551 | { |
1548 | struct task_struct *tsk; | 1552 | struct task_struct *tsk; |
1549 | struct audit_netlink_list *dest; | 1553 | struct audit_netlink_list *dest; |
@@ -1590,7 +1594,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
1590 | 1594 | ||
1591 | err = audit_add_rule(entry, | 1595 | err = audit_add_rule(entry, |
1592 | &audit_filter_list[entry->rule.listnr]); | 1596 | &audit_filter_list[entry->rule.listnr]); |
1593 | audit_log_rule_change(loginuid, sid, "add", &entry->rule, !err); | 1597 | audit_log_rule_change(loginuid, sessionid, sid, "add", |
1598 | &entry->rule, !err); | ||
1594 | 1599 | ||
1595 | if (err) | 1600 | if (err) |
1596 | audit_free_rule(entry); | 1601 | audit_free_rule(entry); |
@@ -1606,8 +1611,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
1606 | 1611 | ||
1607 | err = audit_del_rule(entry, | 1612 | err = audit_del_rule(entry, |
1608 | &audit_filter_list[entry->rule.listnr]); | 1613 | &audit_filter_list[entry->rule.listnr]); |
1609 | audit_log_rule_change(loginuid, sid, "remove", &entry->rule, | 1614 | audit_log_rule_change(loginuid, sessionid, sid, "remove", |
1610 | !err); | 1615 | &entry->rule, !err); |
1611 | 1616 | ||
1612 | audit_free_rule(entry); | 1617 | audit_free_rule(entry); |
1613 | break; | 1618 | break; |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 56e56ed594a8..c10e7aae04d7 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -68,9 +68,6 @@ | |||
68 | 68 | ||
69 | #include "audit.h" | 69 | #include "audit.h" |
70 | 70 | ||
71 | extern struct list_head audit_filter_list[]; | ||
72 | extern int audit_ever_enabled; | ||
73 | |||
74 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context | 71 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context |
75 | * for saving names from getname(). */ | 72 | * for saving names from getname(). */ |
76 | #define AUDIT_NAMES 20 | 73 | #define AUDIT_NAMES 20 |
@@ -283,6 +280,19 @@ static int audit_match_perm(struct audit_context *ctx, int mask) | |||
283 | } | 280 | } |
284 | } | 281 | } |
285 | 282 | ||
283 | static int audit_match_filetype(struct audit_context *ctx, int which) | ||
284 | { | ||
285 | unsigned index = which & ~S_IFMT; | ||
286 | mode_t mode = which & S_IFMT; | ||
287 | if (index >= ctx->name_count) | ||
288 | return 0; | ||
289 | if (ctx->names[index].ino == -1) | ||
290 | return 0; | ||
291 | if ((ctx->names[index].mode ^ mode) & S_IFMT) | ||
292 | return 0; | ||
293 | return 1; | ||
294 | } | ||
295 | |||
286 | /* | 296 | /* |
287 | * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *; | 297 | * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *; |
288 | * ->first_trees points to its beginning, ->trees - to the current end of data. | 298 | * ->first_trees points to its beginning, ->trees - to the current end of data. |
@@ -592,6 +602,9 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
592 | case AUDIT_PERM: | 602 | case AUDIT_PERM: |
593 | result = audit_match_perm(ctx, f->val); | 603 | result = audit_match_perm(ctx, f->val); |
594 | break; | 604 | break; |
605 | case AUDIT_FILETYPE: | ||
606 | result = audit_match_filetype(ctx, f->val); | ||
607 | break; | ||
595 | } | 608 | } |
596 | 609 | ||
597 | if (!result) | 610 | if (!result) |
@@ -1095,7 +1108,7 @@ static int audit_log_single_execve_arg(struct audit_context *context, | |||
1095 | audit_log_format(*ab, "[%d]", i); | 1108 | audit_log_format(*ab, "[%d]", i); |
1096 | audit_log_format(*ab, "="); | 1109 | audit_log_format(*ab, "="); |
1097 | if (has_cntl) | 1110 | if (has_cntl) |
1098 | audit_log_hex(*ab, buf, to_send); | 1111 | audit_log_n_hex(*ab, buf, to_send); |
1099 | else | 1112 | else |
1100 | audit_log_format(*ab, "\"%s\"", buf); | 1113 | audit_log_format(*ab, "\"%s\"", buf); |
1101 | audit_log_format(*ab, "\n"); | 1114 | audit_log_format(*ab, "\n"); |
@@ -1296,7 +1309,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1296 | break; } | 1309 | break; } |
1297 | 1310 | ||
1298 | case AUDIT_SOCKETCALL: { | 1311 | case AUDIT_SOCKETCALL: { |
1299 | int i; | ||
1300 | struct audit_aux_data_socketcall *axs = (void *)aux; | 1312 | struct audit_aux_data_socketcall *axs = (void *)aux; |
1301 | audit_log_format(ab, "nargs=%d", axs->nargs); | 1313 | audit_log_format(ab, "nargs=%d", axs->nargs); |
1302 | for (i=0; i<axs->nargs; i++) | 1314 | for (i=0; i<axs->nargs; i++) |
@@ -1307,7 +1319,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1307 | struct audit_aux_data_sockaddr *axs = (void *)aux; | 1319 | struct audit_aux_data_sockaddr *axs = (void *)aux; |
1308 | 1320 | ||
1309 | audit_log_format(ab, "saddr="); | 1321 | audit_log_format(ab, "saddr="); |
1310 | audit_log_hex(ab, axs->a, axs->len); | 1322 | audit_log_n_hex(ab, axs->a, axs->len); |
1311 | break; } | 1323 | break; } |
1312 | 1324 | ||
1313 | case AUDIT_FD_PAIR: { | 1325 | case AUDIT_FD_PAIR: { |
@@ -1321,7 +1333,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1321 | 1333 | ||
1322 | for (aux = context->aux_pids; aux; aux = aux->next) { | 1334 | for (aux = context->aux_pids; aux; aux = aux->next) { |
1323 | struct audit_aux_data_pids *axs = (void *)aux; | 1335 | struct audit_aux_data_pids *axs = (void *)aux; |
1324 | int i; | ||
1325 | 1336 | ||
1326 | for (i = 0; i < axs->pid_count; i++) | 1337 | for (i = 0; i < axs->pid_count; i++) |
1327 | if (audit_log_pid_context(context, axs->target_pid[i], | 1338 | if (audit_log_pid_context(context, axs->target_pid[i], |
@@ -1371,8 +1382,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1371 | default: | 1382 | default: |
1372 | /* log the name's directory component */ | 1383 | /* log the name's directory component */ |
1373 | audit_log_format(ab, " name="); | 1384 | audit_log_format(ab, " name="); |
1374 | audit_log_n_untrustedstring(ab, n->name_len, | 1385 | audit_log_n_untrustedstring(ab, n->name, |
1375 | n->name); | 1386 | n->name_len); |
1376 | } | 1387 | } |
1377 | } else | 1388 | } else |
1378 | audit_log_format(ab, " name=(null)"); | 1389 | audit_log_format(ab, " name=(null)"); |
@@ -1596,7 +1607,7 @@ static inline void handle_one(const struct inode *inode) | |||
1596 | if (likely(put_tree_ref(context, chunk))) | 1607 | if (likely(put_tree_ref(context, chunk))) |
1597 | return; | 1608 | return; |
1598 | if (unlikely(!grow_tree_refs(context))) { | 1609 | if (unlikely(!grow_tree_refs(context))) { |
1599 | printk(KERN_WARNING "out of memory, audit has lost a tree reference"); | 1610 | printk(KERN_WARNING "out of memory, audit has lost a tree reference\n"); |
1600 | audit_set_auditable(context); | 1611 | audit_set_auditable(context); |
1601 | audit_put_chunk(chunk); | 1612 | audit_put_chunk(chunk); |
1602 | unroll_tree_refs(context, p, count); | 1613 | unroll_tree_refs(context, p, count); |
@@ -1656,7 +1667,7 @@ retry: | |||
1656 | } | 1667 | } |
1657 | /* too bad */ | 1668 | /* too bad */ |
1658 | printk(KERN_WARNING | 1669 | printk(KERN_WARNING |
1659 | "out of memory, audit has lost a tree reference"); | 1670 | "out of memory, audit has lost a tree reference\n"); |
1660 | unroll_tree_refs(context, p, count); | 1671 | unroll_tree_refs(context, p, count); |
1661 | audit_set_auditable(context); | 1672 | audit_set_auditable(context); |
1662 | return; | 1673 | return; |
@@ -1752,13 +1763,13 @@ static int audit_inc_name_count(struct audit_context *context, | |||
1752 | if (context->name_count >= AUDIT_NAMES) { | 1763 | if (context->name_count >= AUDIT_NAMES) { |
1753 | if (inode) | 1764 | if (inode) |
1754 | printk(KERN_DEBUG "name_count maxed, losing inode data: " | 1765 | printk(KERN_DEBUG "name_count maxed, losing inode data: " |
1755 | "dev=%02x:%02x, inode=%lu", | 1766 | "dev=%02x:%02x, inode=%lu\n", |
1756 | MAJOR(inode->i_sb->s_dev), | 1767 | MAJOR(inode->i_sb->s_dev), |
1757 | MINOR(inode->i_sb->s_dev), | 1768 | MINOR(inode->i_sb->s_dev), |
1758 | inode->i_ino); | 1769 | inode->i_ino); |
1759 | 1770 | ||
1760 | else | 1771 | else |
1761 | printk(KERN_DEBUG "name_count maxed, losing inode data"); | 1772 | printk(KERN_DEBUG "name_count maxed, losing inode data\n"); |
1762 | return 1; | 1773 | return 1; |
1763 | } | 1774 | } |
1764 | context->name_count++; | 1775 | context->name_count++; |
@@ -2361,9 +2372,6 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2361 | struct audit_aux_data_pids *axp; | 2372 | struct audit_aux_data_pids *axp; |
2362 | struct task_struct *tsk = current; | 2373 | struct task_struct *tsk = current; |
2363 | struct audit_context *ctx = tsk->audit_context; | 2374 | struct audit_context *ctx = tsk->audit_context; |
2364 | extern pid_t audit_sig_pid; | ||
2365 | extern uid_t audit_sig_uid; | ||
2366 | extern u32 audit_sig_sid; | ||
2367 | 2375 | ||
2368 | if (audit_pid && t->tgid == audit_pid) { | 2376 | if (audit_pid && t->tgid == audit_pid) { |
2369 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { | 2377 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 2403a31fe0f6..9e7236ff6bcc 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -1498,7 +1498,8 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, | |||
1498 | err = xfrm_state_update(x); | 1498 | err = xfrm_state_update(x); |
1499 | 1499 | ||
1500 | xfrm_audit_state_add(x, err ? 0 : 1, | 1500 | xfrm_audit_state_add(x, err ? 0 : 1, |
1501 | audit_get_loginuid(current), 0); | 1501 | audit_get_loginuid(current), |
1502 | audit_get_sessionid(current), 0); | ||
1502 | 1503 | ||
1503 | if (err < 0) { | 1504 | if (err < 0) { |
1504 | x->km.state = XFRM_STATE_DEAD; | 1505 | x->km.state = XFRM_STATE_DEAD; |
@@ -1552,7 +1553,8 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
1552 | km_state_notify(x, &c); | 1553 | km_state_notify(x, &c); |
1553 | out: | 1554 | out: |
1554 | xfrm_audit_state_delete(x, err ? 0 : 1, | 1555 | xfrm_audit_state_delete(x, err ? 0 : 1, |
1555 | audit_get_loginuid(current), 0); | 1556 | audit_get_loginuid(current), |
1557 | audit_get_sessionid(current), 0); | ||
1556 | xfrm_state_put(x); | 1558 | xfrm_state_put(x); |
1557 | 1559 | ||
1558 | return err; | 1560 | return err; |
@@ -1728,6 +1730,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
1728 | return -EINVAL; | 1730 | return -EINVAL; |
1729 | 1731 | ||
1730 | audit_info.loginuid = audit_get_loginuid(current); | 1732 | audit_info.loginuid = audit_get_loginuid(current); |
1733 | audit_info.sessionid = audit_get_sessionid(current); | ||
1731 | audit_info.secid = 0; | 1734 | audit_info.secid = 0; |
1732 | err = xfrm_state_flush(proto, &audit_info); | 1735 | err = xfrm_state_flush(proto, &audit_info); |
1733 | if (err) | 1736 | if (err) |
@@ -2324,7 +2327,8 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2324 | hdr->sadb_msg_type != SADB_X_SPDUPDATE); | 2327 | hdr->sadb_msg_type != SADB_X_SPDUPDATE); |
2325 | 2328 | ||
2326 | xfrm_audit_policy_add(xp, err ? 0 : 1, | 2329 | xfrm_audit_policy_add(xp, err ? 0 : 1, |
2327 | audit_get_loginuid(current), 0); | 2330 | audit_get_loginuid(current), |
2331 | audit_get_sessionid(current), 0); | ||
2328 | 2332 | ||
2329 | if (err) | 2333 | if (err) |
2330 | goto out; | 2334 | goto out; |
@@ -2406,7 +2410,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2406 | return -ENOENT; | 2410 | return -ENOENT; |
2407 | 2411 | ||
2408 | xfrm_audit_policy_delete(xp, err ? 0 : 1, | 2412 | xfrm_audit_policy_delete(xp, err ? 0 : 1, |
2409 | audit_get_loginuid(current), 0); | 2413 | audit_get_loginuid(current), |
2414 | audit_get_sessionid(current), 0); | ||
2410 | 2415 | ||
2411 | if (err) | 2416 | if (err) |
2412 | goto out; | 2417 | goto out; |
@@ -2667,7 +2672,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2667 | 2672 | ||
2668 | if (delete) { | 2673 | if (delete) { |
2669 | xfrm_audit_policy_delete(xp, err ? 0 : 1, | 2674 | xfrm_audit_policy_delete(xp, err ? 0 : 1, |
2670 | audit_get_loginuid(current), 0); | 2675 | audit_get_loginuid(current), |
2676 | audit_get_sessionid(current), 0); | ||
2671 | 2677 | ||
2672 | if (err) | 2678 | if (err) |
2673 | goto out; | 2679 | goto out; |
@@ -2767,6 +2773,7 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2767 | int err; | 2773 | int err; |
2768 | 2774 | ||
2769 | audit_info.loginuid = audit_get_loginuid(current); | 2775 | audit_info.loginuid = audit_get_loginuid(current); |
2776 | audit_info.sessionid = audit_get_sessionid(current); | ||
2770 | audit_info.secid = 0; | 2777 | audit_info.secid = 0; |
2771 | err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); | 2778 | err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); |
2772 | if (err) | 2779 | if (err) |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index d282ad1570a7..0099da5b2591 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -1780,6 +1780,7 @@ int __init netlbl_unlabel_defconf(void) | |||
1780 | * messages so don't worry to much about these values. */ | 1780 | * messages so don't worry to much about these values. */ |
1781 | security_task_getsecid(current, &audit_info.secid); | 1781 | security_task_getsecid(current, &audit_info.secid); |
1782 | audit_info.loginuid = 0; | 1782 | audit_info.loginuid = 0; |
1783 | audit_info.sessionid = 0; | ||
1783 | 1784 | ||
1784 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | 1785 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
1785 | if (entry == NULL) | 1786 | if (entry == NULL) |
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index b17d4203806e..68706b4e3bf8 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c | |||
@@ -107,7 +107,9 @@ struct audit_buffer *netlbl_audit_start_common(int type, | |||
107 | if (audit_buf == NULL) | 107 | if (audit_buf == NULL) |
108 | return NULL; | 108 | return NULL; |
109 | 109 | ||
110 | audit_log_format(audit_buf, "netlabel: auid=%u", audit_info->loginuid); | 110 | audit_log_format(audit_buf, "netlabel: auid=%u ses=%u", |
111 | audit_info->loginuid, | ||
112 | audit_info->sessionid); | ||
111 | 113 | ||
112 | if (audit_info->secid != 0 && | 114 | if (audit_info->secid != 0 && |
113 | security_secid_to_secctx(audit_info->secid, | 115 | security_secid_to_secctx(audit_info->secid, |
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index 6d7f4ab46c2b..6caef8b20611 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h | |||
@@ -51,6 +51,7 @@ static inline void netlbl_netlink_auditinfo(struct sk_buff *skb, | |||
51 | { | 51 | { |
52 | audit_info->secid = NETLINK_CB(skb).sid; | 52 | audit_info->secid = NETLINK_CB(skb).sid; |
53 | audit_info->loginuid = NETLINK_CB(skb).loginuid; | 53 | audit_info->loginuid = NETLINK_CB(skb).loginuid; |
54 | audit_info->sessionid = NETLINK_CB(skb).sessionid; | ||
54 | } | 55 | } |
55 | 56 | ||
56 | /* NetLabel NETLINK I/O functions */ | 57 | /* NetLabel NETLINK I/O functions */ |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 46f3e44bb83a..9b97f8006c9c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1248,6 +1248,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1248 | NETLINK_CB(skb).pid = nlk->pid; | 1248 | NETLINK_CB(skb).pid = nlk->pid; |
1249 | NETLINK_CB(skb).dst_group = dst_group; | 1249 | NETLINK_CB(skb).dst_group = dst_group; |
1250 | NETLINK_CB(skb).loginuid = audit_get_loginuid(current); | 1250 | NETLINK_CB(skb).loginuid = audit_get_loginuid(current); |
1251 | NETLINK_CB(skb).sessionid = audit_get_sessionid(current); | ||
1251 | security_task_getsecid(current, &(NETLINK_CB(skb).sid)); | 1252 | security_task_getsecid(current, &(NETLINK_CB(skb).sid)); |
1252 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); | 1253 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); |
1253 | 1254 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index e0c0390613c0..cae9fd815543 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -762,6 +762,7 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | |||
762 | if (err) { | 762 | if (err) { |
763 | xfrm_audit_policy_delete(pol, 0, | 763 | xfrm_audit_policy_delete(pol, 0, |
764 | audit_info->loginuid, | 764 | audit_info->loginuid, |
765 | audit_info->sessionid, | ||
765 | audit_info->secid); | 766 | audit_info->secid); |
766 | return err; | 767 | return err; |
767 | } | 768 | } |
@@ -777,6 +778,7 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | |||
777 | if (err) { | 778 | if (err) { |
778 | xfrm_audit_policy_delete(pol, 0, | 779 | xfrm_audit_policy_delete(pol, 0, |
779 | audit_info->loginuid, | 780 | audit_info->loginuid, |
781 | audit_info->sessionid, | ||
780 | audit_info->secid); | 782 | audit_info->secid); |
781 | return err; | 783 | return err; |
782 | } | 784 | } |
@@ -819,6 +821,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | |||
819 | write_unlock_bh(&xfrm_policy_lock); | 821 | write_unlock_bh(&xfrm_policy_lock); |
820 | 822 | ||
821 | xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, | 823 | xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, |
824 | audit_info->sessionid, | ||
822 | audit_info->secid); | 825 | audit_info->secid); |
823 | 826 | ||
824 | xfrm_policy_kill(pol); | 827 | xfrm_policy_kill(pol); |
@@ -841,6 +844,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | |||
841 | 844 | ||
842 | xfrm_audit_policy_delete(pol, 1, | 845 | xfrm_audit_policy_delete(pol, 1, |
843 | audit_info->loginuid, | 846 | audit_info->loginuid, |
847 | audit_info->sessionid, | ||
844 | audit_info->secid); | 848 | audit_info->secid); |
845 | xfrm_policy_kill(pol); | 849 | xfrm_policy_kill(pol); |
846 | killed++; | 850 | killed++; |
@@ -2472,14 +2476,14 @@ static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp, | |||
2472 | } | 2476 | } |
2473 | 2477 | ||
2474 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | 2478 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, |
2475 | u32 auid, u32 secid) | 2479 | uid_t auid, u32 sessionid, u32 secid) |
2476 | { | 2480 | { |
2477 | struct audit_buffer *audit_buf; | 2481 | struct audit_buffer *audit_buf; |
2478 | 2482 | ||
2479 | audit_buf = xfrm_audit_start("SPD-add"); | 2483 | audit_buf = xfrm_audit_start("SPD-add"); |
2480 | if (audit_buf == NULL) | 2484 | if (audit_buf == NULL) |
2481 | return; | 2485 | return; |
2482 | xfrm_audit_helper_usrinfo(auid, secid, audit_buf); | 2486 | xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf); |
2483 | audit_log_format(audit_buf, " res=%u", result); | 2487 | audit_log_format(audit_buf, " res=%u", result); |
2484 | xfrm_audit_common_policyinfo(xp, audit_buf); | 2488 | xfrm_audit_common_policyinfo(xp, audit_buf); |
2485 | audit_log_end(audit_buf); | 2489 | audit_log_end(audit_buf); |
@@ -2487,14 +2491,14 @@ void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | |||
2487 | EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); | 2491 | EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); |
2488 | 2492 | ||
2489 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, | 2493 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, |
2490 | u32 auid, u32 secid) | 2494 | uid_t auid, u32 sessionid, u32 secid) |
2491 | { | 2495 | { |
2492 | struct audit_buffer *audit_buf; | 2496 | struct audit_buffer *audit_buf; |
2493 | 2497 | ||
2494 | audit_buf = xfrm_audit_start("SPD-delete"); | 2498 | audit_buf = xfrm_audit_start("SPD-delete"); |
2495 | if (audit_buf == NULL) | 2499 | if (audit_buf == NULL) |
2496 | return; | 2500 | return; |
2497 | xfrm_audit_helper_usrinfo(auid, secid, audit_buf); | 2501 | xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf); |
2498 | audit_log_format(audit_buf, " res=%u", result); | 2502 | audit_log_format(audit_buf, " res=%u", result); |
2499 | xfrm_audit_common_policyinfo(xp, audit_buf); | 2503 | xfrm_audit_common_policyinfo(xp, audit_buf); |
2500 | audit_log_end(audit_buf); | 2504 | audit_log_end(audit_buf); |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index fac27ce770d5..72fddafd891a 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -496,7 +496,8 @@ expired: | |||
496 | km_state_expired(x, 1, 0); | 496 | km_state_expired(x, 1, 0); |
497 | 497 | ||
498 | xfrm_audit_state_delete(x, err ? 0 : 1, | 498 | xfrm_audit_state_delete(x, err ? 0 : 1, |
499 | audit_get_loginuid(current), 0); | 499 | audit_get_loginuid(current), |
500 | audit_get_sessionid(current), 0); | ||
500 | 501 | ||
501 | out: | 502 | out: |
502 | spin_unlock(&x->lock); | 503 | spin_unlock(&x->lock); |
@@ -603,6 +604,7 @@ xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | |||
603 | (err = security_xfrm_state_delete(x)) != 0) { | 604 | (err = security_xfrm_state_delete(x)) != 0) { |
604 | xfrm_audit_state_delete(x, 0, | 605 | xfrm_audit_state_delete(x, 0, |
605 | audit_info->loginuid, | 606 | audit_info->loginuid, |
607 | audit_info->sessionid, | ||
606 | audit_info->secid); | 608 | audit_info->secid); |
607 | return err; | 609 | return err; |
608 | } | 610 | } |
@@ -641,6 +643,7 @@ restart: | |||
641 | err = xfrm_state_delete(x); | 643 | err = xfrm_state_delete(x); |
642 | xfrm_audit_state_delete(x, err ? 0 : 1, | 644 | xfrm_audit_state_delete(x, err ? 0 : 1, |
643 | audit_info->loginuid, | 645 | audit_info->loginuid, |
646 | audit_info->sessionid, | ||
644 | audit_info->secid); | 647 | audit_info->secid); |
645 | xfrm_state_put(x); | 648 | xfrm_state_put(x); |
646 | 649 | ||
@@ -2123,14 +2126,14 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family, | |||
2123 | } | 2126 | } |
2124 | 2127 | ||
2125 | void xfrm_audit_state_add(struct xfrm_state *x, int result, | 2128 | void xfrm_audit_state_add(struct xfrm_state *x, int result, |
2126 | u32 auid, u32 secid) | 2129 | uid_t auid, u32 sessionid, u32 secid) |
2127 | { | 2130 | { |
2128 | struct audit_buffer *audit_buf; | 2131 | struct audit_buffer *audit_buf; |
2129 | 2132 | ||
2130 | audit_buf = xfrm_audit_start("SAD-add"); | 2133 | audit_buf = xfrm_audit_start("SAD-add"); |
2131 | if (audit_buf == NULL) | 2134 | if (audit_buf == NULL) |
2132 | return; | 2135 | return; |
2133 | xfrm_audit_helper_usrinfo(auid, secid, audit_buf); | 2136 | xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf); |
2134 | xfrm_audit_helper_sainfo(x, audit_buf); | 2137 | xfrm_audit_helper_sainfo(x, audit_buf); |
2135 | audit_log_format(audit_buf, " res=%u", result); | 2138 | audit_log_format(audit_buf, " res=%u", result); |
2136 | audit_log_end(audit_buf); | 2139 | audit_log_end(audit_buf); |
@@ -2138,14 +2141,14 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result, | |||
2138 | EXPORT_SYMBOL_GPL(xfrm_audit_state_add); | 2141 | EXPORT_SYMBOL_GPL(xfrm_audit_state_add); |
2139 | 2142 | ||
2140 | void xfrm_audit_state_delete(struct xfrm_state *x, int result, | 2143 | void xfrm_audit_state_delete(struct xfrm_state *x, int result, |
2141 | u32 auid, u32 secid) | 2144 | uid_t auid, u32 sessionid, u32 secid) |
2142 | { | 2145 | { |
2143 | struct audit_buffer *audit_buf; | 2146 | struct audit_buffer *audit_buf; |
2144 | 2147 | ||
2145 | audit_buf = xfrm_audit_start("SAD-delete"); | 2148 | audit_buf = xfrm_audit_start("SAD-delete"); |
2146 | if (audit_buf == NULL) | 2149 | if (audit_buf == NULL) |
2147 | return; | 2150 | return; |
2148 | xfrm_audit_helper_usrinfo(auid, secid, audit_buf); | 2151 | xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf); |
2149 | xfrm_audit_helper_sainfo(x, audit_buf); | 2152 | xfrm_audit_helper_sainfo(x, audit_buf); |
2150 | audit_log_format(audit_buf, " res=%u", result); | 2153 | audit_log_format(audit_buf, " res=%u", result); |
2151 | audit_log_end(audit_buf); | 2154 | audit_log_end(audit_buf); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 22a30ae582a2..a1b0fbe3ea35 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -407,6 +407,9 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
407 | struct xfrm_state *x; | 407 | struct xfrm_state *x; |
408 | int err; | 408 | int err; |
409 | struct km_event c; | 409 | struct km_event c; |
410 | uid_t loginuid = NETLINK_CB(skb).loginuid; | ||
411 | u32 sessionid = NETLINK_CB(skb).sessionid; | ||
412 | u32 sid = NETLINK_CB(skb).sid; | ||
410 | 413 | ||
411 | err = verify_newsa_info(p, attrs); | 414 | err = verify_newsa_info(p, attrs); |
412 | if (err) | 415 | if (err) |
@@ -422,8 +425,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
422 | else | 425 | else |
423 | err = xfrm_state_update(x); | 426 | err = xfrm_state_update(x); |
424 | 427 | ||
425 | xfrm_audit_state_add(x, err ? 0 : 1, NETLINK_CB(skb).loginuid, | 428 | xfrm_audit_state_add(x, err ? 0 : 1, loginuid, sessionid, sid); |
426 | NETLINK_CB(skb).sid); | ||
427 | 429 | ||
428 | if (err < 0) { | 430 | if (err < 0) { |
429 | x->km.state = XFRM_STATE_DEAD; | 431 | x->km.state = XFRM_STATE_DEAD; |
@@ -478,6 +480,9 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
478 | int err = -ESRCH; | 480 | int err = -ESRCH; |
479 | struct km_event c; | 481 | struct km_event c; |
480 | struct xfrm_usersa_id *p = nlmsg_data(nlh); | 482 | struct xfrm_usersa_id *p = nlmsg_data(nlh); |
483 | uid_t loginuid = NETLINK_CB(skb).loginuid; | ||
484 | u32 sessionid = NETLINK_CB(skb).sessionid; | ||
485 | u32 sid = NETLINK_CB(skb).sid; | ||
481 | 486 | ||
482 | x = xfrm_user_state_lookup(p, attrs, &err); | 487 | x = xfrm_user_state_lookup(p, attrs, &err); |
483 | if (x == NULL) | 488 | if (x == NULL) |
@@ -502,8 +507,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
502 | km_state_notify(x, &c); | 507 | km_state_notify(x, &c); |
503 | 508 | ||
504 | out: | 509 | out: |
505 | xfrm_audit_state_delete(x, err ? 0 : 1, NETLINK_CB(skb).loginuid, | 510 | xfrm_audit_state_delete(x, err ? 0 : 1, loginuid, sessionid, sid); |
506 | NETLINK_CB(skb).sid); | ||
507 | xfrm_state_put(x); | 511 | xfrm_state_put(x); |
508 | return err; | 512 | return err; |
509 | } | 513 | } |
@@ -1123,6 +1127,9 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1123 | struct km_event c; | 1127 | struct km_event c; |
1124 | int err; | 1128 | int err; |
1125 | int excl; | 1129 | int excl; |
1130 | uid_t loginuid = NETLINK_CB(skb).loginuid; | ||
1131 | u32 sessionid = NETLINK_CB(skb).sessionid; | ||
1132 | u32 sid = NETLINK_CB(skb).sid; | ||
1126 | 1133 | ||
1127 | err = verify_newpolicy_info(p); | 1134 | err = verify_newpolicy_info(p); |
1128 | if (err) | 1135 | if (err) |
@@ -1141,8 +1148,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1141 | * a type XFRM_MSG_UPDPOLICY - JHS */ | 1148 | * a type XFRM_MSG_UPDPOLICY - JHS */ |
1142 | excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; | 1149 | excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; |
1143 | err = xfrm_policy_insert(p->dir, xp, excl); | 1150 | err = xfrm_policy_insert(p->dir, xp, excl); |
1144 | xfrm_audit_policy_add(xp, err ? 0 : 1, NETLINK_CB(skb).loginuid, | 1151 | xfrm_audit_policy_add(xp, err ? 0 : 1, loginuid, sessionid, sid); |
1145 | NETLINK_CB(skb).sid); | ||
1146 | 1152 | ||
1147 | if (err) { | 1153 | if (err) { |
1148 | security_xfrm_policy_free(xp->security); | 1154 | security_xfrm_policy_free(xp->security); |
@@ -1371,9 +1377,12 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1371 | NETLINK_CB(skb).pid); | 1377 | NETLINK_CB(skb).pid); |
1372 | } | 1378 | } |
1373 | } else { | 1379 | } else { |
1374 | xfrm_audit_policy_delete(xp, err ? 0 : 1, | 1380 | uid_t loginuid = NETLINK_CB(skb).loginuid; |
1375 | NETLINK_CB(skb).loginuid, | 1381 | u32 sessionid = NETLINK_CB(skb).sessionid; |
1376 | NETLINK_CB(skb).sid); | 1382 | u32 sid = NETLINK_CB(skb).sid; |
1383 | |||
1384 | xfrm_audit_policy_delete(xp, err ? 0 : 1, loginuid, sessionid, | ||
1385 | sid); | ||
1377 | 1386 | ||
1378 | if (err != 0) | 1387 | if (err != 0) |
1379 | goto out; | 1388 | goto out; |
@@ -1399,6 +1408,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1399 | int err; | 1408 | int err; |
1400 | 1409 | ||
1401 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1410 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1411 | audit_info.sessionid = NETLINK_CB(skb).sessionid; | ||
1402 | audit_info.secid = NETLINK_CB(skb).sid; | 1412 | audit_info.secid = NETLINK_CB(skb).sid; |
1403 | err = xfrm_state_flush(p->proto, &audit_info); | 1413 | err = xfrm_state_flush(p->proto, &audit_info); |
1404 | if (err) | 1414 | if (err) |
@@ -1546,6 +1556,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1546 | return err; | 1556 | return err; |
1547 | 1557 | ||
1548 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1558 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1559 | audit_info.sessionid = NETLINK_CB(skb).sessionid; | ||
1549 | audit_info.secid = NETLINK_CB(skb).sid; | 1560 | audit_info.secid = NETLINK_CB(skb).sid; |
1550 | err = xfrm_policy_flush(type, &audit_info); | 1561 | err = xfrm_policy_flush(type, &audit_info); |
1551 | if (err) | 1562 | if (err) |
@@ -1604,9 +1615,11 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1604 | read_unlock(&xp->lock); | 1615 | read_unlock(&xp->lock); |
1605 | err = 0; | 1616 | err = 0; |
1606 | if (up->hard) { | 1617 | if (up->hard) { |
1618 | uid_t loginuid = NETLINK_CB(skb).loginuid; | ||
1619 | uid_t sessionid = NETLINK_CB(skb).sessionid; | ||
1620 | u32 sid = NETLINK_CB(skb).sid; | ||
1607 | xfrm_policy_delete(xp, p->dir); | 1621 | xfrm_policy_delete(xp, p->dir); |
1608 | xfrm_audit_policy_delete(xp, 1, NETLINK_CB(skb).loginuid, | 1622 | xfrm_audit_policy_delete(xp, 1, loginuid, sessionid, sid); |
1609 | NETLINK_CB(skb).sid); | ||
1610 | 1623 | ||
1611 | } else { | 1624 | } else { |
1612 | // reset the timers here? | 1625 | // reset the timers here? |
@@ -1640,9 +1653,11 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1640 | km_state_expired(x, ue->hard, current->pid); | 1653 | km_state_expired(x, ue->hard, current->pid); |
1641 | 1654 | ||
1642 | if (ue->hard) { | 1655 | if (ue->hard) { |
1656 | uid_t loginuid = NETLINK_CB(skb).loginuid; | ||
1657 | uid_t sessionid = NETLINK_CB(skb).sessionid; | ||
1658 | u32 sid = NETLINK_CB(skb).sid; | ||
1643 | __xfrm_state_delete(x); | 1659 | __xfrm_state_delete(x); |
1644 | xfrm_audit_state_delete(x, 1, NETLINK_CB(skb).loginuid, | 1660 | xfrm_audit_state_delete(x, 1, loginuid, sessionid, sid); |
1645 | NETLINK_CB(skb).sid); | ||
1646 | } | 1661 | } |
1647 | err = 0; | 1662 | err = 0; |
1648 | out: | 1663 | out: |
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 95a8ef4a5073..114b4b4c97b2 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -646,7 +646,7 @@ void avc_audit(u32 ssid, u32 tsid, | |||
646 | if (*p) | 646 | if (*p) |
647 | audit_log_untrustedstring(ab, p); | 647 | audit_log_untrustedstring(ab, p); |
648 | else | 648 | else |
649 | audit_log_hex(ab, p, len); | 649 | audit_log_n_hex(ab, p, len); |
650 | break; | 650 | break; |
651 | } | 651 | } |
652 | } | 652 | } |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index a5da5a8cfe9b..271a835fbbe3 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -324,6 +324,7 @@ static void smk_cipso_doi(void) | |||
324 | struct netlbl_audit audit_info; | 324 | struct netlbl_audit audit_info; |
325 | 325 | ||
326 | audit_info.loginuid = audit_get_loginuid(current); | 326 | audit_info.loginuid = audit_get_loginuid(current); |
327 | audit_info.sessionid = audit_get_sessionid(current); | ||
327 | audit_info.secid = smack_to_secid(current->security); | 328 | audit_info.secid = smack_to_secid(current->security); |
328 | 329 | ||
329 | rc = netlbl_cfg_map_del(NULL, &audit_info); | 330 | rc = netlbl_cfg_map_del(NULL, &audit_info); |
@@ -356,6 +357,7 @@ static void smk_unlbl_ambient(char *oldambient) | |||
356 | struct netlbl_audit audit_info; | 357 | struct netlbl_audit audit_info; |
357 | 358 | ||
358 | audit_info.loginuid = audit_get_loginuid(current); | 359 | audit_info.loginuid = audit_get_loginuid(current); |
360 | audit_info.sessionid = audit_get_sessionid(current); | ||
359 | audit_info.secid = smack_to_secid(current->security); | 361 | audit_info.secid = smack_to_secid(current->security); |
360 | 362 | ||
361 | if (oldambient != NULL) { | 363 | if (oldambient != NULL) { |