diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-30 11:35:35 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-30 11:35:35 -0400 |
| commit | 847f877600313e65c5659476b30d74a6f66e388e (patch) | |
| tree | b4390fb56dc3c9a47cb51f3a086515a376cffc0c | |
| parent | 79346507ad48895f41b438fa562b1965721f36b9 (diff) | |
| parent | 120a795da07c9a02221ca23464c28a7c6ad7de1d (diff) | |
Merge branch 'audit.b64' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current
* 'audit.b64' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current:
audit mmap
audit: make link()/linkat() match "attribute change" predicate
audit: Use rcu for task lookup protection
audit: Do not send uninitialized data for AUDIT_TTY_GET
audit: Call tty_audit_push_task() outside preempt disabled
in untag_chunk() we need to do alloc_chunk() a bit earlier
audit: make functions static
Audit: add support to match lsm labels on user audit messages
| -rw-r--r-- | drivers/char/tty_audit.c | 38 | ||||
| -rw-r--r-- | include/asm-generic/audit_change_attr.h | 4 | ||||
| -rw-r--r-- | include/linux/audit.h | 9 | ||||
| -rw-r--r-- | include/linux/tty.h | 9 | ||||
| -rw-r--r-- | kernel/audit.c | 67 | ||||
| -rw-r--r-- | kernel/audit.h | 5 | ||||
| -rw-r--r-- | kernel/audit_tree.c | 9 | ||||
| -rw-r--r-- | kernel/audit_watch.c | 4 | ||||
| -rw-r--r-- | kernel/auditfilter.c | 12 | ||||
| -rw-r--r-- | kernel/auditsc.c | 16 | ||||
| -rw-r--r-- | mm/mmap.c | 2 | ||||
| -rw-r--r-- | mm/nommu.c | 2 |
12 files changed, 118 insertions, 59 deletions
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c index 1b8ee590b4ca..f64582b0f623 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/char/tty_audit.c | |||
| @@ -188,25 +188,43 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch) | |||
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | /** | 190 | /** |
| 191 | * tty_audit_push_task - Flush task's pending audit data | 191 | * tty_audit_push_task - Flush task's pending audit data |
| 192 | * @tsk: task pointer | ||
| 193 | * @loginuid: sender login uid | ||
| 194 | * @sessionid: sender session id | ||
| 195 | * | ||
| 196 | * Called with a ref on @tsk held. Try to lock sighand and get a | ||
| 197 | * reference to the tty audit buffer if available. | ||
| 198 | * Flush the buffer or return an appropriate error code. | ||
| 192 | */ | 199 | */ |
| 193 | void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) | 200 | int tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) |
| 194 | { | 201 | { |
| 195 | struct tty_audit_buf *buf; | 202 | struct tty_audit_buf *buf = ERR_PTR(-EPERM); |
| 203 | unsigned long flags; | ||
| 196 | 204 | ||
| 197 | spin_lock_irq(&tsk->sighand->siglock); | 205 | if (!lock_task_sighand(tsk, &flags)) |
| 198 | buf = tsk->signal->tty_audit_buf; | 206 | return -ESRCH; |
| 199 | if (buf) | 207 | |
| 200 | atomic_inc(&buf->count); | 208 | if (tsk->signal->audit_tty) { |
| 201 | spin_unlock_irq(&tsk->sighand->siglock); | 209 | buf = tsk->signal->tty_audit_buf; |
| 202 | if (!buf) | 210 | if (buf) |
| 203 | return; | 211 | atomic_inc(&buf->count); |
| 212 | } | ||
| 213 | unlock_task_sighand(tsk, &flags); | ||
| 214 | |||
| 215 | /* | ||
| 216 | * Return 0 when signal->audit_tty set | ||
| 217 | * but tsk->signal->tty_audit_buf == NULL. | ||
| 218 | */ | ||
| 219 | if (!buf || IS_ERR(buf)) | ||
| 220 | return PTR_ERR(buf); | ||
| 204 | 221 | ||
| 205 | mutex_lock(&buf->mutex); | 222 | mutex_lock(&buf->mutex); |
| 206 | tty_audit_buf_push(tsk, loginuid, sessionid, buf); | 223 | tty_audit_buf_push(tsk, loginuid, sessionid, buf); |
| 207 | mutex_unlock(&buf->mutex); | 224 | mutex_unlock(&buf->mutex); |
| 208 | 225 | ||
| 209 | tty_audit_buf_put(buf); | 226 | tty_audit_buf_put(buf); |
| 227 | return 0; | ||
| 210 | } | 228 | } |
| 211 | 229 | ||
| 212 | /** | 230 | /** |
diff --git a/include/asm-generic/audit_change_attr.h b/include/asm-generic/audit_change_attr.h index 50764550a60c..bcbab3e4a3be 100644 --- a/include/asm-generic/audit_change_attr.h +++ b/include/asm-generic/audit_change_attr.h | |||
| @@ -20,3 +20,7 @@ __NR_chown32, | |||
| 20 | __NR_fchown32, | 20 | __NR_fchown32, |
| 21 | __NR_lchown32, | 21 | __NR_lchown32, |
| 22 | #endif | 22 | #endif |
| 23 | __NR_link, | ||
| 24 | #ifdef __NR_linkat | ||
| 25 | __NR_linkat, | ||
| 26 | #endif | ||
diff --git a/include/linux/audit.h b/include/linux/audit.h index e24afabc548f..8b5c0620abf9 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
| @@ -102,6 +102,7 @@ | |||
| 102 | #define AUDIT_EOE 1320 /* End of multi-record event */ | 102 | #define AUDIT_EOE 1320 /* End of multi-record event */ |
| 103 | #define AUDIT_BPRM_FCAPS 1321 /* Information about fcaps increasing perms */ | 103 | #define AUDIT_BPRM_FCAPS 1321 /* Information about fcaps increasing perms */ |
| 104 | #define AUDIT_CAPSET 1322 /* Record showing argument to sys_capset */ | 104 | #define AUDIT_CAPSET 1322 /* Record showing argument to sys_capset */ |
| 105 | #define AUDIT_MMAP 1323 /* Record showing descriptor and flags in mmap */ | ||
| 105 | 106 | ||
| 106 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ | 107 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ |
| 107 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ | 108 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ |
| @@ -478,6 +479,7 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, | |||
| 478 | const struct cred *new, | 479 | const struct cred *new, |
| 479 | const struct cred *old); | 480 | const struct cred *old); |
| 480 | extern void __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old); | 481 | extern void __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old); |
| 482 | extern void __audit_mmap_fd(int fd, int flags); | ||
| 481 | 483 | ||
| 482 | static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) | 484 | static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) |
| 483 | { | 485 | { |
| @@ -531,6 +533,12 @@ static inline void audit_log_capset(pid_t pid, const struct cred *new, | |||
| 531 | __audit_log_capset(pid, new, old); | 533 | __audit_log_capset(pid, new, old); |
| 532 | } | 534 | } |
| 533 | 535 | ||
| 536 | static inline void audit_mmap_fd(int fd, int flags) | ||
| 537 | { | ||
| 538 | if (unlikely(!audit_dummy_context())) | ||
| 539 | __audit_mmap_fd(fd, flags); | ||
| 540 | } | ||
| 541 | |||
| 534 | extern int audit_n_rules; | 542 | extern int audit_n_rules; |
| 535 | extern int audit_signals; | 543 | extern int audit_signals; |
| 536 | #else | 544 | #else |
| @@ -564,6 +572,7 @@ extern int audit_signals; | |||
| 564 | #define audit_mq_getsetattr(d,s) ((void)0) | 572 | #define audit_mq_getsetattr(d,s) ((void)0) |
| 565 | #define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; }) | 573 | #define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; }) |
| 566 | #define audit_log_capset(pid, ncr, ocr) ((void)0) | 574 | #define audit_log_capset(pid, ncr, ocr) ((void)0) |
| 575 | #define audit_mmap_fd(fd, flags) ((void)0) | ||
| 567 | #define audit_ptrace(t) ((void)0) | 576 | #define audit_ptrace(t) ((void)0) |
| 568 | #define audit_n_rules 0 | 577 | #define audit_n_rules 0 |
| 569 | #define audit_signals 0 | 578 | #define audit_signals 0 |
diff --git a/include/linux/tty.h b/include/linux/tty.h index e500171c745f..2a754748dd5f 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -541,8 +541,8 @@ extern void tty_audit_exit(void); | |||
| 541 | extern void tty_audit_fork(struct signal_struct *sig); | 541 | extern void tty_audit_fork(struct signal_struct *sig); |
| 542 | extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); | 542 | extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); |
| 543 | extern void tty_audit_push(struct tty_struct *tty); | 543 | extern void tty_audit_push(struct tty_struct *tty); |
| 544 | extern void tty_audit_push_task(struct task_struct *tsk, | 544 | extern int tty_audit_push_task(struct task_struct *tsk, |
| 545 | uid_t loginuid, u32 sessionid); | 545 | uid_t loginuid, u32 sessionid); |
| 546 | #else | 546 | #else |
| 547 | static inline void tty_audit_add_data(struct tty_struct *tty, | 547 | static inline void tty_audit_add_data(struct tty_struct *tty, |
| 548 | unsigned char *data, size_t size) | 548 | unsigned char *data, size_t size) |
| @@ -560,9 +560,10 @@ static inline void tty_audit_fork(struct signal_struct *sig) | |||
| 560 | static inline void tty_audit_push(struct tty_struct *tty) | 560 | static inline void tty_audit_push(struct tty_struct *tty) |
| 561 | { | 561 | { |
| 562 | } | 562 | } |
| 563 | static inline void tty_audit_push_task(struct task_struct *tsk, | 563 | static inline int tty_audit_push_task(struct task_struct *tsk, |
| 564 | uid_t loginuid, u32 sessionid) | 564 | uid_t loginuid, u32 sessionid) |
| 565 | { | 565 | { |
| 566 | return 0; | ||
| 566 | } | 567 | } |
| 567 | #endif | 568 | #endif |
| 568 | 569 | ||
diff --git a/kernel/audit.c b/kernel/audit.c index d96045789b54..77770a034d59 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -467,23 +467,16 @@ static int audit_prepare_user_tty(pid_t pid, uid_t loginuid, u32 sessionid) | |||
| 467 | struct task_struct *tsk; | 467 | struct task_struct *tsk; |
| 468 | int err; | 468 | int err; |
| 469 | 469 | ||
| 470 | read_lock(&tasklist_lock); | 470 | rcu_read_lock(); |
| 471 | tsk = find_task_by_vpid(pid); | 471 | tsk = find_task_by_vpid(pid); |
| 472 | err = -ESRCH; | 472 | if (!tsk) { |
| 473 | if (!tsk) | 473 | rcu_read_unlock(); |
| 474 | goto out; | 474 | return -ESRCH; |
| 475 | err = 0; | 475 | } |
| 476 | 476 | get_task_struct(tsk); | |
| 477 | spin_lock_irq(&tsk->sighand->siglock); | 477 | rcu_read_unlock(); |
| 478 | if (!tsk->signal->audit_tty) | 478 | err = tty_audit_push_task(tsk, loginuid, sessionid); |
| 479 | err = -EPERM; | 479 | put_task_struct(tsk); |
| 480 | spin_unlock_irq(&tsk->sighand->siglock); | ||
| 481 | if (err) | ||
| 482 | goto out; | ||
| 483 | |||
| 484 | tty_audit_push_task(tsk, loginuid, sessionid); | ||
| 485 | out: | ||
| 486 | read_unlock(&tasklist_lock); | ||
| 487 | return err; | 480 | return err; |
| 488 | } | 481 | } |
| 489 | 482 | ||
| @@ -506,7 +499,7 @@ int audit_send_list(void *_dest) | |||
| 506 | } | 499 | } |
| 507 | 500 | ||
| 508 | struct sk_buff *audit_make_reply(int pid, int seq, int type, int done, | 501 | struct sk_buff *audit_make_reply(int pid, int seq, int type, int done, |
| 509 | int multi, void *payload, int size) | 502 | int multi, const void *payload, int size) |
| 510 | { | 503 | { |
| 511 | struct sk_buff *skb; | 504 | struct sk_buff *skb; |
| 512 | struct nlmsghdr *nlh; | 505 | struct nlmsghdr *nlh; |
| @@ -555,8 +548,8 @@ static int audit_send_reply_thread(void *arg) | |||
| 555 | * Allocates an skb, builds the netlink message, and sends it to the pid. | 548 | * Allocates an skb, builds the netlink message, and sends it to the pid. |
| 556 | * No failure notifications. | 549 | * No failure notifications. |
| 557 | */ | 550 | */ |
| 558 | void audit_send_reply(int pid, int seq, int type, int done, int multi, | 551 | static void audit_send_reply(int pid, int seq, int type, int done, int multi, |
| 559 | void *payload, int size) | 552 | const void *payload, int size) |
| 560 | { | 553 | { |
| 561 | struct sk_buff *skb; | 554 | struct sk_buff *skb; |
| 562 | struct task_struct *tsk; | 555 | struct task_struct *tsk; |
| @@ -880,40 +873,40 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 880 | case AUDIT_TTY_GET: { | 873 | case AUDIT_TTY_GET: { |
| 881 | struct audit_tty_status s; | 874 | struct audit_tty_status s; |
| 882 | struct task_struct *tsk; | 875 | struct task_struct *tsk; |
| 876 | unsigned long flags; | ||
| 883 | 877 | ||
| 884 | read_lock(&tasklist_lock); | 878 | rcu_read_lock(); |
| 885 | tsk = find_task_by_vpid(pid); | 879 | tsk = find_task_by_vpid(pid); |
| 886 | if (!tsk) | 880 | if (tsk && lock_task_sighand(tsk, &flags)) { |
| 887 | err = -ESRCH; | ||
| 888 | else { | ||
| 889 | spin_lock_irq(&tsk->sighand->siglock); | ||
| 890 | s.enabled = tsk->signal->audit_tty != 0; | 881 | s.enabled = tsk->signal->audit_tty != 0; |
| 891 | spin_unlock_irq(&tsk->sighand->siglock); | 882 | unlock_task_sighand(tsk, &flags); |
| 892 | } | 883 | } else |
| 893 | read_unlock(&tasklist_lock); | 884 | err = -ESRCH; |
| 894 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_TTY_GET, 0, 0, | 885 | rcu_read_unlock(); |
| 895 | &s, sizeof(s)); | 886 | |
| 887 | if (!err) | ||
| 888 | audit_send_reply(NETLINK_CB(skb).pid, seq, | ||
| 889 | AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); | ||
| 896 | break; | 890 | break; |
| 897 | } | 891 | } |
| 898 | case AUDIT_TTY_SET: { | 892 | case AUDIT_TTY_SET: { |
| 899 | struct audit_tty_status *s; | 893 | struct audit_tty_status *s; |
| 900 | struct task_struct *tsk; | 894 | struct task_struct *tsk; |
| 895 | unsigned long flags; | ||
| 901 | 896 | ||
| 902 | if (nlh->nlmsg_len < sizeof(struct audit_tty_status)) | 897 | if (nlh->nlmsg_len < sizeof(struct audit_tty_status)) |
| 903 | return -EINVAL; | 898 | return -EINVAL; |
| 904 | s = data; | 899 | s = data; |
| 905 | if (s->enabled != 0 && s->enabled != 1) | 900 | if (s->enabled != 0 && s->enabled != 1) |
| 906 | return -EINVAL; | 901 | return -EINVAL; |
| 907 | read_lock(&tasklist_lock); | 902 | rcu_read_lock(); |
| 908 | tsk = find_task_by_vpid(pid); | 903 | tsk = find_task_by_vpid(pid); |
| 909 | if (!tsk) | 904 | if (tsk && lock_task_sighand(tsk, &flags)) { |
| 910 | err = -ESRCH; | ||
| 911 | else { | ||
| 912 | spin_lock_irq(&tsk->sighand->siglock); | ||
| 913 | tsk->signal->audit_tty = s->enabled != 0; | 905 | tsk->signal->audit_tty = s->enabled != 0; |
| 914 | spin_unlock_irq(&tsk->sighand->siglock); | 906 | unlock_task_sighand(tsk, &flags); |
| 915 | } | 907 | } else |
| 916 | read_unlock(&tasklist_lock); | 908 | err = -ESRCH; |
| 909 | rcu_read_unlock(); | ||
| 917 | break; | 910 | break; |
| 918 | } | 911 | } |
| 919 | default: | 912 | default: |
diff --git a/kernel/audit.h b/kernel/audit.h index f7206db4e13d..91e7071c4d2c 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
| @@ -84,10 +84,7 @@ extern int audit_compare_dname_path(const char *dname, const char *path, | |||
| 84 | int *dirlen); | 84 | int *dirlen); |
| 85 | extern struct sk_buff * audit_make_reply(int pid, int seq, int type, | 85 | extern struct sk_buff * audit_make_reply(int pid, int seq, int type, |
| 86 | int done, int multi, | 86 | int done, int multi, |
| 87 | void *payload, int size); | 87 | const void *payload, int size); |
| 88 | extern void audit_send_reply(int pid, int seq, int type, | ||
| 89 | int done, int multi, | ||
| 90 | void *payload, int size); | ||
| 91 | extern void audit_panic(const char *message); | 88 | extern void audit_panic(const char *message); |
| 92 | 89 | ||
| 93 | struct audit_netlink_list { | 90 | struct audit_netlink_list { |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 7f18d3a4527e..37b2bea170c8 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
| @@ -223,7 +223,7 @@ static void untag_chunk(struct node *p) | |||
| 223 | { | 223 | { |
| 224 | struct audit_chunk *chunk = find_chunk(p); | 224 | struct audit_chunk *chunk = find_chunk(p); |
| 225 | struct fsnotify_mark *entry = &chunk->mark; | 225 | struct fsnotify_mark *entry = &chunk->mark; |
| 226 | struct audit_chunk *new; | 226 | struct audit_chunk *new = NULL; |
| 227 | struct audit_tree *owner; | 227 | struct audit_tree *owner; |
| 228 | int size = chunk->count - 1; | 228 | int size = chunk->count - 1; |
| 229 | int i, j; | 229 | int i, j; |
| @@ -232,9 +232,14 @@ static void untag_chunk(struct node *p) | |||
| 232 | 232 | ||
| 233 | spin_unlock(&hash_lock); | 233 | spin_unlock(&hash_lock); |
| 234 | 234 | ||
| 235 | if (size) | ||
| 236 | new = alloc_chunk(size); | ||
| 237 | |||
| 235 | spin_lock(&entry->lock); | 238 | spin_lock(&entry->lock); |
| 236 | if (chunk->dead || !entry->i.inode) { | 239 | if (chunk->dead || !entry->i.inode) { |
| 237 | spin_unlock(&entry->lock); | 240 | spin_unlock(&entry->lock); |
| 241 | if (new) | ||
| 242 | free_chunk(new); | ||
| 238 | goto out; | 243 | goto out; |
| 239 | } | 244 | } |
| 240 | 245 | ||
| @@ -255,9 +260,9 @@ static void untag_chunk(struct node *p) | |||
| 255 | goto out; | 260 | goto out; |
| 256 | } | 261 | } |
| 257 | 262 | ||
| 258 | new = alloc_chunk(size); | ||
| 259 | if (!new) | 263 | if (!new) |
| 260 | goto Fallback; | 264 | goto Fallback; |
| 265 | |||
| 261 | fsnotify_duplicate_mark(&new->mark, entry); | 266 | fsnotify_duplicate_mark(&new->mark, entry); |
| 262 | if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, NULL, 1)) { | 267 | if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, NULL, 1)) { |
| 263 | free_chunk(new); | 268 | free_chunk(new); |
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index f0c9b2e7542d..d2e3c7866460 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c | |||
| @@ -60,7 +60,7 @@ struct audit_parent { | |||
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | /* fsnotify handle. */ | 62 | /* fsnotify handle. */ |
| 63 | struct fsnotify_group *audit_watch_group; | 63 | static struct fsnotify_group *audit_watch_group; |
| 64 | 64 | ||
| 65 | /* fsnotify events we care about. */ | 65 | /* fsnotify events we care about. */ |
| 66 | #define AUDIT_FS_WATCH (FS_MOVE | FS_CREATE | FS_DELETE | FS_DELETE_SELF |\ | 66 | #define AUDIT_FS_WATCH (FS_MOVE | FS_CREATE | FS_DELETE | FS_DELETE_SELF |\ |
| @@ -123,7 +123,7 @@ void audit_put_watch(struct audit_watch *watch) | |||
| 123 | } | 123 | } |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | void audit_remove_watch(struct audit_watch *watch) | 126 | static void audit_remove_watch(struct audit_watch *watch) |
| 127 | { | 127 | { |
| 128 | list_del(&watch->wlist); | 128 | list_del(&watch->wlist); |
| 129 | audit_put_parent(watch->parent); | 129 | audit_put_parent(watch->parent); |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index eb7675499fb5..add2819af71b 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
| @@ -1252,6 +1252,18 @@ static int audit_filter_user_rules(struct netlink_skb_parms *cb, | |||
| 1252 | case AUDIT_LOGINUID: | 1252 | case AUDIT_LOGINUID: |
| 1253 | result = audit_comparator(cb->loginuid, f->op, f->val); | 1253 | result = audit_comparator(cb->loginuid, f->op, f->val); |
| 1254 | break; | 1254 | break; |
| 1255 | case AUDIT_SUBJ_USER: | ||
| 1256 | case AUDIT_SUBJ_ROLE: | ||
| 1257 | case AUDIT_SUBJ_TYPE: | ||
| 1258 | case AUDIT_SUBJ_SEN: | ||
| 1259 | case AUDIT_SUBJ_CLR: | ||
| 1260 | if (f->lsm_rule) | ||
| 1261 | result = security_audit_rule_match(cb->sid, | ||
| 1262 | f->type, | ||
| 1263 | f->op, | ||
| 1264 | f->lsm_rule, | ||
| 1265 | NULL); | ||
| 1266 | break; | ||
| 1255 | } | 1267 | } |
| 1256 | 1268 | ||
| 1257 | if (!result) | 1269 | if (!result) |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 1b31c130d034..f49a0318c2ed 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -241,6 +241,10 @@ struct audit_context { | |||
| 241 | pid_t pid; | 241 | pid_t pid; |
| 242 | struct audit_cap_data cap; | 242 | struct audit_cap_data cap; |
| 243 | } capset; | 243 | } capset; |
| 244 | struct { | ||
| 245 | int fd; | ||
| 246 | int flags; | ||
| 247 | } mmap; | ||
| 244 | }; | 248 | }; |
| 245 | int fds[2]; | 249 | int fds[2]; |
| 246 | 250 | ||
| @@ -1305,6 +1309,10 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
| 1305 | audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted); | 1309 | audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted); |
| 1306 | audit_log_cap(ab, "cap_pe", &context->capset.cap.effective); | 1310 | audit_log_cap(ab, "cap_pe", &context->capset.cap.effective); |
| 1307 | break; } | 1311 | break; } |
| 1312 | case AUDIT_MMAP: { | ||
| 1313 | audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd, | ||
| 1314 | context->mmap.flags); | ||
| 1315 | break; } | ||
| 1308 | } | 1316 | } |
| 1309 | audit_log_end(ab); | 1317 | audit_log_end(ab); |
| 1310 | } | 1318 | } |
| @@ -2476,6 +2484,14 @@ void __audit_log_capset(pid_t pid, | |||
| 2476 | context->type = AUDIT_CAPSET; | 2484 | context->type = AUDIT_CAPSET; |
| 2477 | } | 2485 | } |
| 2478 | 2486 | ||
| 2487 | void __audit_mmap_fd(int fd, int flags) | ||
| 2488 | { | ||
| 2489 | struct audit_context *context = current->audit_context; | ||
| 2490 | context->mmap.fd = fd; | ||
| 2491 | context->mmap.flags = flags; | ||
| 2492 | context->type = AUDIT_MMAP; | ||
| 2493 | } | ||
| 2494 | |||
| 2479 | /** | 2495 | /** |
| 2480 | * audit_core_dumps - record information about processes that end abnormally | 2496 | * audit_core_dumps - record information about processes that end abnormally |
| 2481 | * @signr: signal value | 2497 | * @signr: signal value |
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/rmap.h> | 28 | #include <linux/rmap.h> |
| 29 | #include <linux/mmu_notifier.h> | 29 | #include <linux/mmu_notifier.h> |
| 30 | #include <linux/perf_event.h> | 30 | #include <linux/perf_event.h> |
| 31 | #include <linux/audit.h> | ||
| 31 | 32 | ||
| 32 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
| 33 | #include <asm/cacheflush.h> | 34 | #include <asm/cacheflush.h> |
| @@ -1108,6 +1109,7 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, | |||
| 1108 | unsigned long retval = -EBADF; | 1109 | unsigned long retval = -EBADF; |
| 1109 | 1110 | ||
| 1110 | if (!(flags & MAP_ANONYMOUS)) { | 1111 | if (!(flags & MAP_ANONYMOUS)) { |
| 1112 | audit_mmap_fd(fd, flags); | ||
| 1111 | if (unlikely(flags & MAP_HUGETLB)) | 1113 | if (unlikely(flags & MAP_HUGETLB)) |
| 1112 | return -EINVAL; | 1114 | return -EINVAL; |
| 1113 | file = fget(fd); | 1115 | file = fget(fd); |
diff --git a/mm/nommu.c b/mm/nommu.c index 30b5c20eec15..3613517c7592 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/personality.h> | 29 | #include <linux/personality.h> |
| 30 | #include <linux/security.h> | 30 | #include <linux/security.h> |
| 31 | #include <linux/syscalls.h> | 31 | #include <linux/syscalls.h> |
| 32 | #include <linux/audit.h> | ||
| 32 | 33 | ||
| 33 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
| 34 | #include <asm/tlb.h> | 35 | #include <asm/tlb.h> |
| @@ -1458,6 +1459,7 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, | |||
| 1458 | struct file *file = NULL; | 1459 | struct file *file = NULL; |
| 1459 | unsigned long retval = -EBADF; | 1460 | unsigned long retval = -EBADF; |
| 1460 | 1461 | ||
| 1462 | audit_mmap_fd(fd, flags); | ||
| 1461 | if (!(flags & MAP_ANONYMOUS)) { | 1463 | if (!(flags & MAP_ANONYMOUS)) { |
| 1462 | file = fget(fd); | 1464 | file = fget(fd); |
| 1463 | if (!file) | 1465 | if (!file) |
