aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-15 16:28:48 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-15 16:28:48 -0500
commitf9bab2677ac77622618686b199073978ba263c12 (patch)
tree0396a87240a0e00cc0fcae5a1f46c38b819ede1a
parent373c4557d2aa362702c4c2d41288fb1e54990b7c (diff)
parent42d5e37654e4cdb9fb2e2f3ab30045fee35c42d8 (diff)
Merge tag 'audit-pr-20171113' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit
Pull audit updates from Paul Moore: "Another relatively small pull request for audit, nine patches total. The only real new bit of functionality is the patch from Richard which adds the ability to filter records based on the filesystem type. The remainder are bug fixes and cleanups; the bug fix highlights include: - ensuring that we properly audit init/PID-1 (me) - allowing the audit daemon to shutdown the kernel/auditd connection cleanly by setting the audit PID to zero (Steve)" * tag 'audit-pr-20171113' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit: audit: filter PATH records keyed on filesystem magic Audit: remove unused audit_log_secctx function audit: Allow auditd to set pid to 0 to end auditing audit: Add new syscalls to the perm=w filter audit: use audit_set_enabled() in audit_enable() audit: convert audit_ever_enabled to a boolean audit: don't use simple_strtol() anymore audit: initialize the audit subsystem as early as possible audit: ensure that 'audit=1' actually enables audit for PID 1
-rw-r--r--include/asm-generic/audit_dir_write.h3
-rw-r--r--include/asm-generic/audit_write.h3
-rw-r--r--include/linux/audit.h8
-rw-r--r--include/uapi/linux/audit.h8
-rw-r--r--kernel/audit.c76
-rw-r--r--kernel/audit.h2
-rw-r--r--kernel/auditfilter.c39
-rw-r--r--kernel/auditsc.c23
8 files changed, 97 insertions, 65 deletions
diff --git a/include/asm-generic/audit_dir_write.h b/include/asm-generic/audit_dir_write.h
index 8fb83b43006a..da09fb986459 100644
--- a/include/asm-generic/audit_dir_write.h
+++ b/include/asm-generic/audit_dir_write.h
@@ -31,3 +31,6 @@ __NR_renameat,
31__NR_linkat, 31__NR_linkat,
32__NR_symlinkat, 32__NR_symlinkat,
33#endif 33#endif
34#ifdef __NR_renameat2
35__NR_renameat2,
36#endif
diff --git a/include/asm-generic/audit_write.h b/include/asm-generic/audit_write.h
index dfc52b3c103f..f9f1d0ae11d9 100644
--- a/include/asm-generic/audit_write.h
+++ b/include/asm-generic/audit_write.h
@@ -20,3 +20,6 @@ __NR_ftruncate64,
20#ifdef __NR_bind 20#ifdef __NR_bind
21__NR_bind, /* bind can affect fs object only in one way... */ 21__NR_bind, /* bind can affect fs object only in one way... */
22#endif 22#endif
23#ifdef __NR_fallocate
24__NR_fallocate,
25#endif
diff --git a/include/linux/audit.h b/include/linux/audit.h
index d66220dac364..af410d9fbf2d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -149,12 +149,6 @@ extern void audit_log_key(struct audit_buffer *ab,
149extern void audit_log_link_denied(const char *operation, 149extern void audit_log_link_denied(const char *operation,
150 const struct path *link); 150 const struct path *link);
151extern void audit_log_lost(const char *message); 151extern void audit_log_lost(const char *message);
152#ifdef CONFIG_SECURITY
153extern void audit_log_secctx(struct audit_buffer *ab, u32 secid);
154#else
155static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
156{ }
157#endif
158 152
159extern int audit_log_task_context(struct audit_buffer *ab); 153extern int audit_log_task_context(struct audit_buffer *ab);
160extern void audit_log_task_info(struct audit_buffer *ab, 154extern void audit_log_task_info(struct audit_buffer *ab,
@@ -203,8 +197,6 @@ static inline void audit_log_key(struct audit_buffer *ab, char *key)
203static inline void audit_log_link_denied(const char *string, 197static inline void audit_log_link_denied(const char *string,
204 const struct path *link) 198 const struct path *link)
205{ } 199{ }
206static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
207{ }
208static inline int audit_log_task_context(struct audit_buffer *ab) 200static inline int audit_log_task_context(struct audit_buffer *ab)
209{ 201{
210 return 0; 202 return 0;
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 626e76d109b9..4e61a9e05132 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -157,8 +157,9 @@
157#define AUDIT_FILTER_WATCH 0x03 /* Apply rule to file system watches */ 157#define AUDIT_FILTER_WATCH 0x03 /* Apply rule to file system watches */
158#define AUDIT_FILTER_EXIT 0x04 /* Apply rule at syscall exit */ 158#define AUDIT_FILTER_EXIT 0x04 /* Apply rule at syscall exit */
159#define AUDIT_FILTER_TYPE 0x05 /* Apply rule at audit_log_start */ 159#define AUDIT_FILTER_TYPE 0x05 /* Apply rule at audit_log_start */
160#define AUDIT_FILTER_FS 0x06 /* Apply rule at __audit_inode_child */
160 161
161#define AUDIT_NR_FILTERS 6 162#define AUDIT_NR_FILTERS 7
162 163
163#define AUDIT_FILTER_PREPEND 0x10 /* Prepend to front of list */ 164#define AUDIT_FILTER_PREPEND 0x10 /* Prepend to front of list */
164 165
@@ -258,6 +259,7 @@
258#define AUDIT_OBJ_LEV_HIGH 23 259#define AUDIT_OBJ_LEV_HIGH 23
259#define AUDIT_LOGINUID_SET 24 260#define AUDIT_LOGINUID_SET 24
260#define AUDIT_SESSIONID 25 /* Session ID */ 261#define AUDIT_SESSIONID 25 /* Session ID */
262#define AUDIT_FSTYPE 26 /* FileSystem Type */
261 263
262 /* These are ONLY useful when checking 264 /* These are ONLY useful when checking
263 * at syscall exit time (AUDIT_AT_EXIT). */ 265 * at syscall exit time (AUDIT_AT_EXIT). */
@@ -337,13 +339,15 @@ enum {
337#define AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND 0x00000008 339#define AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND 0x00000008
338#define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER 0x00000010 340#define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER 0x00000010
339#define AUDIT_FEATURE_BITMAP_LOST_RESET 0x00000020 341#define AUDIT_FEATURE_BITMAP_LOST_RESET 0x00000020
342#define AUDIT_FEATURE_BITMAP_FILTER_FS 0x00000040
340 343
341#define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \ 344#define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \
342 AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | \ 345 AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | \
343 AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | \ 346 AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | \
344 AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | \ 347 AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | \
345 AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | \ 348 AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | \
346 AUDIT_FEATURE_BITMAP_LOST_RESET) 349 AUDIT_FEATURE_BITMAP_LOST_RESET | \
350 AUDIT_FEATURE_BITMAP_FILTER_FS)
347 351
348/* deprecated: AUDIT_VERSION_* */ 352/* deprecated: AUDIT_VERSION_* */
349#define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL 353#define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL
diff --git a/kernel/audit.c b/kernel/audit.c
index be1c28fd4d57..227db99b0f19 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -85,13 +85,13 @@ static int audit_initialized;
85#define AUDIT_OFF 0 85#define AUDIT_OFF 0
86#define AUDIT_ON 1 86#define AUDIT_ON 1
87#define AUDIT_LOCKED 2 87#define AUDIT_LOCKED 2
88u32 audit_enabled; 88u32 audit_enabled = AUDIT_OFF;
89u32 audit_ever_enabled; 89bool audit_ever_enabled = !!AUDIT_OFF;
90 90
91EXPORT_SYMBOL_GPL(audit_enabled); 91EXPORT_SYMBOL_GPL(audit_enabled);
92 92
93/* Default state when kernel boots without any parameters. */ 93/* Default state when kernel boots without any parameters. */
94static u32 audit_default; 94static u32 audit_default = AUDIT_OFF;
95 95
96/* If auditing cannot proceed, audit_failure selects what happens. */ 96/* If auditing cannot proceed, audit_failure selects what happens. */
97static u32 audit_failure = AUDIT_FAIL_PRINTK; 97static u32 audit_failure = AUDIT_FAIL_PRINTK;
@@ -1197,25 +1197,28 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1197 pid_t auditd_pid; 1197 pid_t auditd_pid;
1198 struct pid *req_pid = task_tgid(current); 1198 struct pid *req_pid = task_tgid(current);
1199 1199
1200 /* sanity check - PID values must match */ 1200 /* Sanity check - PID values must match. Setting
1201 if (new_pid != pid_vnr(req_pid)) 1201 * pid to 0 is how auditd ends auditing. */
1202 if (new_pid && (new_pid != pid_vnr(req_pid)))
1202 return -EINVAL; 1203 return -EINVAL;
1203 1204
1204 /* test the auditd connection */ 1205 /* test the auditd connection */
1205 audit_replace(req_pid); 1206 audit_replace(req_pid);
1206 1207
1207 auditd_pid = auditd_pid_vnr(); 1208 auditd_pid = auditd_pid_vnr();
1208 /* only the current auditd can unregister itself */ 1209 if (auditd_pid) {
1209 if ((!new_pid) && (new_pid != auditd_pid)) { 1210 /* replacing a healthy auditd is not allowed */
1210 audit_log_config_change("audit_pid", new_pid, 1211 if (new_pid) {
1211 auditd_pid, 0); 1212 audit_log_config_change("audit_pid",
1212 return -EACCES; 1213 new_pid, auditd_pid, 0);
1213 } 1214 return -EEXIST;
1214 /* replacing a healthy auditd is not allowed */ 1215 }
1215 if (auditd_pid && new_pid) { 1216 /* only current auditd can unregister itself */
1216 audit_log_config_change("audit_pid", new_pid, 1217 if (pid_vnr(req_pid) != auditd_pid) {
1217 auditd_pid, 0); 1218 audit_log_config_change("audit_pid",
1218 return -EEXIST; 1219 new_pid, auditd_pid, 0);
1220 return -EACCES;
1221 }
1219 } 1222 }
1220 1223
1221 if (new_pid) { 1224 if (new_pid) {
@@ -1549,8 +1552,6 @@ static int __init audit_init(void)
1549 register_pernet_subsys(&audit_net_ops); 1552 register_pernet_subsys(&audit_net_ops);
1550 1553
1551 audit_initialized = AUDIT_INITIALIZED; 1554 audit_initialized = AUDIT_INITIALIZED;
1552 audit_enabled = audit_default;
1553 audit_ever_enabled |= !!audit_default;
1554 1555
1555 kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd"); 1556 kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd");
1556 if (IS_ERR(kauditd_task)) { 1557 if (IS_ERR(kauditd_task)) {
@@ -1564,14 +1565,21 @@ static int __init audit_init(void)
1564 1565
1565 return 0; 1566 return 0;
1566} 1567}
1567__initcall(audit_init); 1568postcore_initcall(audit_init);
1568 1569
1569/* Process kernel command-line parameter at boot time. audit=0 or audit=1. */ 1570/* Process kernel command-line parameter at boot time. audit=0 or audit=1. */
1570static int __init audit_enable(char *str) 1571static int __init audit_enable(char *str)
1571{ 1572{
1572 audit_default = !!simple_strtol(str, NULL, 0); 1573 long val;
1573 if (!audit_default) 1574
1575 if (kstrtol(str, 0, &val))
1576 panic("audit: invalid 'audit' parameter value (%s)\n", str);
1577 audit_default = (val ? AUDIT_ON : AUDIT_OFF);
1578
1579 if (audit_default == AUDIT_OFF)
1574 audit_initialized = AUDIT_DISABLED; 1580 audit_initialized = AUDIT_DISABLED;
1581 if (audit_set_enabled(audit_default))
1582 panic("audit: error setting audit state (%d)\n", audit_default);
1575 1583
1576 pr_info("%s\n", audit_default ? 1584 pr_info("%s\n", audit_default ?
1577 "enabled (after initialization)" : "disabled (until reboot)"); 1585 "enabled (after initialization)" : "disabled (until reboot)");
@@ -2337,32 +2345,6 @@ void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
2337 } 2345 }
2338} 2346}
2339 2347
2340#ifdef CONFIG_SECURITY
2341/**
2342 * audit_log_secctx - Converts and logs SELinux context
2343 * @ab: audit_buffer
2344 * @secid: security number
2345 *
2346 * This is a helper function that calls security_secid_to_secctx to convert
2347 * secid to secctx and then adds the (converted) SELinux context to the audit
2348 * log by calling audit_log_format, thus also preventing leak of internal secid
2349 * to userspace. If secid cannot be converted audit_panic is called.
2350 */
2351void audit_log_secctx(struct audit_buffer *ab, u32 secid)
2352{
2353 u32 len;
2354 char *secctx;
2355
2356 if (security_secid_to_secctx(secid, &secctx, &len)) {
2357 audit_panic("Cannot convert secid to context");
2358 } else {
2359 audit_log_format(ab, " obj=%s", secctx);
2360 security_release_secctx(secctx, len);
2361 }
2362}
2363EXPORT_SYMBOL(audit_log_secctx);
2364#endif
2365
2366EXPORT_SYMBOL(audit_log_start); 2348EXPORT_SYMBOL(audit_log_start);
2367EXPORT_SYMBOL(audit_log_end); 2349EXPORT_SYMBOL(audit_log_end);
2368EXPORT_SYMBOL(audit_log_format); 2350EXPORT_SYMBOL(audit_log_format);
diff --git a/kernel/audit.h b/kernel/audit.h
index 9b110ae17ee3..af5bc59487ed 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -208,7 +208,7 @@ struct audit_context {
208 struct audit_proctitle proctitle; 208 struct audit_proctitle proctitle;
209}; 209};
210 210
211extern u32 audit_ever_enabled; 211extern bool audit_ever_enabled;
212 212
213extern void audit_copy_inode(struct audit_names *name, 213extern void audit_copy_inode(struct audit_names *name,
214 const struct dentry *dentry, 214 const struct dentry *dentry,
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 0b0aa5854dac..4a1758adb222 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -56,7 +56,8 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
56 LIST_HEAD_INIT(audit_filter_list[3]), 56 LIST_HEAD_INIT(audit_filter_list[3]),
57 LIST_HEAD_INIT(audit_filter_list[4]), 57 LIST_HEAD_INIT(audit_filter_list[4]),
58 LIST_HEAD_INIT(audit_filter_list[5]), 58 LIST_HEAD_INIT(audit_filter_list[5]),
59#if AUDIT_NR_FILTERS != 6 59 LIST_HEAD_INIT(audit_filter_list[6]),
60#if AUDIT_NR_FILTERS != 7
60#error Fix audit_filter_list initialiser 61#error Fix audit_filter_list initialiser
61#endif 62#endif
62}; 63};
@@ -67,6 +68,7 @@ static struct list_head audit_rules_list[AUDIT_NR_FILTERS] = {
67 LIST_HEAD_INIT(audit_rules_list[3]), 68 LIST_HEAD_INIT(audit_rules_list[3]),
68 LIST_HEAD_INIT(audit_rules_list[4]), 69 LIST_HEAD_INIT(audit_rules_list[4]),
69 LIST_HEAD_INIT(audit_rules_list[5]), 70 LIST_HEAD_INIT(audit_rules_list[5]),
71 LIST_HEAD_INIT(audit_rules_list[6]),
70}; 72};
71 73
72DEFINE_MUTEX(audit_filter_mutex); 74DEFINE_MUTEX(audit_filter_mutex);
@@ -263,6 +265,7 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule_data *
263#endif 265#endif
264 case AUDIT_FILTER_USER: 266 case AUDIT_FILTER_USER:
265 case AUDIT_FILTER_TYPE: 267 case AUDIT_FILTER_TYPE:
268 case AUDIT_FILTER_FS:
266 ; 269 ;
267 } 270 }
268 if (unlikely(rule->action == AUDIT_POSSIBLE)) { 271 if (unlikely(rule->action == AUDIT_POSSIBLE)) {
@@ -338,6 +341,21 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
338 entry->rule.listnr != AUDIT_FILTER_USER) 341 entry->rule.listnr != AUDIT_FILTER_USER)
339 return -EINVAL; 342 return -EINVAL;
340 break; 343 break;
344 case AUDIT_FSTYPE:
345 if (entry->rule.listnr != AUDIT_FILTER_FS)
346 return -EINVAL;
347 break;
348 }
349
350 switch(entry->rule.listnr) {
351 case AUDIT_FILTER_FS:
352 switch(f->type) {
353 case AUDIT_FSTYPE:
354 case AUDIT_FILTERKEY:
355 break;
356 default:
357 return -EINVAL;
358 }
341 } 359 }
342 360
343 switch(f->type) { 361 switch(f->type) {
@@ -391,6 +409,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
391 return -EINVAL; 409 return -EINVAL;
392 /* FALL THROUGH */ 410 /* FALL THROUGH */
393 case AUDIT_ARCH: 411 case AUDIT_ARCH:
412 case AUDIT_FSTYPE:
394 if (f->op != Audit_not_equal && f->op != Audit_equal) 413 if (f->op != Audit_not_equal && f->op != Audit_equal)
395 return -EINVAL; 414 return -EINVAL;
396 break; 415 break;
@@ -910,10 +929,13 @@ static inline int audit_add_rule(struct audit_entry *entry)
910#ifdef CONFIG_AUDITSYSCALL 929#ifdef CONFIG_AUDITSYSCALL
911 int dont_count = 0; 930 int dont_count = 0;
912 931
913 /* If either of these, don't count towards total */ 932 /* If any of these, don't count towards total */
914 if (entry->rule.listnr == AUDIT_FILTER_USER || 933 switch(entry->rule.listnr) {
915 entry->rule.listnr == AUDIT_FILTER_TYPE) 934 case AUDIT_FILTER_USER:
935 case AUDIT_FILTER_TYPE:
936 case AUDIT_FILTER_FS:
916 dont_count = 1; 937 dont_count = 1;
938 }
917#endif 939#endif
918 940
919 mutex_lock(&audit_filter_mutex); 941 mutex_lock(&audit_filter_mutex);
@@ -989,10 +1011,13 @@ int audit_del_rule(struct audit_entry *entry)
989#ifdef CONFIG_AUDITSYSCALL 1011#ifdef CONFIG_AUDITSYSCALL
990 int dont_count = 0; 1012 int dont_count = 0;
991 1013
992 /* If either of these, don't count towards total */ 1014 /* If any of these, don't count towards total */
993 if (entry->rule.listnr == AUDIT_FILTER_USER || 1015 switch(entry->rule.listnr) {
994 entry->rule.listnr == AUDIT_FILTER_TYPE) 1016 case AUDIT_FILTER_USER:
1017 case AUDIT_FILTER_TYPE:
1018 case AUDIT_FILTER_FS:
995 dont_count = 1; 1019 dont_count = 1;
1020 }
996#endif 1021#endif
997 1022
998 mutex_lock(&audit_filter_mutex); 1023 mutex_lock(&audit_filter_mutex);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 9c723e978245..e80459f7e132 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1869,10 +1869,33 @@ void __audit_inode_child(struct inode *parent,
1869 struct inode *inode = d_backing_inode(dentry); 1869 struct inode *inode = d_backing_inode(dentry);
1870 const char *dname = dentry->d_name.name; 1870 const char *dname = dentry->d_name.name;
1871 struct audit_names *n, *found_parent = NULL, *found_child = NULL; 1871 struct audit_names *n, *found_parent = NULL, *found_child = NULL;
1872 struct audit_entry *e;
1873 struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS];
1874 int i;
1872 1875
1873 if (!context->in_syscall) 1876 if (!context->in_syscall)
1874 return; 1877 return;
1875 1878
1879 rcu_read_lock();
1880 if (!list_empty(list)) {
1881 list_for_each_entry_rcu(e, list, list) {
1882 for (i = 0; i < e->rule.field_count; i++) {
1883 struct audit_field *f = &e->rule.fields[i];
1884
1885 if (f->type == AUDIT_FSTYPE) {
1886 if (audit_comparator(parent->i_sb->s_magic,
1887 f->op, f->val)) {
1888 if (e->rule.action == AUDIT_NEVER) {
1889 rcu_read_unlock();
1890 return;
1891 }
1892 }
1893 }
1894 }
1895 }
1896 }
1897 rcu_read_unlock();
1898
1876 if (inode) 1899 if (inode)
1877 handle_one(inode); 1900 handle_one(inode);
1878 1901