diff options
-rw-r--r-- | include/linux/audit.h | 32 | ||||
-rw-r--r-- | include/uapi/linux/audit.h | 7 | ||||
-rw-r--r-- | kernel/audit.c | 12 | ||||
-rw-r--r-- | kernel/audit.h | 3 | ||||
-rw-r--r-- | kernel/auditsc.c | 40 | ||||
-rw-r--r-- | kernel/module.c | 5 | ||||
-rw-r--r-- | net/compat.c | 17 |
7 files changed, 96 insertions, 20 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index f51fca8d0b6f..504e784b7ffa 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -360,6 +360,7 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, | |||
360 | const struct cred *old); | 360 | const struct cred *old); |
361 | extern void __audit_log_capset(const struct cred *new, const struct cred *old); | 361 | extern void __audit_log_capset(const struct cred *new, const struct cred *old); |
362 | extern void __audit_mmap_fd(int fd, int flags); | 362 | extern void __audit_mmap_fd(int fd, int flags); |
363 | extern void __audit_log_kern_module(char *name); | ||
363 | 364 | ||
364 | static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) | 365 | static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) |
365 | { | 366 | { |
@@ -387,6 +388,20 @@ static inline int audit_socketcall(int nargs, unsigned long *args) | |||
387 | return __audit_socketcall(nargs, args); | 388 | return __audit_socketcall(nargs, args); |
388 | return 0; | 389 | return 0; |
389 | } | 390 | } |
391 | |||
392 | static inline int audit_socketcall_compat(int nargs, u32 *args) | ||
393 | { | ||
394 | unsigned long a[AUDITSC_ARGS]; | ||
395 | int i; | ||
396 | |||
397 | if (audit_dummy_context()) | ||
398 | return 0; | ||
399 | |||
400 | for (i = 0; i < nargs; i++) | ||
401 | a[i] = (unsigned long)args[i]; | ||
402 | return __audit_socketcall(nargs, a); | ||
403 | } | ||
404 | |||
390 | static inline int audit_sockaddr(int len, void *addr) | 405 | static inline int audit_sockaddr(int len, void *addr) |
391 | { | 406 | { |
392 | if (unlikely(!audit_dummy_context())) | 407 | if (unlikely(!audit_dummy_context())) |
@@ -436,6 +451,12 @@ static inline void audit_mmap_fd(int fd, int flags) | |||
436 | __audit_mmap_fd(fd, flags); | 451 | __audit_mmap_fd(fd, flags); |
437 | } | 452 | } |
438 | 453 | ||
454 | static inline void audit_log_kern_module(char *name) | ||
455 | { | ||
456 | if (!audit_dummy_context()) | ||
457 | __audit_log_kern_module(name); | ||
458 | } | ||
459 | |||
439 | extern int audit_n_rules; | 460 | extern int audit_n_rules; |
440 | extern int audit_signals; | 461 | extern int audit_signals; |
441 | #else /* CONFIG_AUDITSYSCALL */ | 462 | #else /* CONFIG_AUDITSYSCALL */ |
@@ -513,6 +534,12 @@ static inline int audit_socketcall(int nargs, unsigned long *args) | |||
513 | { | 534 | { |
514 | return 0; | 535 | return 0; |
515 | } | 536 | } |
537 | |||
538 | static inline int audit_socketcall_compat(int nargs, u32 *args) | ||
539 | { | ||
540 | return 0; | ||
541 | } | ||
542 | |||
516 | static inline void audit_fd_pair(int fd1, int fd2) | 543 | static inline void audit_fd_pair(int fd1, int fd2) |
517 | { } | 544 | { } |
518 | static inline int audit_sockaddr(int len, void *addr) | 545 | static inline int audit_sockaddr(int len, void *addr) |
@@ -541,6 +568,11 @@ static inline void audit_log_capset(const struct cred *new, | |||
541 | { } | 568 | { } |
542 | static inline void audit_mmap_fd(int fd, int flags) | 569 | static inline void audit_mmap_fd(int fd, int flags) |
543 | { } | 570 | { } |
571 | |||
572 | static inline void audit_log_kern_module(char *name) | ||
573 | { | ||
574 | } | ||
575 | |||
544 | static inline void audit_ptrace(struct task_struct *t) | 576 | static inline void audit_ptrace(struct task_struct *t) |
545 | { } | 577 | { } |
546 | #define audit_n_rules 0 | 578 | #define audit_n_rules 0 |
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index 1c107cb1c83f..0714a66f0e0c 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h | |||
@@ -111,6 +111,7 @@ | |||
111 | #define AUDIT_PROCTITLE 1327 /* Proctitle emit event */ | 111 | #define AUDIT_PROCTITLE 1327 /* Proctitle emit event */ |
112 | #define AUDIT_FEATURE_CHANGE 1328 /* audit log listing feature changes */ | 112 | #define AUDIT_FEATURE_CHANGE 1328 /* audit log listing feature changes */ |
113 | #define AUDIT_REPLACE 1329 /* Replace auditd if this packet unanswerd */ | 113 | #define AUDIT_REPLACE 1329 /* Replace auditd if this packet unanswerd */ |
114 | #define AUDIT_KERN_MODULE 1330 /* Kernel Module events */ | ||
114 | 115 | ||
115 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ | 116 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ |
116 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ | 117 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ |
@@ -326,17 +327,21 @@ enum { | |||
326 | #define AUDIT_STATUS_RATE_LIMIT 0x0008 | 327 | #define AUDIT_STATUS_RATE_LIMIT 0x0008 |
327 | #define AUDIT_STATUS_BACKLOG_LIMIT 0x0010 | 328 | #define AUDIT_STATUS_BACKLOG_LIMIT 0x0010 |
328 | #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020 | 329 | #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020 |
330 | #define AUDIT_STATUS_LOST 0x0040 | ||
329 | 331 | ||
330 | #define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT 0x00000001 | 332 | #define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT 0x00000001 |
331 | #define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002 | 333 | #define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002 |
332 | #define AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH 0x00000004 | 334 | #define AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH 0x00000004 |
333 | #define AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND 0x00000008 | 335 | #define AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND 0x00000008 |
334 | #define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER 0x00000010 | 336 | #define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER 0x00000010 |
337 | #define AUDIT_FEATURE_BITMAP_LOST_RESET 0x00000020 | ||
338 | |||
335 | #define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \ | 339 | #define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \ |
336 | AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | \ | 340 | AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | \ |
337 | AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | \ | 341 | AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | \ |
338 | AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | \ | 342 | AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | \ |
339 | AUDIT_FEATURE_BITMAP_SESSIONID_FILTER) | 343 | AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | \ |
344 | AUDIT_FEATURE_BITMAP_LOST_RESET) | ||
340 | 345 | ||
341 | /* deprecated: AUDIT_VERSION_* */ | 346 | /* deprecated: AUDIT_VERSION_* */ |
342 | #define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL | 347 | #define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL |
diff --git a/kernel/audit.c b/kernel/audit.c index 6e399bb69d7c..e794544f5e63 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -121,7 +121,7 @@ u32 audit_sig_sid = 0; | |||
121 | 3) suppressed due to audit_rate_limit | 121 | 3) suppressed due to audit_rate_limit |
122 | 4) suppressed due to audit_backlog_limit | 122 | 4) suppressed due to audit_backlog_limit |
123 | */ | 123 | */ |
124 | static atomic_t audit_lost = ATOMIC_INIT(0); | 124 | static atomic_t audit_lost = ATOMIC_INIT(0); |
125 | 125 | ||
126 | /* The netlink socket. */ | 126 | /* The netlink socket. */ |
127 | static struct sock *audit_sock; | 127 | static struct sock *audit_sock; |
@@ -1058,6 +1058,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1058 | if (err < 0) | 1058 | if (err < 0) |
1059 | return err; | 1059 | return err; |
1060 | } | 1060 | } |
1061 | if (s.mask == AUDIT_STATUS_LOST) { | ||
1062 | u32 lost = atomic_xchg(&audit_lost, 0); | ||
1063 | |||
1064 | audit_log_config_change("lost", 0, lost, 1); | ||
1065 | return lost; | ||
1066 | } | ||
1061 | break; | 1067 | break; |
1062 | } | 1068 | } |
1063 | case AUDIT_GET_FEATURE: | 1069 | case AUDIT_GET_FEATURE: |
@@ -1349,7 +1355,9 @@ static int __init audit_init(void) | |||
1349 | panic("audit: failed to start the kauditd thread (%d)\n", err); | 1355 | panic("audit: failed to start the kauditd thread (%d)\n", err); |
1350 | } | 1356 | } |
1351 | 1357 | ||
1352 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); | 1358 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, |
1359 | "state=initialized audit_enabled=%u res=1", | ||
1360 | audit_enabled); | ||
1353 | 1361 | ||
1354 | return 0; | 1362 | return 0; |
1355 | } | 1363 | } |
diff --git a/kernel/audit.h b/kernel/audit.h index 960d49c9db5e..ca579880303a 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
@@ -199,6 +199,9 @@ struct audit_context { | |||
199 | struct { | 199 | struct { |
200 | int argc; | 200 | int argc; |
201 | } execve; | 201 | } execve; |
202 | struct { | ||
203 | char *name; | ||
204 | } module; | ||
202 | }; | 205 | }; |
203 | int fds[2]; | 206 | int fds[2]; |
204 | struct audit_proctitle proctitle; | 207 | struct audit_proctitle proctitle; |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index cf1fa43512c1..d6a8de5f8fa3 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -1221,7 +1221,7 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
1221 | context->ipc.perm_mode); | 1221 | context->ipc.perm_mode); |
1222 | } | 1222 | } |
1223 | break; } | 1223 | break; } |
1224 | case AUDIT_MQ_OPEN: { | 1224 | case AUDIT_MQ_OPEN: |
1225 | audit_log_format(ab, | 1225 | audit_log_format(ab, |
1226 | "oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld " | 1226 | "oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld " |
1227 | "mq_msgsize=%ld mq_curmsgs=%ld", | 1227 | "mq_msgsize=%ld mq_curmsgs=%ld", |
@@ -1230,8 +1230,8 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
1230 | context->mq_open.attr.mq_maxmsg, | 1230 | context->mq_open.attr.mq_maxmsg, |
1231 | context->mq_open.attr.mq_msgsize, | 1231 | context->mq_open.attr.mq_msgsize, |
1232 | context->mq_open.attr.mq_curmsgs); | 1232 | context->mq_open.attr.mq_curmsgs); |
1233 | break; } | 1233 | break; |
1234 | case AUDIT_MQ_SENDRECV: { | 1234 | case AUDIT_MQ_SENDRECV: |
1235 | audit_log_format(ab, | 1235 | audit_log_format(ab, |
1236 | "mqdes=%d msg_len=%zd msg_prio=%u " | 1236 | "mqdes=%d msg_len=%zd msg_prio=%u " |
1237 | "abs_timeout_sec=%ld abs_timeout_nsec=%ld", | 1237 | "abs_timeout_sec=%ld abs_timeout_nsec=%ld", |
@@ -1240,12 +1240,12 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
1240 | context->mq_sendrecv.msg_prio, | 1240 | context->mq_sendrecv.msg_prio, |
1241 | context->mq_sendrecv.abs_timeout.tv_sec, | 1241 | context->mq_sendrecv.abs_timeout.tv_sec, |
1242 | context->mq_sendrecv.abs_timeout.tv_nsec); | 1242 | context->mq_sendrecv.abs_timeout.tv_nsec); |
1243 | break; } | 1243 | break; |
1244 | case AUDIT_MQ_NOTIFY: { | 1244 | case AUDIT_MQ_NOTIFY: |
1245 | audit_log_format(ab, "mqdes=%d sigev_signo=%d", | 1245 | audit_log_format(ab, "mqdes=%d sigev_signo=%d", |
1246 | context->mq_notify.mqdes, | 1246 | context->mq_notify.mqdes, |
1247 | context->mq_notify.sigev_signo); | 1247 | context->mq_notify.sigev_signo); |
1248 | break; } | 1248 | break; |
1249 | case AUDIT_MQ_GETSETATTR: { | 1249 | case AUDIT_MQ_GETSETATTR: { |
1250 | struct mq_attr *attr = &context->mq_getsetattr.mqstat; | 1250 | struct mq_attr *attr = &context->mq_getsetattr.mqstat; |
1251 | audit_log_format(ab, | 1251 | audit_log_format(ab, |
@@ -1255,19 +1255,24 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
1255 | attr->mq_flags, attr->mq_maxmsg, | 1255 | attr->mq_flags, attr->mq_maxmsg, |
1256 | attr->mq_msgsize, attr->mq_curmsgs); | 1256 | attr->mq_msgsize, attr->mq_curmsgs); |
1257 | break; } | 1257 | break; } |
1258 | case AUDIT_CAPSET: { | 1258 | case AUDIT_CAPSET: |
1259 | audit_log_format(ab, "pid=%d", context->capset.pid); | 1259 | audit_log_format(ab, "pid=%d", context->capset.pid); |
1260 | audit_log_cap(ab, "cap_pi", &context->capset.cap.inheritable); | 1260 | audit_log_cap(ab, "cap_pi", &context->capset.cap.inheritable); |
1261 | audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted); | 1261 | audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted); |
1262 | audit_log_cap(ab, "cap_pe", &context->capset.cap.effective); | 1262 | audit_log_cap(ab, "cap_pe", &context->capset.cap.effective); |
1263 | break; } | 1263 | break; |
1264 | case AUDIT_MMAP: { | 1264 | case AUDIT_MMAP: |
1265 | audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd, | 1265 | audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd, |
1266 | context->mmap.flags); | 1266 | context->mmap.flags); |
1267 | break; } | 1267 | break; |
1268 | case AUDIT_EXECVE: { | 1268 | case AUDIT_EXECVE: |
1269 | audit_log_execve_info(context, &ab); | 1269 | audit_log_execve_info(context, &ab); |
1270 | break; } | 1270 | break; |
1271 | case AUDIT_KERN_MODULE: | ||
1272 | audit_log_format(ab, "name="); | ||
1273 | audit_log_untrustedstring(ab, context->module.name); | ||
1274 | kfree(context->module.name); | ||
1275 | break; | ||
1271 | } | 1276 | } |
1272 | audit_log_end(ab); | 1277 | audit_log_end(ab); |
1273 | } | 1278 | } |
@@ -2368,6 +2373,15 @@ void __audit_mmap_fd(int fd, int flags) | |||
2368 | context->type = AUDIT_MMAP; | 2373 | context->type = AUDIT_MMAP; |
2369 | } | 2374 | } |
2370 | 2375 | ||
2376 | void __audit_log_kern_module(char *name) | ||
2377 | { | ||
2378 | struct audit_context *context = current->audit_context; | ||
2379 | |||
2380 | context->module.name = kmalloc(strlen(name) + 1, GFP_KERNEL); | ||
2381 | strcpy(context->module.name, name); | ||
2382 | context->type = AUDIT_KERN_MODULE; | ||
2383 | } | ||
2384 | |||
2371 | static void audit_log_task(struct audit_buffer *ab) | 2385 | static void audit_log_task(struct audit_buffer *ab) |
2372 | { | 2386 | { |
2373 | kuid_t auid, uid; | 2387 | kuid_t auid, uid; |
@@ -2411,7 +2425,7 @@ void audit_core_dumps(long signr) | |||
2411 | if (unlikely(!ab)) | 2425 | if (unlikely(!ab)) |
2412 | return; | 2426 | return; |
2413 | audit_log_task(ab); | 2427 | audit_log_task(ab); |
2414 | audit_log_format(ab, " sig=%ld", signr); | 2428 | audit_log_format(ab, " sig=%ld res=1", signr); |
2415 | audit_log_end(ab); | 2429 | audit_log_end(ab); |
2416 | } | 2430 | } |
2417 | 2431 | ||
diff --git a/kernel/module.c b/kernel/module.c index 3d8f126208e3..e2eec4b47143 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -61,6 +61,7 @@ | |||
61 | #include <linux/pfn.h> | 61 | #include <linux/pfn.h> |
62 | #include <linux/bsearch.h> | 62 | #include <linux/bsearch.h> |
63 | #include <linux/dynamic_debug.h> | 63 | #include <linux/dynamic_debug.h> |
64 | #include <linux/audit.h> | ||
64 | #include <uapi/linux/module.h> | 65 | #include <uapi/linux/module.h> |
65 | #include "module-internal.h" | 66 | #include "module-internal.h" |
66 | 67 | ||
@@ -3608,6 +3609,8 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
3608 | goto free_copy; | 3609 | goto free_copy; |
3609 | } | 3610 | } |
3610 | 3611 | ||
3612 | audit_log_kern_module(mod->name); | ||
3613 | |||
3611 | /* Reserve our place in the list. */ | 3614 | /* Reserve our place in the list. */ |
3612 | err = add_unformed_module(mod); | 3615 | err = add_unformed_module(mod); |
3613 | if (err) | 3616 | if (err) |
@@ -3696,7 +3699,7 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
3696 | mod->name, after_dashes); | 3699 | mod->name, after_dashes); |
3697 | } | 3700 | } |
3698 | 3701 | ||
3699 | /* Link in to syfs. */ | 3702 | /* Link in to sysfs. */ |
3700 | err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp); | 3703 | err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp); |
3701 | if (err < 0) | 3704 | if (err < 0) |
3702 | goto coming_cleanup; | 3705 | goto coming_cleanup; |
diff --git a/net/compat.c b/net/compat.c index 96c544b05b15..d69f539ca0bc 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/filter.h> | 22 | #include <linux/filter.h> |
23 | #include <linux/compat.h> | 23 | #include <linux/compat.h> |
24 | #include <linux/security.h> | 24 | #include <linux/security.h> |
25 | #include <linux/audit.h> | ||
25 | #include <linux/export.h> | 26 | #include <linux/export.h> |
26 | 27 | ||
27 | #include <net/scm.h> | 28 | #include <net/scm.h> |
@@ -781,14 +782,24 @@ COMPAT_SYSCALL_DEFINE5(recvmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, | |||
781 | 782 | ||
782 | COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) | 783 | COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) |
783 | { | 784 | { |
784 | int ret; | 785 | u32 a[AUDITSC_ARGS]; |
785 | u32 a[6]; | 786 | unsigned int len; |
786 | u32 a0, a1; | 787 | u32 a0, a1; |
788 | int ret; | ||
787 | 789 | ||
788 | if (call < SYS_SOCKET || call > SYS_SENDMMSG) | 790 | if (call < SYS_SOCKET || call > SYS_SENDMMSG) |
789 | return -EINVAL; | 791 | return -EINVAL; |
790 | if (copy_from_user(a, args, nas[call])) | 792 | len = nas[call]; |
793 | if (len > sizeof(a)) | ||
794 | return -EINVAL; | ||
795 | |||
796 | if (copy_from_user(a, args, len)) | ||
791 | return -EFAULT; | 797 | return -EFAULT; |
798 | |||
799 | ret = audit_socketcall_compat(len / sizeof(a[0]), a); | ||
800 | if (ret) | ||
801 | return ret; | ||
802 | |||
792 | a0 = a[0]; | 803 | a0 = a[0]; |
793 | a1 = a[1]; | 804 | a1 = a[1]; |
794 | 805 | ||