diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-12 15:38:53 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-12 15:38:53 -0400 |
| commit | 0b747172dce6e0905ab173afbaffebb7a11d89bd (patch) | |
| tree | cef4092aa49bd44d4759b58762bfa221dac45f57 /kernel | |
| parent | b7e70ca9c7d7f049bba8047d7ab49966fd5e9e9d (diff) | |
| parent | 312103d64d0fcadb332899a2c84b357ddb18f4e3 (diff) | |
Merge git://git.infradead.org/users/eparis/audit
Pull audit updates from Eric Paris.
* git://git.infradead.org/users/eparis/audit: (28 commits)
AUDIT: make audit_is_compat depend on CONFIG_AUDIT_COMPAT_GENERIC
audit: renumber AUDIT_FEATURE_CHANGE into the 1300 range
audit: do not cast audit_rule_data pointers pointlesly
AUDIT: Allow login in non-init namespaces
audit: define audit_is_compat in kernel internal header
kernel: Use RCU_INIT_POINTER(x, NULL) in audit.c
sched: declare pid_alive as inline
audit: use uapi/linux/audit.h for AUDIT_ARCH declarations
syscall_get_arch: remove useless function arguments
audit: remove stray newline from audit_log_execve_info() audit_panic() call
audit: remove stray newlines from audit_log_lost messages
audit: include subject in login records
audit: remove superfluous new- prefix in AUDIT_LOGIN messages
audit: allow user processes to log from another PID namespace
audit: anchor all pid references in the initial pid namespace
audit: convert PPIDs to the inital PID namespace.
pid: get pid_t ppid of task in init_pid_ns
audit: rename the misleading audit_get_context() to audit_take_context()
audit: Add generic compat syscall support
audit: Add CONFIG_HAVE_ARCH_AUDITSYSCALL
...
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/audit.c | 27 | ||||
| -rw-r--r-- | kernel/audit.h | 6 | ||||
| -rw-r--r-- | kernel/auditfilter.c | 33 | ||||
| -rw-r--r-- | kernel/auditsc.c | 133 | ||||
| -rw-r--r-- | kernel/seccomp.c | 4 |
5 files changed, 149 insertions, 54 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 95a20f3f52f1..7c2893602d06 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -182,7 +182,7 @@ struct audit_buffer { | |||
| 182 | 182 | ||
| 183 | struct audit_reply { | 183 | struct audit_reply { |
| 184 | __u32 portid; | 184 | __u32 portid; |
| 185 | struct net *net; | 185 | struct net *net; |
| 186 | struct sk_buff *skb; | 186 | struct sk_buff *skb; |
| 187 | }; | 187 | }; |
| 188 | 188 | ||
| @@ -396,7 +396,7 @@ static void audit_printk_skb(struct sk_buff *skb) | |||
| 396 | if (printk_ratelimit()) | 396 | if (printk_ratelimit()) |
| 397 | pr_notice("type=%d %s\n", nlh->nlmsg_type, data); | 397 | pr_notice("type=%d %s\n", nlh->nlmsg_type, data); |
| 398 | else | 398 | else |
| 399 | audit_log_lost("printk limit exceeded\n"); | 399 | audit_log_lost("printk limit exceeded"); |
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | audit_hold_skb(skb); | 402 | audit_hold_skb(skb); |
| @@ -412,7 +412,7 @@ static void kauditd_send_skb(struct sk_buff *skb) | |||
| 412 | BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */ | 412 | BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */ |
| 413 | if (audit_pid) { | 413 | if (audit_pid) { |
| 414 | pr_err("*NO* daemon at audit_pid=%d\n", audit_pid); | 414 | pr_err("*NO* daemon at audit_pid=%d\n", audit_pid); |
| 415 | audit_log_lost("auditd disappeared\n"); | 415 | audit_log_lost("auditd disappeared"); |
| 416 | audit_pid = 0; | 416 | audit_pid = 0; |
| 417 | audit_sock = NULL; | 417 | audit_sock = NULL; |
| 418 | } | 418 | } |
| @@ -607,7 +607,7 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
| 607 | { | 607 | { |
| 608 | int err = 0; | 608 | int err = 0; |
| 609 | 609 | ||
| 610 | /* Only support the initial namespaces for now. */ | 610 | /* Only support initial user namespace for now. */ |
| 611 | /* | 611 | /* |
| 612 | * We return ECONNREFUSED because it tricks userspace into thinking | 612 | * We return ECONNREFUSED because it tricks userspace into thinking |
| 613 | * that audit was not configured into the kernel. Lots of users | 613 | * that audit was not configured into the kernel. Lots of users |
| @@ -618,8 +618,7 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
| 618 | * userspace will reject all logins. This should be removed when we | 618 | * userspace will reject all logins. This should be removed when we |
| 619 | * support non init namespaces!! | 619 | * support non init namespaces!! |
| 620 | */ | 620 | */ |
| 621 | if ((current_user_ns() != &init_user_ns) || | 621 | if (current_user_ns() != &init_user_ns) |
| 622 | (task_active_pid_ns(current) != &init_pid_ns)) | ||
| 623 | return -ECONNREFUSED; | 622 | return -ECONNREFUSED; |
| 624 | 623 | ||
| 625 | switch (msg_type) { | 624 | switch (msg_type) { |
| @@ -639,6 +638,11 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
| 639 | case AUDIT_TTY_SET: | 638 | case AUDIT_TTY_SET: |
| 640 | case AUDIT_TRIM: | 639 | case AUDIT_TRIM: |
| 641 | case AUDIT_MAKE_EQUIV: | 640 | case AUDIT_MAKE_EQUIV: |
| 641 | /* Only support auditd and auditctl in initial pid namespace | ||
| 642 | * for now. */ | ||
| 643 | if ((task_active_pid_ns(current) != &init_pid_ns)) | ||
| 644 | return -EPERM; | ||
| 645 | |||
| 642 | if (!capable(CAP_AUDIT_CONTROL)) | 646 | if (!capable(CAP_AUDIT_CONTROL)) |
| 643 | err = -EPERM; | 647 | err = -EPERM; |
| 644 | break; | 648 | break; |
| @@ -659,6 +663,7 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type) | |||
| 659 | { | 663 | { |
| 660 | int rc = 0; | 664 | int rc = 0; |
| 661 | uid_t uid = from_kuid(&init_user_ns, current_uid()); | 665 | uid_t uid = from_kuid(&init_user_ns, current_uid()); |
| 666 | pid_t pid = task_tgid_nr(current); | ||
| 662 | 667 | ||
| 663 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) { | 668 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) { |
| 664 | *ab = NULL; | 669 | *ab = NULL; |
| @@ -668,7 +673,7 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type) | |||
| 668 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | 673 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
| 669 | if (unlikely(!*ab)) | 674 | if (unlikely(!*ab)) |
| 670 | return rc; | 675 | return rc; |
| 671 | audit_log_format(*ab, "pid=%d uid=%u", task_tgid_vnr(current), uid); | 676 | audit_log_format(*ab, "pid=%d uid=%u", pid, uid); |
| 672 | audit_log_session_info(*ab); | 677 | audit_log_session_info(*ab); |
| 673 | audit_log_task_context(*ab); | 678 | audit_log_task_context(*ab); |
| 674 | 679 | ||
| @@ -1097,7 +1102,7 @@ static void __net_exit audit_net_exit(struct net *net) | |||
| 1097 | audit_sock = NULL; | 1102 | audit_sock = NULL; |
| 1098 | } | 1103 | } |
| 1099 | 1104 | ||
| 1100 | rcu_assign_pointer(aunet->nlsk, NULL); | 1105 | RCU_INIT_POINTER(aunet->nlsk, NULL); |
| 1101 | synchronize_net(); | 1106 | synchronize_net(); |
| 1102 | netlink_kernel_release(sock); | 1107 | netlink_kernel_release(sock); |
| 1103 | } | 1108 | } |
| @@ -1829,11 +1834,11 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) | |||
| 1829 | spin_unlock_irq(&tsk->sighand->siglock); | 1834 | spin_unlock_irq(&tsk->sighand->siglock); |
| 1830 | 1835 | ||
| 1831 | audit_log_format(ab, | 1836 | audit_log_format(ab, |
| 1832 | " ppid=%ld pid=%d auid=%u uid=%u gid=%u" | 1837 | " ppid=%d pid=%d auid=%u uid=%u gid=%u" |
| 1833 | " euid=%u suid=%u fsuid=%u" | 1838 | " euid=%u suid=%u fsuid=%u" |
| 1834 | " egid=%u sgid=%u fsgid=%u tty=%s ses=%u", | 1839 | " egid=%u sgid=%u fsgid=%u tty=%s ses=%u", |
| 1835 | sys_getppid(), | 1840 | task_ppid_nr(tsk), |
| 1836 | tsk->pid, | 1841 | task_pid_nr(tsk), |
| 1837 | from_kuid(&init_user_ns, audit_get_loginuid(tsk)), | 1842 | from_kuid(&init_user_ns, audit_get_loginuid(tsk)), |
| 1838 | from_kuid(&init_user_ns, cred->uid), | 1843 | from_kuid(&init_user_ns, cred->uid), |
| 1839 | from_kgid(&init_user_ns, cred->gid), | 1844 | from_kgid(&init_user_ns, cred->gid), |
diff --git a/kernel/audit.h b/kernel/audit.h index 8df132214606..7bb65730c890 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
| @@ -106,6 +106,11 @@ struct audit_names { | |||
| 106 | bool should_free; | 106 | bool should_free; |
| 107 | }; | 107 | }; |
| 108 | 108 | ||
| 109 | struct audit_proctitle { | ||
| 110 | int len; /* length of the cmdline field. */ | ||
| 111 | char *value; /* the cmdline field */ | ||
| 112 | }; | ||
| 113 | |||
| 109 | /* The per-task audit context. */ | 114 | /* The per-task audit context. */ |
| 110 | struct audit_context { | 115 | struct audit_context { |
| 111 | int dummy; /* must be the first element */ | 116 | int dummy; /* must be the first element */ |
| @@ -202,6 +207,7 @@ struct audit_context { | |||
| 202 | } execve; | 207 | } execve; |
| 203 | }; | 208 | }; |
| 204 | int fds[2]; | 209 | int fds[2]; |
| 210 | struct audit_proctitle proctitle; | ||
| 205 | 211 | ||
| 206 | #if AUDIT_DEBUG | 212 | #if AUDIT_DEBUG |
| 207 | int put_count; | 213 | int put_count; |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 92062fd6cc8c..8e9bc9c3dbb7 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 23 | |||
| 22 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
| 23 | #include <linux/audit.h> | 25 | #include <linux/audit.h> |
| 24 | #include <linux/kthread.h> | 26 | #include <linux/kthread.h> |
| @@ -226,7 +228,7 @@ static int audit_match_signal(struct audit_entry *entry) | |||
| 226 | #endif | 228 | #endif |
| 227 | 229 | ||
| 228 | /* Common user-space to kernel rule translation. */ | 230 | /* Common user-space to kernel rule translation. */ |
| 229 | static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) | 231 | static inline struct audit_entry *audit_to_entry_common(struct audit_rule_data *rule) |
| 230 | { | 232 | { |
| 231 | unsigned listnr; | 233 | unsigned listnr; |
| 232 | struct audit_entry *entry; | 234 | struct audit_entry *entry; |
| @@ -249,7 +251,7 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) | |||
| 249 | ; | 251 | ; |
| 250 | } | 252 | } |
| 251 | if (unlikely(rule->action == AUDIT_POSSIBLE)) { | 253 | if (unlikely(rule->action == AUDIT_POSSIBLE)) { |
| 252 | printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n"); | 254 | pr_err("AUDIT_POSSIBLE is deprecated\n"); |
| 253 | goto exit_err; | 255 | goto exit_err; |
| 254 | } | 256 | } |
| 255 | if (rule->action != AUDIT_NEVER && rule->action != AUDIT_ALWAYS) | 257 | if (rule->action != AUDIT_NEVER && rule->action != AUDIT_ALWAYS) |
| @@ -403,7 +405,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
| 403 | int i; | 405 | int i; |
| 404 | char *str; | 406 | char *str; |
| 405 | 407 | ||
| 406 | entry = audit_to_entry_common((struct audit_rule *)data); | 408 | entry = audit_to_entry_common(data); |
| 407 | if (IS_ERR(entry)) | 409 | if (IS_ERR(entry)) |
| 408 | goto exit_nofree; | 410 | goto exit_nofree; |
| 409 | 411 | ||
| @@ -431,6 +433,19 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
| 431 | f->val = 0; | 433 | f->val = 0; |
| 432 | } | 434 | } |
| 433 | 435 | ||
| 436 | if ((f->type == AUDIT_PID) || (f->type == AUDIT_PPID)) { | ||
| 437 | struct pid *pid; | ||
| 438 | rcu_read_lock(); | ||
| 439 | pid = find_vpid(f->val); | ||
| 440 | if (!pid) { | ||
| 441 | rcu_read_unlock(); | ||
| 442 | err = -ESRCH; | ||
| 443 | goto exit_free; | ||
| 444 | } | ||
| 445 | f->val = pid_nr(pid); | ||
| 446 | rcu_read_unlock(); | ||
| 447 | } | ||
| 448 | |||
| 434 | err = audit_field_valid(entry, f); | 449 | err = audit_field_valid(entry, f); |
| 435 | if (err) | 450 | if (err) |
| 436 | goto exit_free; | 451 | goto exit_free; |
| @@ -479,8 +494,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
| 479 | /* Keep currently invalid fields around in case they | 494 | /* Keep currently invalid fields around in case they |
| 480 | * become valid after a policy reload. */ | 495 | * become valid after a policy reload. */ |
| 481 | if (err == -EINVAL) { | 496 | if (err == -EINVAL) { |
| 482 | printk(KERN_WARNING "audit rule for LSM " | 497 | pr_warn("audit rule for LSM \'%s\' is invalid\n", |
| 483 | "\'%s\' is invalid\n", str); | 498 | str); |
| 484 | err = 0; | 499 | err = 0; |
| 485 | } | 500 | } |
| 486 | if (err) { | 501 | if (err) { |
| @@ -709,8 +724,8 @@ static inline int audit_dupe_lsm_field(struct audit_field *df, | |||
| 709 | /* Keep currently invalid fields around in case they | 724 | /* Keep currently invalid fields around in case they |
| 710 | * become valid after a policy reload. */ | 725 | * become valid after a policy reload. */ |
| 711 | if (ret == -EINVAL) { | 726 | if (ret == -EINVAL) { |
| 712 | printk(KERN_WARNING "audit rule for LSM \'%s\' is " | 727 | pr_warn("audit rule for LSM \'%s\' is invalid\n", |
| 713 | "invalid\n", df->lsm_str); | 728 | df->lsm_str); |
| 714 | ret = 0; | 729 | ret = 0; |
| 715 | } | 730 | } |
| 716 | 731 | ||
| @@ -1240,12 +1255,14 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type, | |||
| 1240 | 1255 | ||
| 1241 | for (i = 0; i < rule->field_count; i++) { | 1256 | for (i = 0; i < rule->field_count; i++) { |
| 1242 | struct audit_field *f = &rule->fields[i]; | 1257 | struct audit_field *f = &rule->fields[i]; |
| 1258 | pid_t pid; | ||
| 1243 | int result = 0; | 1259 | int result = 0; |
| 1244 | u32 sid; | 1260 | u32 sid; |
| 1245 | 1261 | ||
| 1246 | switch (f->type) { | 1262 | switch (f->type) { |
| 1247 | case AUDIT_PID: | 1263 | case AUDIT_PID: |
| 1248 | result = audit_comparator(task_pid_vnr(current), f->op, f->val); | 1264 | pid = task_pid_nr(current); |
| 1265 | result = audit_comparator(pid, f->op, f->val); | ||
| 1249 | break; | 1266 | break; |
| 1250 | case AUDIT_UID: | 1267 | case AUDIT_UID: |
| 1251 | result = audit_uid_comparator(current_uid(), f->op, f->uid); | 1268 | result = audit_uid_comparator(current_uid(), f->op, f->uid); |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 7aef2f4b6c64..f251a5e8d17a 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -42,6 +42,8 @@ | |||
| 42 | * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance. | 42 | * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance. |
| 43 | */ | 43 | */ |
| 44 | 44 | ||
| 45 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 46 | |||
| 45 | #include <linux/init.h> | 47 | #include <linux/init.h> |
| 46 | #include <asm/types.h> | 48 | #include <asm/types.h> |
| 47 | #include <linux/atomic.h> | 49 | #include <linux/atomic.h> |
| @@ -68,6 +70,7 @@ | |||
| 68 | #include <linux/capability.h> | 70 | #include <linux/capability.h> |
| 69 | #include <linux/fs_struct.h> | 71 | #include <linux/fs_struct.h> |
| 70 | #include <linux/compat.h> | 72 | #include <linux/compat.h> |
| 73 | #include <linux/ctype.h> | ||
| 71 | 74 | ||
| 72 | #include "audit.h" | 75 | #include "audit.h" |
| 73 | 76 | ||
| @@ -79,6 +82,9 @@ | |||
| 79 | /* no execve audit message should be longer than this (userspace limits) */ | 82 | /* no execve audit message should be longer than this (userspace limits) */ |
| 80 | #define MAX_EXECVE_AUDIT_LEN 7500 | 83 | #define MAX_EXECVE_AUDIT_LEN 7500 |
| 81 | 84 | ||
| 85 | /* max length to print of cmdline/proctitle value during audit */ | ||
| 86 | #define MAX_PROCTITLE_AUDIT_LEN 128 | ||
| 87 | |||
| 82 | /* number of audit rules */ | 88 | /* number of audit rules */ |
| 83 | int audit_n_rules; | 89 | int audit_n_rules; |
| 84 | 90 | ||
| @@ -451,15 +457,17 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
| 451 | struct audit_field *f = &rule->fields[i]; | 457 | struct audit_field *f = &rule->fields[i]; |
| 452 | struct audit_names *n; | 458 | struct audit_names *n; |
| 453 | int result = 0; | 459 | int result = 0; |
| 460 | pid_t pid; | ||
| 454 | 461 | ||
| 455 | switch (f->type) { | 462 | switch (f->type) { |
| 456 | case AUDIT_PID: | 463 | case AUDIT_PID: |
| 457 | result = audit_comparator(tsk->pid, f->op, f->val); | 464 | pid = task_pid_nr(tsk); |
| 465 | result = audit_comparator(pid, f->op, f->val); | ||
| 458 | break; | 466 | break; |
| 459 | case AUDIT_PPID: | 467 | case AUDIT_PPID: |
| 460 | if (ctx) { | 468 | if (ctx) { |
| 461 | if (!ctx->ppid) | 469 | if (!ctx->ppid) |
| 462 | ctx->ppid = sys_getppid(); | 470 | ctx->ppid = task_ppid_nr(tsk); |
| 463 | result = audit_comparator(ctx->ppid, f->op, f->val); | 471 | result = audit_comparator(ctx->ppid, f->op, f->val); |
| 464 | } | 472 | } |
| 465 | break; | 473 | break; |
| @@ -805,7 +813,8 @@ void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx) | |||
| 805 | rcu_read_unlock(); | 813 | rcu_read_unlock(); |
| 806 | } | 814 | } |
| 807 | 815 | ||
| 808 | static inline struct audit_context *audit_get_context(struct task_struct *tsk, | 816 | /* Transfer the audit context pointer to the caller, clearing it in the tsk's struct */ |
| 817 | static inline struct audit_context *audit_take_context(struct task_struct *tsk, | ||
| 809 | int return_valid, | 818 | int return_valid, |
| 810 | long return_code) | 819 | long return_code) |
| 811 | { | 820 | { |
| @@ -842,6 +851,13 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk, | |||
| 842 | return context; | 851 | return context; |
| 843 | } | 852 | } |
| 844 | 853 | ||
| 854 | static inline void audit_proctitle_free(struct audit_context *context) | ||
| 855 | { | ||
| 856 | kfree(context->proctitle.value); | ||
| 857 | context->proctitle.value = NULL; | ||
| 858 | context->proctitle.len = 0; | ||
| 859 | } | ||
| 860 | |||
| 845 | static inline void audit_free_names(struct audit_context *context) | 861 | static inline void audit_free_names(struct audit_context *context) |
| 846 | { | 862 | { |
| 847 | struct audit_names *n, *next; | 863 | struct audit_names *n, *next; |
| @@ -850,16 +866,15 @@ static inline void audit_free_names(struct audit_context *context) | |||
| 850 | if (context->put_count + context->ino_count != context->name_count) { | 866 | if (context->put_count + context->ino_count != context->name_count) { |
| 851 | int i = 0; | 867 | int i = 0; |
| 852 | 868 | ||
| 853 | printk(KERN_ERR "%s:%d(:%d): major=%d in_syscall=%d" | 869 | pr_err("%s:%d(:%d): major=%d in_syscall=%d" |
| 854 | " name_count=%d put_count=%d" | 870 | " name_count=%d put_count=%d ino_count=%d" |
| 855 | " ino_count=%d [NOT freeing]\n", | 871 | " [NOT freeing]\n", __FILE__, __LINE__, |
| 856 | __FILE__, __LINE__, | ||
| 857 | context->serial, context->major, context->in_syscall, | 872 | context->serial, context->major, context->in_syscall, |
| 858 | context->name_count, context->put_count, | 873 | context->name_count, context->put_count, |
| 859 | context->ino_count); | 874 | context->ino_count); |
| 860 | list_for_each_entry(n, &context->names_list, list) { | 875 | list_for_each_entry(n, &context->names_list, list) { |
| 861 | printk(KERN_ERR "names[%d] = %p = %s\n", i++, | 876 | pr_err("names[%d] = %p = %s\n", i++, n->name, |
| 862 | n->name, n->name->name ?: "(null)"); | 877 | n->name->name ?: "(null)"); |
| 863 | } | 878 | } |
| 864 | dump_stack(); | 879 | dump_stack(); |
| 865 | return; | 880 | return; |
| @@ -955,6 +970,7 @@ static inline void audit_free_context(struct audit_context *context) | |||
| 955 | audit_free_aux(context); | 970 | audit_free_aux(context); |
| 956 | kfree(context->filterkey); | 971 | kfree(context->filterkey); |
| 957 | kfree(context->sockaddr); | 972 | kfree(context->sockaddr); |
| 973 | audit_proctitle_free(context); | ||
| 958 | kfree(context); | 974 | kfree(context); |
| 959 | } | 975 | } |
| 960 | 976 | ||
| @@ -1157,7 +1173,7 @@ static void audit_log_execve_info(struct audit_context *context, | |||
| 1157 | */ | 1173 | */ |
| 1158 | buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL); | 1174 | buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL); |
| 1159 | if (!buf) { | 1175 | if (!buf) { |
| 1160 | audit_panic("out of memory for argv string\n"); | 1176 | audit_panic("out of memory for argv string"); |
| 1161 | return; | 1177 | return; |
| 1162 | } | 1178 | } |
| 1163 | 1179 | ||
| @@ -1271,6 +1287,59 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
| 1271 | audit_log_end(ab); | 1287 | audit_log_end(ab); |
| 1272 | } | 1288 | } |
| 1273 | 1289 | ||
| 1290 | static inline int audit_proctitle_rtrim(char *proctitle, int len) | ||
| 1291 | { | ||
| 1292 | char *end = proctitle + len - 1; | ||
| 1293 | while (end > proctitle && !isprint(*end)) | ||
| 1294 | end--; | ||
| 1295 | |||
| 1296 | /* catch the case where proctitle is only 1 non-print character */ | ||
| 1297 | len = end - proctitle + 1; | ||
| 1298 | len -= isprint(proctitle[len-1]) == 0; | ||
| 1299 | return len; | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | static void audit_log_proctitle(struct task_struct *tsk, | ||
| 1303 | struct audit_context *context) | ||
| 1304 | { | ||
| 1305 | int res; | ||
| 1306 | char *buf; | ||
| 1307 | char *msg = "(null)"; | ||
| 1308 | int len = strlen(msg); | ||
| 1309 | struct audit_buffer *ab; | ||
| 1310 | |||
| 1311 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_PROCTITLE); | ||
| 1312 | if (!ab) | ||
| 1313 | return; /* audit_panic or being filtered */ | ||
| 1314 | |||
| 1315 | audit_log_format(ab, "proctitle="); | ||
| 1316 | |||
| 1317 | /* Not cached */ | ||
| 1318 | if (!context->proctitle.value) { | ||
| 1319 | buf = kmalloc(MAX_PROCTITLE_AUDIT_LEN, GFP_KERNEL); | ||
| 1320 | if (!buf) | ||
| 1321 | goto out; | ||
| 1322 | /* Historically called this from procfs naming */ | ||
| 1323 | res = get_cmdline(tsk, buf, MAX_PROCTITLE_AUDIT_LEN); | ||
| 1324 | if (res == 0) { | ||
| 1325 | kfree(buf); | ||
| 1326 | goto out; | ||
| 1327 | } | ||
| 1328 | res = audit_proctitle_rtrim(buf, res); | ||
| 1329 | if (res == 0) { | ||
| 1330 | kfree(buf); | ||
| 1331 | goto out; | ||
| 1332 | } | ||
| 1333 | context->proctitle.value = buf; | ||
| 1334 | context->proctitle.len = res; | ||
| 1335 | } | ||
| 1336 | msg = context->proctitle.value; | ||
| 1337 | len = context->proctitle.len; | ||
| 1338 | out: | ||
| 1339 | audit_log_n_untrustedstring(ab, msg, len); | ||
| 1340 | audit_log_end(ab); | ||
| 1341 | } | ||
| 1342 | |||
| 1274 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) | 1343 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) |
| 1275 | { | 1344 | { |
| 1276 | int i, call_panic = 0; | 1345 | int i, call_panic = 0; |
| @@ -1388,6 +1457,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
| 1388 | audit_log_name(context, n, NULL, i++, &call_panic); | 1457 | audit_log_name(context, n, NULL, i++, &call_panic); |
| 1389 | } | 1458 | } |
| 1390 | 1459 | ||
| 1460 | audit_log_proctitle(tsk, context); | ||
| 1461 | |||
| 1391 | /* Send end of event record to help user space know we are finished */ | 1462 | /* Send end of event record to help user space know we are finished */ |
| 1392 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); | 1463 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); |
| 1393 | if (ab) | 1464 | if (ab) |
| @@ -1406,7 +1477,7 @@ void __audit_free(struct task_struct *tsk) | |||
| 1406 | { | 1477 | { |
| 1407 | struct audit_context *context; | 1478 | struct audit_context *context; |
| 1408 | 1479 | ||
| 1409 | context = audit_get_context(tsk, 0, 0); | 1480 | context = audit_take_context(tsk, 0, 0); |
| 1410 | if (!context) | 1481 | if (!context) |
| 1411 | return; | 1482 | return; |
| 1412 | 1483 | ||
| @@ -1500,7 +1571,7 @@ void __audit_syscall_exit(int success, long return_code) | |||
| 1500 | else | 1571 | else |
| 1501 | success = AUDITSC_FAILURE; | 1572 | success = AUDITSC_FAILURE; |
| 1502 | 1573 | ||
| 1503 | context = audit_get_context(tsk, success, return_code); | 1574 | context = audit_take_context(tsk, success, return_code); |
| 1504 | if (!context) | 1575 | if (!context) |
| 1505 | return; | 1576 | return; |
| 1506 | 1577 | ||
| @@ -1550,7 +1621,7 @@ static inline void handle_one(const struct inode *inode) | |||
| 1550 | if (likely(put_tree_ref(context, chunk))) | 1621 | if (likely(put_tree_ref(context, chunk))) |
| 1551 | return; | 1622 | return; |
| 1552 | if (unlikely(!grow_tree_refs(context))) { | 1623 | if (unlikely(!grow_tree_refs(context))) { |
| 1553 | printk(KERN_WARNING "out of memory, audit has lost a tree reference\n"); | 1624 | pr_warn("out of memory, audit has lost a tree reference\n"); |
| 1554 | audit_set_auditable(context); | 1625 | audit_set_auditable(context); |
| 1555 | audit_put_chunk(chunk); | 1626 | audit_put_chunk(chunk); |
| 1556 | unroll_tree_refs(context, p, count); | 1627 | unroll_tree_refs(context, p, count); |
| @@ -1609,8 +1680,7 @@ retry: | |||
| 1609 | goto retry; | 1680 | goto retry; |
| 1610 | } | 1681 | } |
| 1611 | /* too bad */ | 1682 | /* too bad */ |
| 1612 | printk(KERN_WARNING | 1683 | pr_warn("out of memory, audit has lost a tree reference\n"); |
| 1613 | "out of memory, audit has lost a tree reference\n"); | ||
| 1614 | unroll_tree_refs(context, p, count); | 1684 | unroll_tree_refs(context, p, count); |
| 1615 | audit_set_auditable(context); | 1685 | audit_set_auditable(context); |
| 1616 | return; | 1686 | return; |
| @@ -1682,7 +1752,7 @@ void __audit_getname(struct filename *name) | |||
| 1682 | 1752 | ||
| 1683 | if (!context->in_syscall) { | 1753 | if (!context->in_syscall) { |
| 1684 | #if AUDIT_DEBUG == 2 | 1754 | #if AUDIT_DEBUG == 2 |
| 1685 | printk(KERN_ERR "%s:%d(:%d): ignoring getname(%p)\n", | 1755 | pr_err("%s:%d(:%d): ignoring getname(%p)\n", |
| 1686 | __FILE__, __LINE__, context->serial, name); | 1756 | __FILE__, __LINE__, context->serial, name); |
| 1687 | dump_stack(); | 1757 | dump_stack(); |
| 1688 | #endif | 1758 | #endif |
| @@ -1721,15 +1791,15 @@ void audit_putname(struct filename *name) | |||
| 1721 | BUG_ON(!context); | 1791 | BUG_ON(!context); |
| 1722 | if (!name->aname || !context->in_syscall) { | 1792 | if (!name->aname || !context->in_syscall) { |
| 1723 | #if AUDIT_DEBUG == 2 | 1793 | #if AUDIT_DEBUG == 2 |
| 1724 | printk(KERN_ERR "%s:%d(:%d): final_putname(%p)\n", | 1794 | pr_err("%s:%d(:%d): final_putname(%p)\n", |
| 1725 | __FILE__, __LINE__, context->serial, name); | 1795 | __FILE__, __LINE__, context->serial, name); |
| 1726 | if (context->name_count) { | 1796 | if (context->name_count) { |
| 1727 | struct audit_names *n; | 1797 | struct audit_names *n; |
| 1728 | int i = 0; | 1798 | int i = 0; |
| 1729 | 1799 | ||
| 1730 | list_for_each_entry(n, &context->names_list, list) | 1800 | list_for_each_entry(n, &context->names_list, list) |
| 1731 | printk(KERN_ERR "name[%d] = %p = %s\n", i++, | 1801 | pr_err("name[%d] = %p = %s\n", i++, n->name, |
| 1732 | n->name, n->name->name ?: "(null)"); | 1802 | n->name->name ?: "(null)"); |
| 1733 | } | 1803 | } |
| 1734 | #endif | 1804 | #endif |
| 1735 | final_putname(name); | 1805 | final_putname(name); |
| @@ -1738,9 +1808,8 @@ void audit_putname(struct filename *name) | |||
| 1738 | else { | 1808 | else { |
| 1739 | ++context->put_count; | 1809 | ++context->put_count; |
| 1740 | if (context->put_count > context->name_count) { | 1810 | if (context->put_count > context->name_count) { |
| 1741 | printk(KERN_ERR "%s:%d(:%d): major=%d" | 1811 | pr_err("%s:%d(:%d): major=%d in_syscall=%d putname(%p)" |
| 1742 | " in_syscall=%d putname(%p) name_count=%d" | 1812 | " name_count=%d put_count=%d\n", |
| 1743 | " put_count=%d\n", | ||
| 1744 | __FILE__, __LINE__, | 1813 | __FILE__, __LINE__, |
| 1745 | context->serial, context->major, | 1814 | context->serial, context->major, |
| 1746 | context->in_syscall, name->name, | 1815 | context->in_syscall, name->name, |
| @@ -1981,12 +2050,10 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, | |||
| 1981 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); | 2050 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); |
| 1982 | if (!ab) | 2051 | if (!ab) |
| 1983 | return; | 2052 | return; |
| 1984 | audit_log_format(ab, "pid=%d uid=%u" | 2053 | audit_log_format(ab, "pid=%d uid=%u", task_pid_nr(current), uid); |
| 1985 | " old-auid=%u new-auid=%u old-ses=%u new-ses=%u" | 2054 | audit_log_task_context(ab); |
| 1986 | " res=%d", | 2055 | audit_log_format(ab, " old-auid=%u auid=%u old-ses=%u ses=%u res=%d", |
| 1987 | current->pid, uid, | 2056 | oldloginuid, loginuid, oldsessionid, sessionid, !rc); |
| 1988 | oldloginuid, loginuid, oldsessionid, sessionid, | ||
| 1989 | !rc); | ||
| 1990 | audit_log_end(ab); | 2057 | audit_log_end(ab); |
| 1991 | } | 2058 | } |
| 1992 | 2059 | ||
| @@ -2208,7 +2275,7 @@ void __audit_ptrace(struct task_struct *t) | |||
| 2208 | { | 2275 | { |
| 2209 | struct audit_context *context = current->audit_context; | 2276 | struct audit_context *context = current->audit_context; |
| 2210 | 2277 | ||
| 2211 | context->target_pid = t->pid; | 2278 | context->target_pid = task_pid_nr(t); |
| 2212 | context->target_auid = audit_get_loginuid(t); | 2279 | context->target_auid = audit_get_loginuid(t); |
| 2213 | context->target_uid = task_uid(t); | 2280 | context->target_uid = task_uid(t); |
| 2214 | context->target_sessionid = audit_get_sessionid(t); | 2281 | context->target_sessionid = audit_get_sessionid(t); |
| @@ -2233,7 +2300,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
| 2233 | 2300 | ||
| 2234 | if (audit_pid && t->tgid == audit_pid) { | 2301 | if (audit_pid && t->tgid == audit_pid) { |
| 2235 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) { | 2302 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) { |
| 2236 | audit_sig_pid = tsk->pid; | 2303 | audit_sig_pid = task_pid_nr(tsk); |
| 2237 | if (uid_valid(tsk->loginuid)) | 2304 | if (uid_valid(tsk->loginuid)) |
| 2238 | audit_sig_uid = tsk->loginuid; | 2305 | audit_sig_uid = tsk->loginuid; |
| 2239 | else | 2306 | else |
| @@ -2247,7 +2314,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
| 2247 | /* optimize the common case by putting first signal recipient directly | 2314 | /* optimize the common case by putting first signal recipient directly |
| 2248 | * in audit_context */ | 2315 | * in audit_context */ |
| 2249 | if (!ctx->target_pid) { | 2316 | if (!ctx->target_pid) { |
| 2250 | ctx->target_pid = t->tgid; | 2317 | ctx->target_pid = task_tgid_nr(t); |
| 2251 | ctx->target_auid = audit_get_loginuid(t); | 2318 | ctx->target_auid = audit_get_loginuid(t); |
| 2252 | ctx->target_uid = t_uid; | 2319 | ctx->target_uid = t_uid; |
| 2253 | ctx->target_sessionid = audit_get_sessionid(t); | 2320 | ctx->target_sessionid = audit_get_sessionid(t); |
| @@ -2268,7 +2335,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
| 2268 | } | 2335 | } |
| 2269 | BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS); | 2336 | BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS); |
| 2270 | 2337 | ||
| 2271 | axp->target_pid[axp->pid_count] = t->tgid; | 2338 | axp->target_pid[axp->pid_count] = task_tgid_nr(t); |
| 2272 | axp->target_auid[axp->pid_count] = audit_get_loginuid(t); | 2339 | axp->target_auid[axp->pid_count] = audit_get_loginuid(t); |
| 2273 | axp->target_uid[axp->pid_count] = t_uid; | 2340 | axp->target_uid[axp->pid_count] = t_uid; |
| 2274 | axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); | 2341 | axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); |
| @@ -2368,7 +2435,7 @@ static void audit_log_task(struct audit_buffer *ab) | |||
| 2368 | from_kgid(&init_user_ns, gid), | 2435 | from_kgid(&init_user_ns, gid), |
| 2369 | sessionid); | 2436 | sessionid); |
| 2370 | audit_log_task_context(ab); | 2437 | audit_log_task_context(ab); |
| 2371 | audit_log_format(ab, " pid=%d comm=", current->pid); | 2438 | audit_log_format(ab, " pid=%d comm=", task_pid_nr(current)); |
| 2372 | audit_log_untrustedstring(ab, current->comm); | 2439 | audit_log_untrustedstring(ab, current->comm); |
| 2373 | if (mm) { | 2440 | if (mm) { |
| 2374 | down_read(&mm->mmap_sem); | 2441 | down_read(&mm->mmap_sem); |
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index fd609bd9d6dd..d8d046c0726a 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
| @@ -71,7 +71,7 @@ static void populate_seccomp_data(struct seccomp_data *sd) | |||
| 71 | struct pt_regs *regs = task_pt_regs(task); | 71 | struct pt_regs *regs = task_pt_regs(task); |
| 72 | 72 | ||
| 73 | sd->nr = syscall_get_nr(task, regs); | 73 | sd->nr = syscall_get_nr(task, regs); |
| 74 | sd->arch = syscall_get_arch(task, regs); | 74 | sd->arch = syscall_get_arch(); |
| 75 | 75 | ||
| 76 | /* Unroll syscall_get_args to help gcc on arm. */ | 76 | /* Unroll syscall_get_args to help gcc on arm. */ |
| 77 | syscall_get_arguments(task, regs, 0, 1, (unsigned long *) &sd->args[0]); | 77 | syscall_get_arguments(task, regs, 0, 1, (unsigned long *) &sd->args[0]); |
| @@ -348,7 +348,7 @@ static void seccomp_send_sigsys(int syscall, int reason) | |||
| 348 | info.si_code = SYS_SECCOMP; | 348 | info.si_code = SYS_SECCOMP; |
| 349 | info.si_call_addr = (void __user *)KSTK_EIP(current); | 349 | info.si_call_addr = (void __user *)KSTK_EIP(current); |
| 350 | info.si_errno = reason; | 350 | info.si_errno = reason; |
| 351 | info.si_arch = syscall_get_arch(current, task_pt_regs(current)); | 351 | info.si_arch = syscall_get_arch(); |
| 352 | info.si_syscall = syscall; | 352 | info.si_syscall = syscall; |
| 353 | force_sig_info(SIGSYS, &info, current); | 353 | force_sig_info(SIGSYS, &info, current); |
| 354 | } | 354 | } |
