Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'audit.b63' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current

* 'audit.b63' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current:
Fix rule eviction order for AUDIT_DIR
Audit: clean up all op= output to include string quoting
Audit: move audit_get_nd completely into audit_watch
audit: seperate audit inode watches into a subfile
Audit: clean up audit_receive_skb
Audit: cleanup netlink mesg handling
Audit: unify the printk of an skb when auditd not around
Audit: dereferencing krule as if it were an audit_watch
Audit: better estimation of execve record length
Audit: fix audit watch use after free

+733 -621
+3
include/linux/audit.h
··· 599 599 extern void audit_log_d_path(struct audit_buffer *ab, 600 600 const char *prefix, 601 601 struct path *path); 602 + extern void audit_log_key(struct audit_buffer *ab, 603 + char *key); 602 604 extern void audit_log_lost(const char *message); 603 605 extern int audit_update_lsm_rules(void); 604 606 ··· 623 621 #define audit_log_n_untrustedstring(a,n,s) do { ; } while (0) 624 622 #define audit_log_untrustedstring(a,s) do { ; } while (0) 625 623 #define audit_log_d_path(b, p, d) do { ; } while (0) 624 + #define audit_log_key(b, k) do { ; } while (0) 626 625 #define audit_enabled 0 627 626 #endif 628 627 #endif
+1 -1
kernel/Makefile
··· 70 70 obj-$(CONFIG_STOP_MACHINE) += stop_machine.o 71 71 obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o 72 72 obj-$(CONFIG_AUDIT) += audit.o auditfilter.o 73 - obj-$(CONFIG_AUDITSYSCALL) += auditsc.o 73 + obj-$(CONFIG_AUDITSYSCALL) += auditsc.o audit_watch.o 74 74 obj-$(CONFIG_GCOV_KERNEL) += gcov/ 75 75 obj-$(CONFIG_AUDIT_TREE) += audit_tree.o 76 76 obj-$(CONFIG_KPROBES) += kprobes.o
+65 -81
kernel/audit.c
··· 115 115 /* The netlink socket. */ 116 116 static struct sock *audit_sock; 117 117 118 - /* Inotify handle. */ 119 - struct inotify_handle *audit_ih; 120 - 121 118 /* Hash for inode-based rules */ 122 119 struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; 123 120 ··· 133 136 static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); 134 137 135 138 /* Serialize requests from userspace. */ 136 - static DEFINE_MUTEX(audit_cmd_mutex); 139 + DEFINE_MUTEX(audit_cmd_mutex); 137 140 138 141 /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting 139 142 * audit records. Since printk uses a 1024 byte buffer, this buffer ··· 372 375 kfree_skb(skb); 373 376 } 374 377 378 + /* 379 + * For one reason or another this nlh isn't getting delivered to the userspace 380 + * audit daemon, just send it to printk. 381 + */ 382 + static void audit_printk_skb(struct sk_buff *skb) 383 + { 384 + struct nlmsghdr *nlh = nlmsg_hdr(skb); 385 + char *data = NLMSG_DATA(nlh); 386 + 387 + if (nlh->nlmsg_type != AUDIT_EOE) { 388 + if (printk_ratelimit()) 389 + printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, data); 390 + else 391 + audit_log_lost("printk limit exceeded\n"); 392 + } 393 + 394 + audit_hold_skb(skb); 395 + } 396 + 375 397 static void kauditd_send_skb(struct sk_buff *skb) 376 398 { 377 399 int err; ··· 443 427 if (skb) { 444 428 if (audit_pid) 445 429 kauditd_send_skb(skb); 446 - else { 447 - if (printk_ratelimit()) 448 - printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0)); 449 - else 450 - audit_log_lost("printk limit exceeded\n"); 451 - 452 - audit_hold_skb(skb); 453 - } 430 + else 431 + audit_printk_skb(skb); 454 432 } else { 455 433 DECLARE_WAITQUEUE(wait, current); 456 434 set_current_state(TASK_INTERRUPTIBLE); ··· 505 495 return 0; 506 496 } 507 497 508 - #ifdef CONFIG_AUDIT_TREE 509 - static int prune_tree_thread(void *unused) 510 - { 511 - mutex_lock(&audit_cmd_mutex); 512 - audit_prune_trees(); 513 - mutex_unlock(&audit_cmd_mutex); 514 - return 0; 515 - } 516 - 517 - void audit_schedule_prune(void) 518 - { 519 - kthread_run(prune_tree_thread, NULL, "audit_prune_tree"); 520 - } 521 - #endif 522 - 523 498 struct sk_buff *audit_make_reply(int pid, int seq, int type, int done, 524 499 int multi, void *payload, int size) 525 500 { 526 501 struct sk_buff *skb; 527 502 struct nlmsghdr *nlh; 528 - int len = NLMSG_SPACE(size); 529 503 void *data; 530 504 int flags = multi ? NLM_F_MULTI : 0; 531 505 int t = done ? NLMSG_DONE : type; 532 506 533 - skb = alloc_skb(len, GFP_KERNEL); 507 + skb = nlmsg_new(size, GFP_KERNEL); 534 508 if (!skb) 535 509 return NULL; 536 510 537 - nlh = NLMSG_PUT(skb, pid, seq, t, size); 538 - nlh->nlmsg_flags = flags; 539 - data = NLMSG_DATA(nlh); 511 + nlh = NLMSG_NEW(skb, pid, seq, t, size, flags); 512 + data = NLMSG_DATA(nlh); 540 513 memcpy(data, payload, size); 541 514 return skb; 542 515 543 - nlmsg_failure: /* Used by NLMSG_PUT */ 516 + nlmsg_failure: /* Used by NLMSG_NEW */ 544 517 if (skb) 545 518 kfree_skb(skb); 546 519 return NULL; ··· 919 926 } 920 927 921 928 /* 922 - * Get message from skb (based on rtnetlink_rcv_skb). Each message is 923 - * processed by audit_receive_msg. Malformed skbs with wrong length are 924 - * discarded silently. 929 + * Get message from skb. Each message is processed by audit_receive_msg. 930 + * Malformed skbs with wrong length are discarded silently. 925 931 */ 926 932 static void audit_receive_skb(struct sk_buff *skb) 927 933 { 928 - int err; 929 - struct nlmsghdr *nlh; 930 - u32 rlen; 934 + struct nlmsghdr *nlh; 935 + /* 936 + * len MUST be signed for NLMSG_NEXT to be able to dec it below 0 937 + * if the nlmsg_len was not aligned 938 + */ 939 + int len; 940 + int err; 931 941 932 - while (skb->len >= NLMSG_SPACE(0)) { 933 - nlh = nlmsg_hdr(skb); 934 - if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) 935 - return; 936 - rlen = NLMSG_ALIGN(nlh->nlmsg_len); 937 - if (rlen > skb->len) 938 - rlen = skb->len; 939 - if ((err = audit_receive_msg(skb, nlh))) { 942 + nlh = nlmsg_hdr(skb); 943 + len = skb->len; 944 + 945 + while (NLMSG_OK(nlh, len)) { 946 + err = audit_receive_msg(skb, nlh); 947 + /* if err or if this message says it wants a response */ 948 + if (err || (nlh->nlmsg_flags & NLM_F_ACK)) 940 949 netlink_ack(skb, nlh, err); 941 - } else if (nlh->nlmsg_flags & NLM_F_ACK) 942 - netlink_ack(skb, nlh, 0); 943 - skb_pull(skb, rlen); 950 + 951 + nlh = NLMSG_NEXT(nlh, len); 944 952 } 945 953 } 946 954 ··· 952 958 audit_receive_skb(skb); 953 959 mutex_unlock(&audit_cmd_mutex); 954 960 } 955 - 956 - #ifdef CONFIG_AUDITSYSCALL 957 - static const struct inotify_operations audit_inotify_ops = { 958 - .handle_event = audit_handle_ievent, 959 - .destroy_watch = audit_free_parent, 960 - }; 961 - #endif 962 961 963 962 /* Initialize audit support at boot time. */ 964 963 static int __init audit_init(void) ··· 977 990 audit_ever_enabled |= !!audit_default; 978 991 979 992 audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); 980 - 981 - #ifdef CONFIG_AUDITSYSCALL 982 - audit_ih = inotify_init(&audit_inotify_ops); 983 - if (IS_ERR(audit_ih)) 984 - audit_panic("cannot initialize inotify handle"); 985 - #endif 986 993 987 994 for (i = 0; i < AUDIT_INODE_BUCKETS; i++) 988 995 INIT_LIST_HEAD(&audit_inode_hash[i]); ··· 1051 1070 goto err; 1052 1071 } 1053 1072 1054 - ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask); 1055 - if (!ab->skb) 1056 - goto err; 1057 - 1058 1073 ab->ctx = ctx; 1059 1074 ab->gfp_mask = gfp_mask; 1060 - nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0)); 1061 - nlh->nlmsg_type = type; 1062 - nlh->nlmsg_flags = 0; 1063 - nlh->nlmsg_pid = 0; 1064 - nlh->nlmsg_seq = 0; 1075 + 1076 + ab->skb = nlmsg_new(AUDIT_BUFSIZ, gfp_mask); 1077 + if (!ab->skb) 1078 + goto nlmsg_failure; 1079 + 1080 + nlh = NLMSG_NEW(ab->skb, 0, 0, type, 0, 0); 1081 + 1065 1082 return ab; 1083 + 1084 + nlmsg_failure: /* Used by NLMSG_NEW */ 1085 + kfree_skb(ab->skb); 1086 + ab->skb = NULL; 1066 1087 err: 1067 1088 audit_buffer_free(ab); 1068 1089 return NULL; ··· 1435 1452 kfree(pathname); 1436 1453 } 1437 1454 1455 + void audit_log_key(struct audit_buffer *ab, char *key) 1456 + { 1457 + audit_log_format(ab, " key="); 1458 + if (key) 1459 + audit_log_untrustedstring(ab, key); 1460 + else 1461 + audit_log_format(ab, "(null)"); 1462 + } 1463 + 1438 1464 /** 1439 1465 * audit_log_end - end one audit record 1440 1466 * @ab: the audit_buffer ··· 1467 1475 skb_queue_tail(&audit_skb_queue, ab->skb); 1468 1476 wake_up_interruptible(&kauditd_wait); 1469 1477 } else { 1470 - if (nlh->nlmsg_type != AUDIT_EOE) { 1471 - if (printk_ratelimit()) { 1472 - printk(KERN_NOTICE "type=%d %s\n", 1473 - nlh->nlmsg_type, 1474 - ab->skb->data + NLMSG_SPACE(0)); 1475 - } else 1476 - audit_log_lost("printk limit exceeded\n"); 1477 - } 1478 - audit_hold_skb(ab->skb); 1478 + audit_printk_skb(ab->skb); 1479 1479 } 1480 1480 ab->skb = NULL; 1481 1481 }
+22 -21
kernel/audit.h
··· 53 53 }; 54 54 55 55 /* Rule lists */ 56 - struct audit_parent; 57 - 58 - struct audit_watch { 59 - atomic_t count; /* reference count */ 60 - char *path; /* insertion path */ 61 - dev_t dev; /* associated superblock device */ 62 - unsigned long ino; /* associated inode number */ 63 - struct audit_parent *parent; /* associated parent */ 64 - struct list_head wlist; /* entry in parent->watches list */ 65 - struct list_head rules; /* associated rules */ 66 - }; 67 - 56 + struct audit_watch; 68 57 struct audit_tree; 69 58 struct audit_chunk; 70 59 ··· 97 108 98 109 int audit_send_list(void *); 99 110 100 - struct inotify_watch; 101 - /* Inotify handle */ 102 - extern struct inotify_handle *audit_ih; 103 - 104 - extern void audit_free_parent(struct inotify_watch *); 105 - extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32, 106 - const char *, struct inode *); 107 111 extern int selinux_audit_rule_update(void); 108 112 109 113 extern struct mutex audit_filter_mutex; 110 114 extern void audit_free_rule_rcu(struct rcu_head *); 111 115 extern struct list_head audit_filter_list[]; 116 + 117 + /* audit watch functions */ 118 + extern unsigned long audit_watch_inode(struct audit_watch *watch); 119 + extern dev_t audit_watch_dev(struct audit_watch *watch); 120 + extern void audit_put_watch(struct audit_watch *watch); 121 + extern void audit_get_watch(struct audit_watch *watch); 122 + extern int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 op); 123 + extern int audit_add_watch(struct audit_krule *krule); 124 + extern void audit_remove_watch(struct audit_watch *watch); 125 + extern void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list); 126 + extern void audit_inotify_unregister(struct list_head *in_list); 127 + extern char *audit_watch_path(struct audit_watch *watch); 128 + extern struct list_head *audit_watch_rules(struct audit_watch *watch); 129 + 130 + extern struct audit_entry *audit_dupe_rule(struct audit_krule *old, 131 + struct audit_watch *watch); 112 132 113 133 #ifdef CONFIG_AUDIT_TREE 114 134 extern struct audit_chunk *audit_tree_lookup(const struct inode *); ··· 128 130 extern int audit_remove_tree_rule(struct audit_krule *); 129 131 extern void audit_trim_trees(void); 130 132 extern int audit_tag_tree(char *old, char *new); 131 - extern void audit_schedule_prune(void); 132 - extern void audit_prune_trees(void); 133 133 extern const char *audit_tree_path(struct audit_tree *); 134 134 extern void audit_put_tree(struct audit_tree *); 135 + extern void audit_kill_trees(struct list_head *); 135 136 #else 136 137 #define audit_remove_tree_rule(rule) BUG() 137 138 #define audit_add_tree_rule(rule) -EINVAL ··· 139 142 #define audit_put_tree(tree) (void)0 140 143 #define audit_tag_tree(old, new) -EINVAL 141 144 #define audit_tree_path(rule) "" /* never called */ 145 + #define audit_kill_trees(list) BUG() 142 146 #endif 143 147 144 148 extern char *audit_unpack_string(void **, size_t *, size_t); ··· 158 160 return 0; 159 161 } 160 162 extern void audit_filter_inodes(struct task_struct *, struct audit_context *); 163 + extern struct list_head *audit_killed_trees(void); 161 164 #else 162 165 #define audit_signal_info(s,t) AUDIT_DISABLED 163 166 #define audit_filter_inodes(t,c) AUDIT_DISABLED 164 167 #endif 168 + 169 + extern struct mutex audit_cmd_mutex;
+55 -11
kernel/audit_tree.c
··· 2 2 #include <linux/inotify.h> 3 3 #include <linux/namei.h> 4 4 #include <linux/mount.h> 5 + #include <linux/kthread.h> 5 6 6 7 struct audit_tree; 7 8 struct audit_chunk; ··· 442 441 if (rule->tree) { 443 442 /* not a half-baked one */ 444 443 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); 445 - audit_log_format(ab, "op=remove rule dir="); 444 + audit_log_format(ab, "op="); 445 + audit_log_string(ab, "remove rule"); 446 + audit_log_format(ab, " dir="); 446 447 audit_log_untrustedstring(ab, rule->tree->pathname); 447 - if (rule->filterkey) { 448 - audit_log_format(ab, " key="); 449 - audit_log_untrustedstring(ab, rule->filterkey); 450 - } else 451 - audit_log_format(ab, " key=(null)"); 448 + audit_log_key(ab, rule->filterkey); 452 449 audit_log_format(ab, " list=%d res=1", rule->listnr); 453 450 audit_log_end(ab); 454 451 rule->tree = NULL; ··· 517 518 spin_unlock(&hash_lock); 518 519 } 519 520 } 521 + 522 + static void audit_schedule_prune(void); 520 523 521 524 /* called with audit_filter_mutex */ 522 525 int audit_remove_tree_rule(struct audit_krule *rule) ··· 825 824 826 825 /* 827 826 * That gets run when evict_chunk() ends up needing to kill audit_tree. 828 - * Runs from a separate thread, with audit_cmd_mutex held. 827 + * Runs from a separate thread. 829 828 */ 830 - void audit_prune_trees(void) 829 + static int prune_tree_thread(void *unused) 831 830 { 831 + mutex_lock(&audit_cmd_mutex); 832 832 mutex_lock(&audit_filter_mutex); 833 833 834 834 while (!list_empty(&prune_list)) { ··· 846 844 } 847 845 848 846 mutex_unlock(&audit_filter_mutex); 847 + mutex_unlock(&audit_cmd_mutex); 848 + return 0; 849 + } 850 + 851 + static void audit_schedule_prune(void) 852 + { 853 + kthread_run(prune_tree_thread, NULL, "audit_prune_tree"); 854 + } 855 + 856 + /* 857 + * ... and that one is done if evict_chunk() decides to delay until the end 858 + * of syscall. Runs synchronously. 859 + */ 860 + void audit_kill_trees(struct list_head *list) 861 + { 862 + mutex_lock(&audit_cmd_mutex); 863 + mutex_lock(&audit_filter_mutex); 864 + 865 + while (!list_empty(list)) { 866 + struct audit_tree *victim; 867 + 868 + victim = list_entry(list->next, struct audit_tree, list); 869 + kill_rules(victim); 870 + list_del_init(&victim->list); 871 + 872 + mutex_unlock(&audit_filter_mutex); 873 + 874 + prune_one(victim); 875 + 876 + mutex_lock(&audit_filter_mutex); 877 + } 878 + 879 + mutex_unlock(&audit_filter_mutex); 880 + mutex_unlock(&audit_cmd_mutex); 849 881 } 850 882 851 883 /* ··· 890 854 static void evict_chunk(struct audit_chunk *chunk) 891 855 { 892 856 struct audit_tree *owner; 857 + struct list_head *postponed = audit_killed_trees(); 858 + int need_prune = 0; 893 859 int n; 894 860 895 861 if (chunk->dead) ··· 907 869 owner->root = NULL; 908 870 list_del_init(&owner->same_root); 909 871 spin_unlock(&hash_lock); 910 - kill_rules(owner); 911 - list_move(&owner->list, &prune_list); 912 - audit_schedule_prune(); 872 + if (!postponed) { 873 + kill_rules(owner); 874 + list_move(&owner->list, &prune_list); 875 + need_prune = 1; 876 + } else { 877 + list_move(&owner->list, postponed); 878 + } 913 879 spin_lock(&hash_lock); 914 880 } 915 881 list_del_rcu(&chunk->hash); 916 882 for (n = 0; n < chunk->count; n++) 917 883 list_del_init(&chunk->owners[n].list); 918 884 spin_unlock(&hash_lock); 885 + if (need_prune) 886 + audit_schedule_prune(); 919 887 mutex_unlock(&audit_filter_mutex); 920 888 } 921 889
+543
kernel/audit_watch.c
··· 1 + /* audit_watch.c -- watching inodes 2 + * 3 + * Copyright 2003-2009 Red Hat, Inc. 4 + * Copyright 2005 Hewlett-Packard Development Company, L.P. 5 + * Copyright 2005 IBM Corporation 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #include <linux/kernel.h> 23 + #include <linux/audit.h> 24 + #include <linux/kthread.h> 25 + #include <linux/mutex.h> 26 + #include <linux/fs.h> 27 + #include <linux/namei.h> 28 + #include <linux/netlink.h> 29 + #include <linux/sched.h> 30 + #include <linux/inotify.h> 31 + #include <linux/security.h> 32 + #include "audit.h" 33 + 34 + /* 35 + * Reference counting: 36 + * 37 + * audit_parent: lifetime is from audit_init_parent() to receipt of an IN_IGNORED 38 + * event. Each audit_watch holds a reference to its associated parent. 39 + * 40 + * audit_watch: if added to lists, lifetime is from audit_init_watch() to 41 + * audit_remove_watch(). Additionally, an audit_watch may exist 42 + * temporarily to assist in searching existing filter data. Each 43 + * audit_krule holds a reference to its associated watch. 44 + */ 45 + 46 + struct audit_watch { 47 + atomic_t count; /* reference count */ 48 + char *path; /* insertion path */ 49 + dev_t dev; /* associated superblock device */ 50 + unsigned long ino; /* associated inode number */ 51 + struct audit_parent *parent; /* associated parent */ 52 + struct list_head wlist; /* entry in parent->watches list */ 53 + struct list_head rules; /* associated rules */ 54 + }; 55 + 56 + struct audit_parent { 57 + struct list_head ilist; /* entry in inotify registration list */ 58 + struct list_head watches; /* associated watches */ 59 + struct inotify_watch wdata; /* inotify watch data */ 60 + unsigned flags; /* status flags */ 61 + }; 62 + 63 + /* Inotify handle. */ 64 + struct inotify_handle *audit_ih; 65 + 66 + /* 67 + * audit_parent status flags: 68 + * 69 + * AUDIT_PARENT_INVALID - set anytime rules/watches are auto-removed due to 70 + * a filesystem event to ensure we're adding audit watches to a valid parent. 71 + * Technically not needed for IN_DELETE_SELF or IN_UNMOUNT events, as we cannot 72 + * receive them while we have nameidata, but must be used for IN_MOVE_SELF which 73 + * we can receive while holding nameidata. 74 + */ 75 + #define AUDIT_PARENT_INVALID 0x001 76 + 77 + /* Inotify events we care about. */ 78 + #define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF 79 + 80 + static void audit_free_parent(struct inotify_watch *i_watch) 81 + { 82 + struct audit_parent *parent; 83 + 84 + parent = container_of(i_watch, struct audit_parent, wdata); 85 + WARN_ON(!list_empty(&parent->watches)); 86 + kfree(parent); 87 + } 88 + 89 + void audit_get_watch(struct audit_watch *watch) 90 + { 91 + atomic_inc(&watch->count); 92 + } 93 + 94 + void audit_put_watch(struct audit_watch *watch) 95 + { 96 + if (atomic_dec_and_test(&watch->count)) { 97 + WARN_ON(watch->parent); 98 + WARN_ON(!list_empty(&watch->rules)); 99 + kfree(watch->path); 100 + kfree(watch); 101 + } 102 + } 103 + 104 + void audit_remove_watch(struct audit_watch *watch) 105 + { 106 + list_del(&watch->wlist); 107 + put_inotify_watch(&watch->parent->wdata); 108 + watch->parent = NULL; 109 + audit_put_watch(watch); /* match initial get */ 110 + } 111 + 112 + char *audit_watch_path(struct audit_watch *watch) 113 + { 114 + return watch->path; 115 + } 116 + 117 + struct list_head *audit_watch_rules(struct audit_watch *watch) 118 + { 119 + return &watch->rules; 120 + } 121 + 122 + unsigned long audit_watch_inode(struct audit_watch *watch) 123 + { 124 + return watch->ino; 125 + } 126 + 127 + dev_t audit_watch_dev(struct audit_watch *watch) 128 + { 129 + return watch->dev; 130 + } 131 + 132 + /* Initialize a parent watch entry. */ 133 + static struct audit_parent *audit_init_parent(struct nameidata *ndp) 134 + { 135 + struct audit_parent *parent; 136 + s32 wd; 137 + 138 + parent = kzalloc(sizeof(*parent), GFP_KERNEL); 139 + if (unlikely(!parent)) 140 + return ERR_PTR(-ENOMEM); 141 + 142 + INIT_LIST_HEAD(&parent->watches); 143 + parent->flags = 0; 144 + 145 + inotify_init_watch(&parent->wdata); 146 + /* grab a ref so inotify watch hangs around until we take audit_filter_mutex */ 147 + get_inotify_watch(&parent->wdata); 148 + wd = inotify_add_watch(audit_ih, &parent->wdata, 149 + ndp->path.dentry->d_inode, AUDIT_IN_WATCH); 150 + if (wd < 0) { 151 + audit_free_parent(&parent->wdata); 152 + return ERR_PTR(wd); 153 + } 154 + 155 + return parent; 156 + } 157 + 158 + /* Initialize a watch entry. */ 159 + static struct audit_watch *audit_init_watch(char *path) 160 + { 161 + struct audit_watch *watch; 162 + 163 + watch = kzalloc(sizeof(*watch), GFP_KERNEL); 164 + if (unlikely(!watch)) 165 + return ERR_PTR(-ENOMEM); 166 + 167 + INIT_LIST_HEAD(&watch->rules); 168 + atomic_set(&watch->count, 1); 169 + watch->path = path; 170 + watch->dev = (dev_t)-1; 171 + watch->ino = (unsigned long)-1; 172 + 173 + return watch; 174 + } 175 + 176 + /* Translate a watch string to kernel respresentation. */ 177 + int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 op) 178 + { 179 + struct audit_watch *watch; 180 + 181 + if (!audit_ih) 182 + return -EOPNOTSUPP; 183 + 184 + if (path[0] != '/' || path[len-1] == '/' || 185 + krule->listnr != AUDIT_FILTER_EXIT || 186 + op != Audit_equal || 187 + krule->inode_f || krule->watch || krule->tree) 188 + return -EINVAL; 189 + 190 + watch = audit_init_watch(path); 191 + if (IS_ERR(watch)) 192 + return PTR_ERR(watch); 193 + 194 + audit_get_watch(watch); 195 + krule->watch = watch; 196 + 197 + return 0; 198 + } 199 + 200 + /* Duplicate the given audit watch. The new watch's rules list is initialized 201 + * to an empty list and wlist is undefined. */ 202 + static struct audit_watch *audit_dupe_watch(struct audit_watch *old) 203 + { 204 + char *path; 205 + struct audit_watch *new; 206 + 207 + path = kstrdup(old->path, GFP_KERNEL); 208 + if (unlikely(!path)) 209 + return ERR_PTR(-ENOMEM); 210 + 211 + new = audit_init_watch(path); 212 + if (IS_ERR(new)) { 213 + kfree(path); 214 + goto out; 215 + } 216 + 217 + new->dev = old->dev; 218 + new->ino = old->ino; 219 + get_inotify_watch(&old->parent->wdata); 220 + new->parent = old->parent; 221 + 222 + out: 223 + return new; 224 + } 225 + 226 + static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watch *w, char *op) 227 + { 228 + if (audit_enabled) { 229 + struct audit_buffer *ab; 230 + ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE); 231 + audit_log_format(ab, "auid=%u ses=%u op=", 232 + audit_get_loginuid(current), 233 + audit_get_sessionid(current)); 234 + audit_log_string(ab, op); 235 + audit_log_format(ab, " path="); 236 + audit_log_untrustedstring(ab, w->path); 237 + audit_log_key(ab, r->filterkey); 238 + audit_log_format(ab, " list=%d res=1", r->listnr); 239 + audit_log_end(ab); 240 + } 241 + } 242 + 243 + /* Update inode info in audit rules based on filesystem event. */ 244 + static void audit_update_watch(struct audit_parent *parent, 245 + const char *dname, dev_t dev, 246 + unsigned long ino, unsigned invalidating) 247 + { 248 + struct audit_watch *owatch, *nwatch, *nextw; 249 + struct audit_krule *r, *nextr; 250 + struct audit_entry *oentry, *nentry; 251 + 252 + mutex_lock(&audit_filter_mutex); 253 + list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) { 254 + if (audit_compare_dname_path(dname, owatch->path, NULL)) 255 + continue; 256 + 257 + /* If the update involves invalidating rules, do the inode-based 258 + * filtering now, so we don't omit records. */ 259 + if (invalidating && current->audit_context) 260 + audit_filter_inodes(current, current->audit_context); 261 + 262 + nwatch = audit_dupe_watch(owatch); 263 + if (IS_ERR(nwatch)) { 264 + mutex_unlock(&audit_filter_mutex); 265 + audit_panic("error updating watch, skipping"); 266 + return; 267 + } 268 + nwatch->dev = dev; 269 + nwatch->ino = ino; 270 + 271 + list_for_each_entry_safe(r, nextr, &owatch->rules, rlist) { 272 + 273 + oentry = container_of(r, struct audit_entry, rule); 274 + list_del(&oentry->rule.rlist); 275 + list_del_rcu(&oentry->list); 276 + 277 + nentry = audit_dupe_rule(&oentry->rule, nwatch); 278 + if (IS_ERR(nentry)) { 279 + list_del(&oentry->rule.list); 280 + audit_panic("error updating watch, removing"); 281 + } else { 282 + int h = audit_hash_ino((u32)ino); 283 + list_add(&nentry->rule.rlist, &nwatch->rules); 284 + list_add_rcu(&nentry->list, &audit_inode_hash[h]); 285 + list_replace(&oentry->rule.list, 286 + &nentry->rule.list); 287 + } 288 + 289 + audit_watch_log_rule_change(r, owatch, "updated rules"); 290 + 291 + call_rcu(&oentry->rcu, audit_free_rule_rcu); 292 + } 293 + 294 + audit_remove_watch(owatch); 295 + goto add_watch_to_parent; /* event applies to a single watch */ 296 + } 297 + mutex_unlock(&audit_filter_mutex); 298 + return; 299 + 300 + add_watch_to_parent: 301 + list_add(&nwatch->wlist, &parent->watches); 302 + mutex_unlock(&audit_filter_mutex); 303 + return; 304 + } 305 + 306 + /* Remove all watches & rules associated with a parent that is going away. */ 307 + static void audit_remove_parent_watches(struct audit_parent *parent) 308 + { 309 + struct audit_watch *w, *nextw; 310 + struct audit_krule *r, *nextr; 311 + struct audit_entry *e; 312 + 313 + mutex_lock(&audit_filter_mutex); 314 + parent->flags |= AUDIT_PARENT_INVALID; 315 + list_for_each_entry_safe(w, nextw, &parent->watches, wlist) { 316 + list_for_each_entry_safe(r, nextr, &w->rules, rlist) { 317 + e = container_of(r, struct audit_entry, rule); 318 + audit_watch_log_rule_change(r, w, "remove rule"); 319 + list_del(&r->rlist); 320 + list_del(&r->list); 321 + list_del_rcu(&e->list); 322 + call_rcu(&e->rcu, audit_free_rule_rcu); 323 + } 324 + audit_remove_watch(w); 325 + } 326 + mutex_unlock(&audit_filter_mutex); 327 + } 328 + 329 + /* Unregister inotify watches for parents on in_list. 330 + * Generates an IN_IGNORED event. */ 331 + void audit_inotify_unregister(struct list_head *in_list) 332 + { 333 + struct audit_parent *p, *n; 334 + 335 + list_for_each_entry_safe(p, n, in_list, ilist) { 336 + list_del(&p->ilist); 337 + inotify_rm_watch(audit_ih, &p->wdata); 338 + /* the unpin matching the pin in audit_do_del_rule() */ 339 + unpin_inotify_watch(&p->wdata); 340 + } 341 + } 342 + 343 + /* Get path information necessary for adding watches. */ 344 + static int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw) 345 + { 346 + struct nameidata *ndparent, *ndwatch; 347 + int err; 348 + 349 + ndparent = kmalloc(sizeof(*ndparent), GFP_KERNEL); 350 + if (unlikely(!ndparent)) 351 + return -ENOMEM; 352 + 353 + ndwatch = kmalloc(sizeof(*ndwatch), GFP_KERNEL); 354 + if (unlikely(!ndwatch)) { 355 + kfree(ndparent); 356 + return -ENOMEM; 357 + } 358 + 359 + err = path_lookup(path, LOOKUP_PARENT, ndparent); 360 + if (err) { 361 + kfree(ndparent); 362 + kfree(ndwatch); 363 + return err; 364 + } 365 + 366 + err = path_lookup(path, 0, ndwatch); 367 + if (err) { 368 + kfree(ndwatch); 369 + ndwatch = NULL; 370 + } 371 + 372 + *ndp = ndparent; 373 + *ndw = ndwatch; 374 + 375 + return 0; 376 + } 377 + 378 + /* Release resources used for watch path information. */ 379 + static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw) 380 + { 381 + if (ndp) { 382 + path_put(&ndp->path); 383 + kfree(ndp); 384 + } 385 + if (ndw) { 386 + path_put(&ndw->path); 387 + kfree(ndw); 388 + } 389 + } 390 + 391 + /* Associate the given rule with an existing parent inotify_watch. 392 + * Caller must hold audit_filter_mutex. */ 393 + static void audit_add_to_parent(struct audit_krule *krule, 394 + struct audit_parent *parent) 395 + { 396 + struct audit_watch *w, *watch = krule->watch; 397 + int watch_found = 0; 398 + 399 + list_for_each_entry(w, &parent->watches, wlist) { 400 + if (strcmp(watch->path, w->path)) 401 + continue; 402 + 403 + watch_found = 1; 404 + 405 + /* put krule's and initial refs to temporary watch */ 406 + audit_put_watch(watch); 407 + audit_put_watch(watch); 408 + 409 + audit_get_watch(w); 410 + krule->watch = watch = w; 411 + break; 412 + } 413 + 414 + if (!watch_found) { 415 + get_inotify_watch(&parent->wdata); 416 + watch->parent = parent; 417 + 418 + list_add(&watch->wlist, &parent->watches); 419 + } 420 + list_add(&krule->rlist, &watch->rules); 421 + } 422 + 423 + /* Find a matching watch entry, or add this one. 424 + * Caller must hold audit_filter_mutex. */ 425 + int audit_add_watch(struct audit_krule *krule) 426 + { 427 + struct audit_watch *watch = krule->watch; 428 + struct inotify_watch *i_watch; 429 + struct audit_parent *parent; 430 + struct nameidata *ndp = NULL, *ndw = NULL; 431 + int ret = 0; 432 + 433 + mutex_unlock(&audit_filter_mutex); 434 + 435 + /* Avoid calling path_lookup under audit_filter_mutex. */ 436 + ret = audit_get_nd(watch->path, &ndp, &ndw); 437 + if (ret) { 438 + /* caller expects mutex locked */ 439 + mutex_lock(&audit_filter_mutex); 440 + goto error; 441 + } 442 + 443 + /* update watch filter fields */ 444 + if (ndw) { 445 + watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev; 446 + watch->ino = ndw->path.dentry->d_inode->i_ino; 447 + } 448 + 449 + /* The audit_filter_mutex must not be held during inotify calls because 450 + * we hold it during inotify event callback processing. If an existing 451 + * inotify watch is found, inotify_find_watch() grabs a reference before 452 + * returning. 453 + */ 454 + if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode, 455 + &i_watch) < 0) { 456 + parent = audit_init_parent(ndp); 457 + if (IS_ERR(parent)) { 458 + /* caller expects mutex locked */ 459 + mutex_lock(&audit_filter_mutex); 460 + ret = PTR_ERR(parent); 461 + goto error; 462 + } 463 + } else 464 + parent = container_of(i_watch, struct audit_parent, wdata); 465 + 466 + mutex_lock(&audit_filter_mutex); 467 + 468 + /* parent was moved before we took audit_filter_mutex */ 469 + if (parent->flags & AUDIT_PARENT_INVALID) 470 + ret = -ENOENT; 471 + else 472 + audit_add_to_parent(krule, parent); 473 + 474 + /* match get in audit_init_parent or inotify_find_watch */ 475 + put_inotify_watch(&parent->wdata); 476 + 477 + error: 478 + audit_put_nd(ndp, ndw); /* NULL args OK */ 479 + return ret; 480 + 481 + } 482 + 483 + void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list) 484 + { 485 + struct audit_watch *watch = krule->watch; 486 + struct audit_parent *parent = watch->parent; 487 + 488 + list_del(&krule->rlist); 489 + 490 + if (list_empty(&watch->rules)) { 491 + audit_remove_watch(watch); 492 + 493 + if (list_empty(&parent->watches)) { 494 + /* Put parent on the inotify un-registration 495 + * list. Grab a reference before releasing 496 + * audit_filter_mutex, to be released in 497 + * audit_inotify_unregister(). 498 + * If filesystem is going away, just leave 499 + * the sucker alone, eviction will take 500 + * care of it. */ 501 + if (pin_inotify_watch(&parent->wdata)) 502 + list_add(&parent->ilist, list); 503 + } 504 + } 505 + } 506 + 507 + /* Update watch data in audit rules based on inotify events. */ 508 + static void audit_handle_ievent(struct inotify_watch *i_watch, u32 wd, u32 mask, 509 + u32 cookie, const char *dname, struct inode *inode) 510 + { 511 + struct audit_parent *parent; 512 + 513 + parent = container_of(i_watch, struct audit_parent, wdata); 514 + 515 + if (mask & (IN_CREATE|IN_MOVED_TO) && inode) 516 + audit_update_watch(parent, dname, inode->i_sb->s_dev, 517 + inode->i_ino, 0); 518 + else if (mask & (IN_DELETE|IN_MOVED_FROM)) 519 + audit_update_watch(parent, dname, (dev_t)-1, (unsigned long)-1, 1); 520 + /* inotify automatically removes the watch and sends IN_IGNORED */ 521 + else if (mask & (IN_DELETE_SELF|IN_UNMOUNT)) 522 + audit_remove_parent_watches(parent); 523 + /* inotify does not remove the watch, so remove it manually */ 524 + else if(mask & IN_MOVE_SELF) { 525 + audit_remove_parent_watches(parent); 526 + inotify_remove_watch_locked(audit_ih, i_watch); 527 + } else if (mask & IN_IGNORED) 528 + put_inotify_watch(i_watch); 529 + } 530 + 531 + static const struct inotify_operations audit_inotify_ops = { 532 + .handle_event = audit_handle_ievent, 533 + .destroy_watch = audit_free_parent, 534 + }; 535 + 536 + static int __init audit_watch_init(void) 537 + { 538 + audit_ih = inotify_init(&audit_inotify_ops); 539 + if (IS_ERR(audit_ih)) 540 + audit_panic("cannot initialize inotify handle"); 541 + return 0; 542 + } 543 + subsys_initcall(audit_watch_init);
+22 -496
kernel/auditfilter.c
··· 27 27 #include <linux/namei.h> 28 28 #include <linux/netlink.h> 29 29 #include <linux/sched.h> 30 - #include <linux/inotify.h> 31 30 #include <linux/security.h> 32 31 #include "audit.h" 33 32 ··· 42 43 * An audit_parent struct is not accessed during filtering, so may 43 44 * be written directly provided audit_filter_mutex is held. 44 45 */ 45 - 46 - /* 47 - * Reference counting: 48 - * 49 - * audit_parent: lifetime is from audit_init_parent() to receipt of an IN_IGNORED 50 - * event. Each audit_watch holds a reference to its associated parent. 51 - * 52 - * audit_watch: if added to lists, lifetime is from audit_init_watch() to 53 - * audit_remove_watch(). Additionally, an audit_watch may exist 54 - * temporarily to assist in searching existing filter data. Each 55 - * audit_krule holds a reference to its associated watch. 56 - */ 57 - 58 - struct audit_parent { 59 - struct list_head ilist; /* entry in inotify registration list */ 60 - struct list_head watches; /* associated watches */ 61 - struct inotify_watch wdata; /* inotify watch data */ 62 - unsigned flags; /* status flags */ 63 - }; 64 - 65 - /* 66 - * audit_parent status flags: 67 - * 68 - * AUDIT_PARENT_INVALID - set anytime rules/watches are auto-removed due to 69 - * a filesystem event to ensure we're adding audit watches to a valid parent. 70 - * Technically not needed for IN_DELETE_SELF or IN_UNMOUNT events, as we cannot 71 - * receive them while we have nameidata, but must be used for IN_MOVE_SELF which 72 - * we can receive while holding nameidata. 73 - */ 74 - #define AUDIT_PARENT_INVALID 0x001 75 46 76 47 /* Audit filter lists, defined in <linux/audit.h> */ 77 48 struct list_head audit_filter_list[AUDIT_NR_FILTERS] = { ··· 66 97 67 98 DEFINE_MUTEX(audit_filter_mutex); 68 99 69 - /* Inotify events we care about. */ 70 - #define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF 71 - 72 - void audit_free_parent(struct inotify_watch *i_watch) 73 - { 74 - struct audit_parent *parent; 75 - 76 - parent = container_of(i_watch, struct audit_parent, wdata); 77 - WARN_ON(!list_empty(&parent->watches)); 78 - kfree(parent); 79 - } 80 - 81 - static inline void audit_get_watch(struct audit_watch *watch) 82 - { 83 - atomic_inc(&watch->count); 84 - } 85 - 86 - static void audit_put_watch(struct audit_watch *watch) 87 - { 88 - if (atomic_dec_and_test(&watch->count)) { 89 - WARN_ON(watch->parent); 90 - WARN_ON(!list_empty(&watch->rules)); 91 - kfree(watch->path); 92 - kfree(watch); 93 - } 94 - } 95 - 96 - static void audit_remove_watch(struct audit_watch *watch) 97 - { 98 - list_del(&watch->wlist); 99 - put_inotify_watch(&watch->parent->wdata); 100 - watch->parent = NULL; 101 - audit_put_watch(watch); /* match initial get */ 102 - } 103 - 104 100 static inline void audit_free_rule(struct audit_entry *e) 105 101 { 106 102 int i; ··· 88 154 { 89 155 struct audit_entry *e = container_of(head, struct audit_entry, rcu); 90 156 audit_free_rule(e); 91 - } 92 - 93 - /* Initialize a parent watch entry. */ 94 - static struct audit_parent *audit_init_parent(struct nameidata *ndp) 95 - { 96 - struct audit_parent *parent; 97 - s32 wd; 98 - 99 - parent = kzalloc(sizeof(*parent), GFP_KERNEL); 100 - if (unlikely(!parent)) 101 - return ERR_PTR(-ENOMEM); 102 - 103 - INIT_LIST_HEAD(&parent->watches); 104 - parent->flags = 0; 105 - 106 - inotify_init_watch(&parent->wdata); 107 - /* grab a ref so inotify watch hangs around until we take audit_filter_mutex */ 108 - get_inotify_watch(&parent->wdata); 109 - wd = inotify_add_watch(audit_ih, &parent->wdata, 110 - ndp->path.dentry->d_inode, AUDIT_IN_WATCH); 111 - if (wd < 0) { 112 - audit_free_parent(&parent->wdata); 113 - return ERR_PTR(wd); 114 - } 115 - 116 - return parent; 117 - } 118 - 119 - /* Initialize a watch entry. */ 120 - static struct audit_watch *audit_init_watch(char *path) 121 - { 122 - struct audit_watch *watch; 123 - 124 - watch = kzalloc(sizeof(*watch), GFP_KERNEL); 125 - if (unlikely(!watch)) 126 - return ERR_PTR(-ENOMEM); 127 - 128 - INIT_LIST_HEAD(&watch->rules); 129 - atomic_set(&watch->count, 1); 130 - watch->path = path; 131 - watch->dev = (dev_t)-1; 132 - watch->ino = (unsigned long)-1; 133 - 134 - return watch; 135 157 } 136 158 137 159 /* Initialize an audit filterlist entry. */ ··· 147 257 return -EINVAL; 148 258 149 259 krule->inode_f = f; 150 - return 0; 151 - } 152 - 153 - /* Translate a watch string to kernel respresentation. */ 154 - static int audit_to_watch(struct audit_krule *krule, char *path, int len, 155 - u32 op) 156 - { 157 - struct audit_watch *watch; 158 - 159 - if (!audit_ih) 160 - return -EOPNOTSUPP; 161 - 162 - if (path[0] != '/' || path[len-1] == '/' || 163 - krule->listnr != AUDIT_FILTER_EXIT || 164 - op != Audit_equal || 165 - krule->inode_f || krule->watch || krule->tree) 166 - return -EINVAL; 167 - 168 - watch = audit_init_watch(path); 169 - if (IS_ERR(watch)) 170 - return PTR_ERR(watch); 171 - 172 - audit_get_watch(watch); 173 - krule->watch = watch; 174 - 175 260 return 0; 176 261 } 177 262 ··· 631 766 break; 632 767 case AUDIT_WATCH: 633 768 data->buflen += data->values[i] = 634 - audit_pack_string(&bufp, krule->watch->path); 769 + audit_pack_string(&bufp, 770 + audit_watch_path(krule->watch)); 635 771 break; 636 772 case AUDIT_DIR: 637 773 data->buflen += data->values[i] = ··· 684 818 return 1; 685 819 break; 686 820 case AUDIT_WATCH: 687 - if (strcmp(a->watch->path, b->watch->path)) 821 + if (strcmp(audit_watch_path(a->watch), 822 + audit_watch_path(b->watch))) 688 823 return 1; 689 824 break; 690 825 case AUDIT_DIR: ··· 709 842 return 1; 710 843 711 844 return 0; 712 - } 713 - 714 - /* Duplicate the given audit watch. The new watch's rules list is initialized 715 - * to an empty list and wlist is undefined. */ 716 - static struct audit_watch *audit_dupe_watch(struct audit_watch *old) 717 - { 718 - char *path; 719 - struct audit_watch *new; 720 - 721 - path = kstrdup(old->path, GFP_KERNEL); 722 - if (unlikely(!path)) 723 - return ERR_PTR(-ENOMEM); 724 - 725 - new = audit_init_watch(path); 726 - if (IS_ERR(new)) { 727 - kfree(path); 728 - goto out; 729 - } 730 - 731 - new->dev = old->dev; 732 - new->ino = old->ino; 733 - get_inotify_watch(&old->parent->wdata); 734 - new->parent = old->parent; 735 - 736 - out: 737 - return new; 738 845 } 739 846 740 847 /* Duplicate LSM field information. The lsm_rule is opaque, so must be ··· 745 904 * rule with the new rule in the filterlist, then free the old rule. 746 905 * The rlist element is undefined; list manipulations are handled apart from 747 906 * the initial copy. */ 748 - static struct audit_entry *audit_dupe_rule(struct audit_krule *old, 749 - struct audit_watch *watch) 907 + struct audit_entry *audit_dupe_rule(struct audit_krule *old, 908 + struct audit_watch *watch) 750 909 { 751 910 u32 fcount = old->field_count; 752 911 struct audit_entry *entry; ··· 818 977 return entry; 819 978 } 820 979 821 - /* Update inode info in audit rules based on filesystem event. */ 822 - static void audit_update_watch(struct audit_parent *parent, 823 - const char *dname, dev_t dev, 824 - unsigned long ino, unsigned invalidating) 825 - { 826 - struct audit_watch *owatch, *nwatch, *nextw; 827 - struct audit_krule *r, *nextr; 828 - struct audit_entry *oentry, *nentry; 829 - 830 - mutex_lock(&audit_filter_mutex); 831 - list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) { 832 - if (audit_compare_dname_path(dname, owatch->path, NULL)) 833 - continue; 834 - 835 - /* If the update involves invalidating rules, do the inode-based 836 - * filtering now, so we don't omit records. */ 837 - if (invalidating && current->audit_context) 838 - audit_filter_inodes(current, current->audit_context); 839 - 840 - nwatch = audit_dupe_watch(owatch); 841 - if (IS_ERR(nwatch)) { 842 - mutex_unlock(&audit_filter_mutex); 843 - audit_panic("error updating watch, skipping"); 844 - return; 845 - } 846 - nwatch->dev = dev; 847 - nwatch->ino = ino; 848 - 849 - list_for_each_entry_safe(r, nextr, &owatch->rules, rlist) { 850 - 851 - oentry = container_of(r, struct audit_entry, rule); 852 - list_del(&oentry->rule.rlist); 853 - list_del_rcu(&oentry->list); 854 - 855 - nentry = audit_dupe_rule(&oentry->rule, nwatch); 856 - if (IS_ERR(nentry)) { 857 - list_del(&oentry->rule.list); 858 - audit_panic("error updating watch, removing"); 859 - } else { 860 - int h = audit_hash_ino((u32)ino); 861 - list_add(&nentry->rule.rlist, &nwatch->rules); 862 - list_add_rcu(&nentry->list, &audit_inode_hash[h]); 863 - list_replace(&oentry->rule.list, 864 - &nentry->rule.list); 865 - } 866 - 867 - call_rcu(&oentry->rcu, audit_free_rule_rcu); 868 - } 869 - 870 - if (audit_enabled) { 871 - struct audit_buffer *ab; 872 - ab = audit_log_start(NULL, GFP_NOFS, 873 - AUDIT_CONFIG_CHANGE); 874 - audit_log_format(ab, "auid=%u ses=%u", 875 - audit_get_loginuid(current), 876 - audit_get_sessionid(current)); 877 - audit_log_format(ab, 878 - " op=updated rules specifying path="); 879 - audit_log_untrustedstring(ab, owatch->path); 880 - audit_log_format(ab, " with dev=%u ino=%lu\n", 881 - dev, ino); 882 - audit_log_format(ab, " list=%d res=1", r->listnr); 883 - audit_log_end(ab); 884 - } 885 - audit_remove_watch(owatch); 886 - goto add_watch_to_parent; /* event applies to a single watch */ 887 - } 888 - mutex_unlock(&audit_filter_mutex); 889 - return; 890 - 891 - add_watch_to_parent: 892 - list_add(&nwatch->wlist, &parent->watches); 893 - mutex_unlock(&audit_filter_mutex); 894 - return; 895 - } 896 - 897 - /* Remove all watches & rules associated with a parent that is going away. */ 898 - static void audit_remove_parent_watches(struct audit_parent *parent) 899 - { 900 - struct audit_watch *w, *nextw; 901 - struct audit_krule *r, *nextr; 902 - struct audit_entry *e; 903 - 904 - mutex_lock(&audit_filter_mutex); 905 - parent->flags |= AUDIT_PARENT_INVALID; 906 - list_for_each_entry_safe(w, nextw, &parent->watches, wlist) { 907 - list_for_each_entry_safe(r, nextr, &w->rules, rlist) { 908 - e = container_of(r, struct audit_entry, rule); 909 - if (audit_enabled) { 910 - struct audit_buffer *ab; 911 - ab = audit_log_start(NULL, GFP_NOFS, 912 - AUDIT_CONFIG_CHANGE); 913 - audit_log_format(ab, "auid=%u ses=%u", 914 - audit_get_loginuid(current), 915 - audit_get_sessionid(current)); 916 - audit_log_format(ab, " op=remove rule path="); 917 - audit_log_untrustedstring(ab, w->path); 918 - if (r->filterkey) { 919 - audit_log_format(ab, " key="); 920 - audit_log_untrustedstring(ab, 921 - r->filterkey); 922 - } else 923 - audit_log_format(ab, " key=(null)"); 924 - audit_log_format(ab, " list=%d res=1", 925 - r->listnr); 926 - audit_log_end(ab); 927 - } 928 - list_del(&r->rlist); 929 - list_del(&r->list); 930 - list_del_rcu(&e->list); 931 - call_rcu(&e->rcu, audit_free_rule_rcu); 932 - } 933 - audit_remove_watch(w); 934 - } 935 - mutex_unlock(&audit_filter_mutex); 936 - } 937 - 938 - /* Unregister inotify watches for parents on in_list. 939 - * Generates an IN_IGNORED event. */ 940 - static void audit_inotify_unregister(struct list_head *in_list) 941 - { 942 - struct audit_parent *p, *n; 943 - 944 - list_for_each_entry_safe(p, n, in_list, ilist) { 945 - list_del(&p->ilist); 946 - inotify_rm_watch(audit_ih, &p->wdata); 947 - /* the unpin matching the pin in audit_do_del_rule() */ 948 - unpin_inotify_watch(&p->wdata); 949 - } 950 - } 951 - 952 980 /* Find an existing audit rule. 953 981 * Caller must hold audit_filter_mutex to prevent stale rule data. */ 954 982 static struct audit_entry *audit_find_rule(struct audit_entry *entry, ··· 855 1145 return found; 856 1146 } 857 1147 858 - /* Get path information necessary for adding watches. */ 859 - static int audit_get_nd(char *path, struct nameidata **ndp, 860 - struct nameidata **ndw) 861 - { 862 - struct nameidata *ndparent, *ndwatch; 863 - int err; 864 - 865 - ndparent = kmalloc(sizeof(*ndparent), GFP_KERNEL); 866 - if (unlikely(!ndparent)) 867 - return -ENOMEM; 868 - 869 - ndwatch = kmalloc(sizeof(*ndwatch), GFP_KERNEL); 870 - if (unlikely(!ndwatch)) { 871 - kfree(ndparent); 872 - return -ENOMEM; 873 - } 874 - 875 - err = path_lookup(path, LOOKUP_PARENT, ndparent); 876 - if (err) { 877 - kfree(ndparent); 878 - kfree(ndwatch); 879 - return err; 880 - } 881 - 882 - err = path_lookup(path, 0, ndwatch); 883 - if (err) { 884 - kfree(ndwatch); 885 - ndwatch = NULL; 886 - } 887 - 888 - *ndp = ndparent; 889 - *ndw = ndwatch; 890 - 891 - return 0; 892 - } 893 - 894 - /* Release resources used for watch path information. */ 895 - static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw) 896 - { 897 - if (ndp) { 898 - path_put(&ndp->path); 899 - kfree(ndp); 900 - } 901 - if (ndw) { 902 - path_put(&ndw->path); 903 - kfree(ndw); 904 - } 905 - } 906 - 907 - /* Associate the given rule with an existing parent inotify_watch. 908 - * Caller must hold audit_filter_mutex. */ 909 - static void audit_add_to_parent(struct audit_krule *krule, 910 - struct audit_parent *parent) 911 - { 912 - struct audit_watch *w, *watch = krule->watch; 913 - int watch_found = 0; 914 - 915 - list_for_each_entry(w, &parent->watches, wlist) { 916 - if (strcmp(watch->path, w->path)) 917 - continue; 918 - 919 - watch_found = 1; 920 - 921 - /* put krule's and initial refs to temporary watch */ 922 - audit_put_watch(watch); 923 - audit_put_watch(watch); 924 - 925 - audit_get_watch(w); 926 - krule->watch = watch = w; 927 - break; 928 - } 929 - 930 - if (!watch_found) { 931 - get_inotify_watch(&parent->wdata); 932 - watch->parent = parent; 933 - 934 - list_add(&watch->wlist, &parent->watches); 935 - } 936 - list_add(&krule->rlist, &watch->rules); 937 - } 938 - 939 - /* Find a matching watch entry, or add this one. 940 - * Caller must hold audit_filter_mutex. */ 941 - static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp, 942 - struct nameidata *ndw) 943 - { 944 - struct audit_watch *watch = krule->watch; 945 - struct inotify_watch *i_watch; 946 - struct audit_parent *parent; 947 - int ret = 0; 948 - 949 - /* update watch filter fields */ 950 - if (ndw) { 951 - watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev; 952 - watch->ino = ndw->path.dentry->d_inode->i_ino; 953 - } 954 - 955 - /* The audit_filter_mutex must not be held during inotify calls because 956 - * we hold it during inotify event callback processing. If an existing 957 - * inotify watch is found, inotify_find_watch() grabs a reference before 958 - * returning. 959 - */ 960 - mutex_unlock(&audit_filter_mutex); 961 - 962 - if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode, 963 - &i_watch) < 0) { 964 - parent = audit_init_parent(ndp); 965 - if (IS_ERR(parent)) { 966 - /* caller expects mutex locked */ 967 - mutex_lock(&audit_filter_mutex); 968 - return PTR_ERR(parent); 969 - } 970 - } else 971 - parent = container_of(i_watch, struct audit_parent, wdata); 972 - 973 - mutex_lock(&audit_filter_mutex); 974 - 975 - /* parent was moved before we took audit_filter_mutex */ 976 - if (parent->flags & AUDIT_PARENT_INVALID) 977 - ret = -ENOENT; 978 - else 979 - audit_add_to_parent(krule, parent); 980 - 981 - /* match get in audit_init_parent or inotify_find_watch */ 982 - put_inotify_watch(&parent->wdata); 983 - return ret; 984 - } 985 - 986 1148 static u64 prio_low = ~0ULL/2; 987 1149 static u64 prio_high = ~0ULL/2 - 1; 988 1150 ··· 864 1282 struct audit_entry *e; 865 1283 struct audit_watch *watch = entry->rule.watch; 866 1284 struct audit_tree *tree = entry->rule.tree; 867 - struct nameidata *ndp = NULL, *ndw = NULL; 868 1285 struct list_head *list; 869 1286 int h, err; 870 1287 #ifdef CONFIG_AUDITSYSCALL ··· 877 1296 878 1297 mutex_lock(&audit_filter_mutex); 879 1298 e = audit_find_rule(entry, &list); 880 - mutex_unlock(&audit_filter_mutex); 881 1299 if (e) { 1300 + mutex_unlock(&audit_filter_mutex); 882 1301 err = -EEXIST; 883 1302 /* normally audit_add_tree_rule() will free it on failure */ 884 1303 if (tree) ··· 886 1305 goto error; 887 1306 } 888 1307 889 - /* Avoid calling path_lookup under audit_filter_mutex. */ 890 - if (watch) { 891 - err = audit_get_nd(watch->path, &ndp, &ndw); 892 - if (err) 893 - goto error; 894 - } 895 - 896 - mutex_lock(&audit_filter_mutex); 897 1308 if (watch) { 898 1309 /* audit_filter_mutex is dropped and re-taken during this call */ 899 - err = audit_add_watch(&entry->rule, ndp, ndw); 1310 + err = audit_add_watch(&entry->rule); 900 1311 if (err) { 901 1312 mutex_unlock(&audit_filter_mutex); 902 1313 goto error; 903 1314 } 904 - h = audit_hash_ino((u32)watch->ino); 1315 + /* entry->rule.watch may have changed during audit_add_watch() */ 1316 + watch = entry->rule.watch; 1317 + h = audit_hash_ino((u32)audit_watch_inode(watch)); 905 1318 list = &audit_inode_hash[h]; 906 1319 } 907 1320 if (tree) { ··· 933 1358 #endif 934 1359 mutex_unlock(&audit_filter_mutex); 935 1360 936 - audit_put_nd(ndp, ndw); /* NULL args OK */ 937 1361 return 0; 938 1362 939 1363 error: 940 - audit_put_nd(ndp, ndw); /* NULL args OK */ 941 1364 if (watch) 942 1365 audit_put_watch(watch); /* tmp watch, matches initial get */ 943 1366 return err; ··· 945 1372 static inline int audit_del_rule(struct audit_entry *entry) 946 1373 { 947 1374 struct audit_entry *e; 948 - struct audit_watch *watch, *tmp_watch = entry->rule.watch; 1375 + struct audit_watch *watch = entry->rule.watch; 949 1376 struct audit_tree *tree = entry->rule.tree; 950 1377 struct list_head *list; 951 1378 LIST_HEAD(inotify_list); ··· 967 1394 goto out; 968 1395 } 969 1396 970 - watch = e->rule.watch; 971 - if (watch) { 972 - struct audit_parent *parent = watch->parent; 973 - 974 - list_del(&e->rule.rlist); 975 - 976 - if (list_empty(&watch->rules)) { 977 - audit_remove_watch(watch); 978 - 979 - if (list_empty(&parent->watches)) { 980 - /* Put parent on the inotify un-registration 981 - * list. Grab a reference before releasing 982 - * audit_filter_mutex, to be released in 983 - * audit_inotify_unregister(). 984 - * If filesystem is going away, just leave 985 - * the sucker alone, eviction will take 986 - * care of it. 987 - */ 988 - if (pin_inotify_watch(&parent->wdata)) 989 - list_add(&parent->ilist, &inotify_list); 990 - } 991 - } 992 - } 1397 + if (e->rule.watch) 1398 + audit_remove_watch_rule(&e->rule, &inotify_list); 993 1399 994 1400 if (e->rule.tree) 995 1401 audit_remove_tree_rule(&e->rule); ··· 990 1438 audit_inotify_unregister(&inotify_list); 991 1439 992 1440 out: 993 - if (tmp_watch) 994 - audit_put_watch(tmp_watch); /* match initial get */ 1441 + if (watch) 1442 + audit_put_watch(watch); /* match initial get */ 995 1443 if (tree) 996 1444 audit_put_tree(tree); /* that's the temporary one */ 997 1445 ··· 1079 1527 security_release_secctx(ctx, len); 1080 1528 } 1081 1529 } 1082 - audit_log_format(ab, " op=%s rule key=", action); 1083 - if (rule->filterkey) 1084 - audit_log_untrustedstring(ab, rule->filterkey); 1085 - else 1086 - audit_log_format(ab, "(null)"); 1530 + audit_log_format(ab, " op="); 1531 + audit_log_string(ab, action); 1532 + audit_log_key(ab, rule->filterkey); 1087 1533 audit_log_format(ab, " list=%d res=%d", rule->listnr, res); 1088 1534 audit_log_end(ab); 1089 1535 } ··· 1145 1595 return PTR_ERR(entry); 1146 1596 1147 1597 err = audit_add_rule(entry); 1148 - audit_log_rule_change(loginuid, sessionid, sid, "add", 1598 + audit_log_rule_change(loginuid, sessionid, sid, "add rule", 1149 1599 &entry->rule, !err); 1150 1600 1151 1601 if (err) ··· 1161 1611 return PTR_ERR(entry); 1162 1612 1163 1613 err = audit_del_rule(entry); 1164 - audit_log_rule_change(loginuid, sessionid, sid, "remove", 1614 + audit_log_rule_change(loginuid, sessionid, sid, "remove rule", 1165 1615 &entry->rule, !err); 1166 1616 1167 1617 audit_free_rule(entry); ··· 1343 1793 list_del(&r->list); 1344 1794 } else { 1345 1795 if (watch) { 1346 - list_add(&nentry->rule.rlist, &watch->rules); 1796 + list_add(&nentry->rule.rlist, audit_watch_rules(watch)); 1347 1797 list_del(&r->rlist); 1348 1798 } else if (tree) 1349 1799 list_replace_init(&r->rlist, &nentry->rule.rlist); ··· 1378 1828 mutex_unlock(&audit_filter_mutex); 1379 1829 1380 1830 return err; 1381 - } 1382 - 1383 - /* Update watch data in audit rules based on inotify events. */ 1384 - void audit_handle_ievent(struct inotify_watch *i_watch, u32 wd, u32 mask, 1385 - u32 cookie, const char *dname, struct inode *inode) 1386 - { 1387 - struct audit_parent *parent; 1388 - 1389 - parent = container_of(i_watch, struct audit_parent, wdata); 1390 - 1391 - if (mask & (IN_CREATE|IN_MOVED_TO) && inode) 1392 - audit_update_watch(parent, dname, inode->i_sb->s_dev, 1393 - inode->i_ino, 0); 1394 - else if (mask & (IN_DELETE|IN_MOVED_FROM)) 1395 - audit_update_watch(parent, dname, (dev_t)-1, (unsigned long)-1, 1); 1396 - /* inotify automatically removes the watch and sends IN_IGNORED */ 1397 - else if (mask & (IN_DELETE_SELF|IN_UNMOUNT)) 1398 - audit_remove_parent_watches(parent); 1399 - /* inotify does not remove the watch, so remove it manually */ 1400 - else if(mask & IN_MOVE_SELF) { 1401 - audit_remove_parent_watches(parent); 1402 - inotify_remove_watch_locked(audit_ih, i_watch); 1403 - } else if (mask & IN_IGNORED) 1404 - put_inotify_watch(i_watch); 1405 1831 }
+22 -11
kernel/auditsc.c
··· 199 199 200 200 struct audit_tree_refs *trees, *first_trees; 201 201 int tree_count; 202 + struct list_head killed_trees; 202 203 203 204 int type; 204 205 union { ··· 549 548 } 550 549 break; 551 550 case AUDIT_WATCH: 552 - if (name && rule->watch->ino != (unsigned long)-1) 553 - result = (name->dev == rule->watch->dev && 554 - name->ino == rule->watch->ino); 551 + if (name && audit_watch_inode(rule->watch) != (unsigned long)-1) 552 + result = (name->dev == audit_watch_dev(rule->watch) && 553 + name->ino == audit_watch_inode(rule->watch)); 555 554 break; 556 555 case AUDIT_DIR: 557 556 if (ctx) ··· 854 853 if (!(context = kmalloc(sizeof(*context), GFP_KERNEL))) 855 854 return NULL; 856 855 audit_zero_context(context, state); 856 + INIT_LIST_HEAD(&context->killed_trees); 857 857 return context; 858 858 } 859 859 ··· 1026 1024 { 1027 1025 char arg_num_len_buf[12]; 1028 1026 const char __user *tmp_p = p; 1029 - /* how many digits are in arg_num? 3 is the length of " a=" */ 1030 - size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 3; 1027 + /* how many digits are in arg_num? 5 is the length of ' a=""' */ 1028 + size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 5; 1031 1029 size_t len, len_left, to_send; 1032 1030 size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN; 1033 1031 unsigned int i, has_cntl = 0, too_long = 0; ··· 1139 1137 if (has_cntl) 1140 1138 audit_log_n_hex(*ab, buf, to_send); 1141 1139 else 1142 - audit_log_format(*ab, "\"%s\"", buf); 1140 + audit_log_string(*ab, buf); 1143 1141 1144 1142 p += to_send; 1145 1143 len_left -= to_send; ··· 1374 1372 1375 1373 1376 1374 audit_log_task_info(ab, tsk); 1377 - if (context->filterkey) { 1378 - audit_log_format(ab, " key="); 1379 - audit_log_untrustedstring(ab, context->filterkey); 1380 - } else 1381 - audit_log_format(ab, " key=(null)"); 1375 + audit_log_key(ab, context->filterkey); 1382 1376 audit_log_end(ab); 1383 1377 1384 1378 for (aux = context->aux; aux; aux = aux->next) { ··· 1547 1549 /* that can happen only if we are called from do_exit() */ 1548 1550 if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT) 1549 1551 audit_log_exit(context, tsk); 1552 + if (!list_empty(&context->killed_trees)) 1553 + audit_kill_trees(&context->killed_trees); 1550 1554 1551 1555 audit_free_context(context); 1552 1556 } ··· 1691 1691 1692 1692 context->in_syscall = 0; 1693 1693 context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0; 1694 + 1695 + if (!list_empty(&context->killed_trees)) 1696 + audit_kill_trees(&context->killed_trees); 1694 1697 1695 1698 if (context->previous) { 1696 1699 struct audit_context *new_context = context->previous; ··· 2527 2524 audit_log_untrustedstring(ab, current->comm); 2528 2525 audit_log_format(ab, " sig=%ld", signr); 2529 2526 audit_log_end(ab); 2527 + } 2528 + 2529 + struct list_head *audit_killed_trees(void) 2530 + { 2531 + struct audit_context *ctx = current->audit_context; 2532 + if (likely(!ctx || !ctx->in_syscall)) 2533 + return NULL; 2534 + return &ctx->killed_trees; 2530 2535 }