summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-08 21:55:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-08 21:55:42 -0400
commit61fc5771f5e729a2ce235af42f69c8506725e84a (patch)
treee0871c1921ab43d8a46c541791927f4459ba9a84
parent884922591e2b58fd7f1018701f957446d1ffac4d (diff)
parent839d05e413856bd686a33b59294d4e8238169320 (diff)
Merge tag 'audit-pr-20190702' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit
Pull audit updates from Paul Moore: "This pull request is a bit early, but with some vacation time coming up I wanted to send this out now just in case the remote Internet Gods decide not to smile on me once the merge window opens. The patchset for v5.3 is pretty minor this time, the highlights include: - When the audit daemon is sent a signal, ensure we deliver information about the sender even when syscall auditing is not enabled/supported. - Add the ability to filter audit records based on network address family. - Tighten the audit field filtering restrictions on string based fields. - Cleanup the audit field filtering verification code. - Remove a few BUG() calls from the audit code" * tag 'audit-pr-20190702' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit: audit: remove the BUG() calls in the audit rule comparison functions audit: enforce op for string fields audit: add saddr_fam filter field audit: re-structure audit field valid checks audit: deliver signal_info regarless of syscall
-rw-r--r--include/linux/audit.h9
-rw-r--r--include/uapi/linux/audit.h1
-rw-r--r--kernel/audit.c27
-rw-r--r--kernel/audit.h8
-rw-r--r--kernel/auditfilter.c62
-rw-r--r--kernel/auditsc.c42
-rw-r--r--kernel/signal.c2
7 files changed, 105 insertions, 46 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 3a4f2415bb7c..97d0925454df 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -182,6 +182,9 @@ static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
182} 182}
183 183
184extern u32 audit_enabled; 184extern u32 audit_enabled;
185
186extern int audit_signal_info(int sig, struct task_struct *t);
187
185#else /* CONFIG_AUDIT */ 188#else /* CONFIG_AUDIT */
186static inline __printf(4, 5) 189static inline __printf(4, 5)
187void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, 190void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
@@ -235,6 +238,12 @@ static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
235} 238}
236 239
237#define audit_enabled AUDIT_OFF 240#define audit_enabled AUDIT_OFF
241
242static inline int audit_signal_info(int sig, struct task_struct *t)
243{
244 return 0;
245}
246
238#endif /* CONFIG_AUDIT */ 247#endif /* CONFIG_AUDIT */
239 248
240#ifdef CONFIG_AUDIT_COMPAT_GENERIC 249#ifdef CONFIG_AUDIT_COMPAT_GENERIC
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index a1280af20336..c89c6495983d 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -281,6 +281,7 @@
281#define AUDIT_OBJ_GID 110 281#define AUDIT_OBJ_GID 110
282#define AUDIT_FIELD_COMPARE 111 282#define AUDIT_FIELD_COMPARE 111
283#define AUDIT_EXE 112 283#define AUDIT_EXE 112
284#define AUDIT_SADDR_FAM 113
284 285
285#define AUDIT_ARG0 200 286#define AUDIT_ARG0 200
286#define AUDIT_ARG1 (AUDIT_ARG0+1) 287#define AUDIT_ARG1 (AUDIT_ARG0+1)
diff --git a/kernel/audit.c b/kernel/audit.c
index 486c968214d9..da8dc0db5bd3 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2261,6 +2261,33 @@ out:
2261} 2261}
2262 2262
2263/** 2263/**
2264 * audit_signal_info - record signal info for shutting down audit subsystem
2265 * @sig: signal value
2266 * @t: task being signaled
2267 *
2268 * If the audit subsystem is being terminated, record the task (pid)
2269 * and uid that is doing that.
2270 */
2271int audit_signal_info(int sig, struct task_struct *t)
2272{
2273 kuid_t uid = current_uid(), auid;
2274
2275 if (auditd_test_task(t) &&
2276 (sig == SIGTERM || sig == SIGHUP ||
2277 sig == SIGUSR1 || sig == SIGUSR2)) {
2278 audit_sig_pid = task_tgid_nr(current);
2279 auid = audit_get_loginuid(current);
2280 if (uid_valid(auid))
2281 audit_sig_uid = auid;
2282 else
2283 audit_sig_uid = uid;
2284 security_task_getsecid(current, &audit_sig_sid);
2285 }
2286
2287 return audit_signal_info_syscall(t);
2288}
2289
2290/**
2264 * audit_log_end - end one audit record 2291 * audit_log_end - end one audit record
2265 * @ab: the audit_buffer 2292 * @ab: the audit_buffer
2266 * 2293 *
diff --git a/kernel/audit.h b/kernel/audit.h
index 6c076d4982da..6fb7160412d4 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -286,7 +286,7 @@ extern const char *audit_tree_path(struct audit_tree *tree);
286extern void audit_put_tree(struct audit_tree *tree); 286extern void audit_put_tree(struct audit_tree *tree);
287extern void audit_kill_trees(struct audit_context *context); 287extern void audit_kill_trees(struct audit_context *context);
288 288
289extern int audit_signal_info(int sig, struct task_struct *t); 289extern int audit_signal_info_syscall(struct task_struct *t);
290extern void audit_filter_inodes(struct task_struct *tsk, 290extern void audit_filter_inodes(struct task_struct *tsk,
291 struct audit_context *ctx); 291 struct audit_context *ctx);
292extern struct list_head *audit_killed_trees(void); 292extern struct list_head *audit_killed_trees(void);
@@ -317,7 +317,11 @@ extern struct list_head *audit_killed_trees(void);
317#define audit_tree_path(rule) "" /* never called */ 317#define audit_tree_path(rule) "" /* never called */
318#define audit_kill_trees(context) BUG() 318#define audit_kill_trees(context) BUG()
319 319
320#define audit_signal_info(s, t) AUDIT_DISABLED 320static inline int audit_signal_info_syscall(struct task_struct *t)
321{
322 return 0;
323}
324
321#define audit_filter_inodes(t, c) AUDIT_DISABLED 325#define audit_filter_inodes(t, c) AUDIT_DISABLED
322#endif /* CONFIG_AUDITSYSCALL */ 326#endif /* CONFIG_AUDITSYSCALL */
323 327
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 9f8e190e3bea..b0126e9c0743 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -322,7 +322,7 @@ static u32 audit_to_op(u32 op)
322/* check if an audit field is valid */ 322/* check if an audit field is valid */
323static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) 323static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
324{ 324{
325 switch(f->type) { 325 switch (f->type) {
326 case AUDIT_MSGTYPE: 326 case AUDIT_MSGTYPE:
327 if (entry->rule.listnr != AUDIT_FILTER_EXCLUDE && 327 if (entry->rule.listnr != AUDIT_FILTER_EXCLUDE &&
328 entry->rule.listnr != AUDIT_FILTER_USER) 328 entry->rule.listnr != AUDIT_FILTER_USER)
@@ -334,7 +334,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
334 break; 334 break;
335 } 335 }
336 336
337 switch(entry->rule.listnr) { 337 switch (entry->rule.listnr) {
338 case AUDIT_FILTER_FS: 338 case AUDIT_FILTER_FS:
339 switch(f->type) { 339 switch(f->type) {
340 case AUDIT_FSTYPE: 340 case AUDIT_FSTYPE:
@@ -345,9 +345,16 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
345 } 345 }
346 } 346 }
347 347
348 switch(f->type) { 348 /* Check for valid field type and op */
349 default: 349 switch (f->type) {
350 return -EINVAL; 350 case AUDIT_ARG0:
351 case AUDIT_ARG1:
352 case AUDIT_ARG2:
353 case AUDIT_ARG3:
354 case AUDIT_PERS: /* <uapi/linux/personality.h> */
355 case AUDIT_DEVMINOR:
356 /* all ops are valid */
357 break;
351 case AUDIT_UID: 358 case AUDIT_UID:
352 case AUDIT_EUID: 359 case AUDIT_EUID:
353 case AUDIT_SUID: 360 case AUDIT_SUID:
@@ -360,46 +367,53 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
360 case AUDIT_FSGID: 367 case AUDIT_FSGID:
361 case AUDIT_OBJ_GID: 368 case AUDIT_OBJ_GID:
362 case AUDIT_PID: 369 case AUDIT_PID:
363 case AUDIT_PERS:
364 case AUDIT_MSGTYPE: 370 case AUDIT_MSGTYPE:
365 case AUDIT_PPID: 371 case AUDIT_PPID:
366 case AUDIT_DEVMAJOR: 372 case AUDIT_DEVMAJOR:
367 case AUDIT_DEVMINOR:
368 case AUDIT_EXIT: 373 case AUDIT_EXIT:
369 case AUDIT_SUCCESS: 374 case AUDIT_SUCCESS:
370 case AUDIT_INODE: 375 case AUDIT_INODE:
371 case AUDIT_SESSIONID: 376 case AUDIT_SESSIONID:
377 case AUDIT_SUBJ_SEN:
378 case AUDIT_SUBJ_CLR:
379 case AUDIT_OBJ_LEV_LOW:
380 case AUDIT_OBJ_LEV_HIGH:
381 case AUDIT_SADDR_FAM:
372 /* bit ops are only useful on syscall args */ 382 /* bit ops are only useful on syscall args */
373 if (f->op == Audit_bitmask || f->op == Audit_bittest) 383 if (f->op == Audit_bitmask || f->op == Audit_bittest)
374 return -EINVAL; 384 return -EINVAL;
375 break; 385 break;
376 case AUDIT_ARG0:
377 case AUDIT_ARG1:
378 case AUDIT_ARG2:
379 case AUDIT_ARG3:
380 case AUDIT_SUBJ_USER: 386 case AUDIT_SUBJ_USER:
381 case AUDIT_SUBJ_ROLE: 387 case AUDIT_SUBJ_ROLE:
382 case AUDIT_SUBJ_TYPE: 388 case AUDIT_SUBJ_TYPE:
383 case AUDIT_SUBJ_SEN:
384 case AUDIT_SUBJ_CLR:
385 case AUDIT_OBJ_USER: 389 case AUDIT_OBJ_USER:
386 case AUDIT_OBJ_ROLE: 390 case AUDIT_OBJ_ROLE:
387 case AUDIT_OBJ_TYPE: 391 case AUDIT_OBJ_TYPE:
388 case AUDIT_OBJ_LEV_LOW:
389 case AUDIT_OBJ_LEV_HIGH:
390 case AUDIT_WATCH: 392 case AUDIT_WATCH:
391 case AUDIT_DIR: 393 case AUDIT_DIR:
392 case AUDIT_FILTERKEY: 394 case AUDIT_FILTERKEY:
393 break;
394 case AUDIT_LOGINUID_SET: 395 case AUDIT_LOGINUID_SET:
395 if ((f->val != 0) && (f->val != 1))
396 return -EINVAL;
397 /* FALL THROUGH */
398 case AUDIT_ARCH: 396 case AUDIT_ARCH:
399 case AUDIT_FSTYPE: 397 case AUDIT_FSTYPE:
398 case AUDIT_PERM:
399 case AUDIT_FILETYPE:
400 case AUDIT_FIELD_COMPARE:
401 case AUDIT_EXE:
402 /* only equal and not equal valid ops */
400 if (f->op != Audit_not_equal && f->op != Audit_equal) 403 if (f->op != Audit_not_equal && f->op != Audit_equal)
401 return -EINVAL; 404 return -EINVAL;
402 break; 405 break;
406 default:
407 /* field not recognized */
408 return -EINVAL;
409 }
410
411 /* Check for select valid field values */
412 switch (f->type) {
413 case AUDIT_LOGINUID_SET:
414 if ((f->val != 0) && (f->val != 1))
415 return -EINVAL;
416 break;
403 case AUDIT_PERM: 417 case AUDIT_PERM:
404 if (f->val & ~15) 418 if (f->val & ~15)
405 return -EINVAL; 419 return -EINVAL;
@@ -412,11 +426,14 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
412 if (f->val > AUDIT_MAX_FIELD_COMPARE) 426 if (f->val > AUDIT_MAX_FIELD_COMPARE)
413 return -EINVAL; 427 return -EINVAL;
414 break; 428 break;
415 case AUDIT_EXE: 429 case AUDIT_SADDR_FAM:
416 if (f->op != Audit_not_equal && f->op != Audit_equal) 430 if (f->val >= AF_MAX)
417 return -EINVAL; 431 return -EINVAL;
418 break; 432 break;
433 default:
434 break;
419 } 435 }
436
420 return 0; 437 return 0;
421} 438}
422 439
@@ -1190,7 +1207,6 @@ int audit_comparator(u32 left, u32 op, u32 right)
1190 case Audit_bittest: 1207 case Audit_bittest:
1191 return ((left & right) == right); 1208 return ((left & right) == right);
1192 default: 1209 default:
1193 BUG();
1194 return 0; 1210 return 0;
1195 } 1211 }
1196} 1212}
@@ -1213,7 +1229,6 @@ int audit_uid_comparator(kuid_t left, u32 op, kuid_t right)
1213 case Audit_bitmask: 1229 case Audit_bitmask:
1214 case Audit_bittest: 1230 case Audit_bittest:
1215 default: 1231 default:
1216 BUG();
1217 return 0; 1232 return 0;
1218 } 1233 }
1219} 1234}
@@ -1236,7 +1251,6 @@ int audit_gid_comparator(kgid_t left, u32 op, kgid_t right)
1236 case Audit_bitmask: 1251 case Audit_bitmask:
1237 case Audit_bittest: 1252 case Audit_bittest:
1238 default: 1253 default:
1239 BUG();
1240 return 0; 1254 return 0;
1241 } 1255 }
1242} 1256}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 95ae27edd417..4effe01ebbe2 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -601,12 +601,20 @@ static int audit_filter_rules(struct task_struct *tsk,
601 } 601 }
602 break; 602 break;
603 case AUDIT_WATCH: 603 case AUDIT_WATCH:
604 if (name) 604 if (name) {
605 result = audit_watch_compare(rule->watch, name->ino, name->dev); 605 result = audit_watch_compare(rule->watch,
606 name->ino,
607 name->dev);
608 if (f->op == Audit_not_equal)
609 result = !result;
610 }
606 break; 611 break;
607 case AUDIT_DIR: 612 case AUDIT_DIR:
608 if (ctx) 613 if (ctx) {
609 result = match_tree_refs(ctx, rule->tree); 614 result = match_tree_refs(ctx, rule->tree);
615 if (f->op == Audit_not_equal)
616 result = !result;
617 }
610 break; 618 break;
611 case AUDIT_LOGINUID: 619 case AUDIT_LOGINUID:
612 result = audit_uid_comparator(audit_get_loginuid(tsk), 620 result = audit_uid_comparator(audit_get_loginuid(tsk),
@@ -615,6 +623,11 @@ static int audit_filter_rules(struct task_struct *tsk,
615 case AUDIT_LOGINUID_SET: 623 case AUDIT_LOGINUID_SET:
616 result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val); 624 result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val);
617 break; 625 break;
626 case AUDIT_SADDR_FAM:
627 if (ctx->sockaddr)
628 result = audit_comparator(ctx->sockaddr->ss_family,
629 f->op, f->val);
630 break;
618 case AUDIT_SUBJ_USER: 631 case AUDIT_SUBJ_USER:
619 case AUDIT_SUBJ_ROLE: 632 case AUDIT_SUBJ_ROLE:
620 case AUDIT_SUBJ_TYPE: 633 case AUDIT_SUBJ_TYPE:
@@ -684,9 +697,13 @@ static int audit_filter_rules(struct task_struct *tsk,
684 break; 697 break;
685 case AUDIT_PERM: 698 case AUDIT_PERM:
686 result = audit_match_perm(ctx, f->val); 699 result = audit_match_perm(ctx, f->val);
700 if (f->op == Audit_not_equal)
701 result = !result;
687 break; 702 break;
688 case AUDIT_FILETYPE: 703 case AUDIT_FILETYPE:
689 result = audit_match_filetype(ctx, f->val); 704 result = audit_match_filetype(ctx, f->val);
705 if (f->op == Audit_not_equal)
706 result = !result;
690 break; 707 break;
691 case AUDIT_FIELD_COMPARE: 708 case AUDIT_FIELD_COMPARE:
692 result = audit_field_compare(tsk, cred, f, ctx, name); 709 result = audit_field_compare(tsk, cred, f, ctx, name);
@@ -2360,30 +2377,17 @@ void __audit_ptrace(struct task_struct *t)
2360} 2377}
2361 2378
2362/** 2379/**
2363 * audit_signal_info - record signal info for shutting down audit subsystem 2380 * audit_signal_info_syscall - record signal info for syscalls
2364 * @sig: signal value
2365 * @t: task being signaled 2381 * @t: task being signaled
2366 * 2382 *
2367 * If the audit subsystem is being terminated, record the task (pid) 2383 * If the audit subsystem is being terminated, record the task (pid)
2368 * and uid that is doing that. 2384 * and uid that is doing that.
2369 */ 2385 */
2370int audit_signal_info(int sig, struct task_struct *t) 2386int audit_signal_info_syscall(struct task_struct *t)
2371{ 2387{
2372 struct audit_aux_data_pids *axp; 2388 struct audit_aux_data_pids *axp;
2373 struct audit_context *ctx = audit_context(); 2389 struct audit_context *ctx = audit_context();
2374 kuid_t uid = current_uid(), auid, t_uid = task_uid(t); 2390 kuid_t t_uid = task_uid(t);
2375
2376 if (auditd_test_task(t) &&
2377 (sig == SIGTERM || sig == SIGHUP ||
2378 sig == SIGUSR1 || sig == SIGUSR2)) {
2379 audit_sig_pid = task_tgid_nr(current);
2380 auid = audit_get_loginuid(current);
2381 if (uid_valid(auid))
2382 audit_sig_uid = auid;
2383 else
2384 audit_sig_uid = uid;
2385 security_task_getsecid(current, &audit_sig_sid);
2386 }
2387 2391
2388 if (!audit_signals || audit_dummy_context()) 2392 if (!audit_signals || audit_dummy_context())
2389 return 0; 2393 return 0;
diff --git a/kernel/signal.c b/kernel/signal.c
index edf8915ddd54..35e97f4073c2 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -45,6 +45,7 @@
45#include <linux/posix-timers.h> 45#include <linux/posix-timers.h>
46#include <linux/livepatch.h> 46#include <linux/livepatch.h>
47#include <linux/cgroup.h> 47#include <linux/cgroup.h>
48#include <linux/audit.h>
48 49
49#define CREATE_TRACE_POINTS 50#define CREATE_TRACE_POINTS
50#include <trace/events/signal.h> 51#include <trace/events/signal.h>
@@ -54,7 +55,6 @@
54#include <asm/unistd.h> 55#include <asm/unistd.h>
55#include <asm/siginfo.h> 56#include <asm/siginfo.h>
56#include <asm/cacheflush.h> 57#include <asm/cacheflush.h>
57#include "audit.h" /* audit_signal_info() */
58 58
59/* 59/*
60 * SLAB caches for signal bits. 60 * SLAB caches for signal bits.