diff options
-rw-r--r-- | include/linux/audit.h | 7 | ||||
-rw-r--r-- | kernel/audit.c | 32 | ||||
-rw-r--r-- | kernel/auditsc.c | 21 |
3 files changed, 34 insertions, 26 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 5d1a9dda5acb..77adef640537 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -51,7 +51,8 @@ | |||
51 | #define AUDIT_WATCH_LIST 1009 /* List all file/dir watches */ | 51 | #define AUDIT_WATCH_LIST 1009 /* List all file/dir watches */ |
52 | #define AUDIT_SIGNAL_INFO 1010 /* Get info about sender of signal to auditd */ | 52 | #define AUDIT_SIGNAL_INFO 1010 /* Get info about sender of signal to auditd */ |
53 | 53 | ||
54 | #define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages uninteresting to kernel */ | 54 | #define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel */ |
55 | #define AUDIT_USER_AVC 1107 /* We filter this differently */ | ||
55 | #define AUDIT_LAST_USER_MSG 1199 | 56 | #define AUDIT_LAST_USER_MSG 1199 |
56 | 57 | ||
57 | #define AUDIT_DAEMON_START 1200 /* Daemon startup record */ | 58 | #define AUDIT_DAEMON_START 1200 /* Daemon startup record */ |
@@ -235,7 +236,7 @@ extern int audit_socketcall(int nargs, unsigned long *args); | |||
235 | extern int audit_sockaddr(int len, void *addr); | 236 | extern int audit_sockaddr(int len, void *addr); |
236 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); | 237 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); |
237 | extern void audit_signal_info(int sig, struct task_struct *t); | 238 | extern void audit_signal_info(int sig, struct task_struct *t); |
238 | extern int audit_filter_user(struct task_struct *tsk, int type); | 239 | extern int audit_filter_user(int pid, int type); |
239 | #else | 240 | #else |
240 | #define audit_alloc(t) ({ 0; }) | 241 | #define audit_alloc(t) ({ 0; }) |
241 | #define audit_free(t) do { ; } while (0) | 242 | #define audit_free(t) do { ; } while (0) |
@@ -252,7 +253,7 @@ extern int audit_filter_user(struct task_struct *tsk, int type); | |||
252 | #define audit_sockaddr(len, addr) ({ 0; }) | 253 | #define audit_sockaddr(len, addr) ({ 0; }) |
253 | #define audit_avc_path(dentry, mnt) ({ 0; }) | 254 | #define audit_avc_path(dentry, mnt) ({ 0; }) |
254 | #define audit_signal_info(s,t) do { ; } while (0) | 255 | #define audit_signal_info(s,t) do { ; } while (0) |
255 | #define audit_filter_user(struct ({ 1; }) | 256 | #define audit_filter_user(p,t) ({ 1; }) |
256 | #endif | 257 | #endif |
257 | 258 | ||
258 | #ifdef CONFIG_AUDIT | 259 | #ifdef CONFIG_AUDIT |
diff --git a/kernel/audit.c b/kernel/audit.c index c1ab8dbbb67b..09a37581213b 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -429,25 +429,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
429 | break; | 429 | break; |
430 | case AUDIT_USER: | 430 | case AUDIT_USER: |
431 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: | 431 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: |
432 | read_lock(&tasklist_lock); | 432 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) |
433 | tsk = find_task_by_pid(pid); | 433 | return 0; |
434 | if (tsk) | 434 | |
435 | get_task_struct(tsk); | 435 | err = audit_filter_user(pid, msg_type); |
436 | read_unlock(&tasklist_lock); | 436 | if (err == 1) { |
437 | if (!tsk) | 437 | err = 0; |
438 | return -ESRCH; | 438 | ab = audit_log_start(NULL, msg_type); |
439 | 439 | if (ab) { | |
440 | if (audit_enabled && audit_filter_user(tsk, msg_type)) { | 440 | audit_log_format(ab, |
441 | ab = audit_log_start(NULL, msg_type); | 441 | "user pid=%d uid=%u auid=%u msg='%.1024s'", |
442 | if (ab) { | 442 | pid, uid, loginuid, (char *)data); |
443 | audit_log_format(ab, | 443 | audit_set_pid(ab, pid); |
444 | "user pid=%d uid=%u auid=%u msg='%.1024s'", | 444 | audit_log_end(ab); |
445 | pid, uid, loginuid, (char *)data); | 445 | } |
446 | audit_set_pid(ab, pid); | ||
447 | audit_log_end(ab); | ||
448 | } | ||
449 | } | 446 | } |
450 | put_task_struct(tsk); | ||
451 | break; | 447 | break; |
452 | case AUDIT_ADD: | 448 | case AUDIT_ADD: |
453 | case AUDIT_DEL: | 449 | case AUDIT_DEL: |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index cb8a44945157..fc858b0c044a 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -530,22 +530,33 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, | |||
530 | return AUDIT_BUILD_CONTEXT; | 530 | return AUDIT_BUILD_CONTEXT; |
531 | } | 531 | } |
532 | 532 | ||
533 | int audit_filter_user(struct task_struct *tsk, int type) | 533 | int audit_filter_user(int pid, int type) |
534 | { | 534 | { |
535 | struct task_struct *tsk; | ||
535 | struct audit_entry *e; | 536 | struct audit_entry *e; |
536 | enum audit_state state; | 537 | enum audit_state state; |
538 | int ret = 1; | ||
537 | 539 | ||
538 | if (audit_pid && tsk->pid == audit_pid) | 540 | read_lock(&tasklist_lock); |
539 | return AUDIT_DISABLED; | 541 | tsk = find_task_by_pid(pid); |
542 | if (tsk) | ||
543 | get_task_struct(tsk); | ||
544 | read_unlock(&tasklist_lock); | ||
545 | |||
546 | if (!tsk) | ||
547 | return -ESRCH; | ||
540 | 548 | ||
541 | rcu_read_lock(); | 549 | rcu_read_lock(); |
542 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { | 550 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { |
543 | if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { | 551 | if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { |
544 | rcu_read_unlock(); | 552 | if (state == AUDIT_DISABLED) |
545 | return state != AUDIT_DISABLED; | 553 | ret = 0; |
554 | break; | ||
546 | } | 555 | } |
547 | } | 556 | } |
548 | rcu_read_unlock(); | 557 | rcu_read_unlock(); |
558 | put_task_struct(tsk); | ||
559 | |||
549 | return 1; /* Audit by default */ | 560 | return 1; /* Audit by default */ |
550 | 561 | ||
551 | } | 562 | } |