diff options
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 255 |
1 files changed, 226 insertions, 29 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index cf5bc2f5f9c3..bc1e2d854bf6 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -65,6 +65,7 @@ | |||
65 | #include <linux/highmem.h> | 65 | #include <linux/highmem.h> |
66 | #include <linux/syscalls.h> | 66 | #include <linux/syscalls.h> |
67 | #include <linux/inotify.h> | 67 | #include <linux/inotify.h> |
68 | #include <linux/capability.h> | ||
68 | 69 | ||
69 | #include "audit.h" | 70 | #include "audit.h" |
70 | 71 | ||
@@ -84,6 +85,15 @@ int audit_n_rules; | |||
84 | /* determines whether we collect data for signals sent */ | 85 | /* determines whether we collect data for signals sent */ |
85 | int audit_signals; | 86 | int audit_signals; |
86 | 87 | ||
88 | struct audit_cap_data { | ||
89 | kernel_cap_t permitted; | ||
90 | kernel_cap_t inheritable; | ||
91 | union { | ||
92 | unsigned int fE; /* effective bit of a file capability */ | ||
93 | kernel_cap_t effective; /* effective set of a process */ | ||
94 | }; | ||
95 | }; | ||
96 | |||
87 | /* When fs/namei.c:getname() is called, we store the pointer in name and | 97 | /* When fs/namei.c:getname() is called, we store the pointer in name and |
88 | * we don't let putname() free it (instead we free all of the saved | 98 | * we don't let putname() free it (instead we free all of the saved |
89 | * pointers at syscall exit time). | 99 | * pointers at syscall exit time). |
@@ -100,6 +110,8 @@ struct audit_names { | |||
100 | gid_t gid; | 110 | gid_t gid; |
101 | dev_t rdev; | 111 | dev_t rdev; |
102 | u32 osid; | 112 | u32 osid; |
113 | struct audit_cap_data fcap; | ||
114 | unsigned int fcap_ver; | ||
103 | }; | 115 | }; |
104 | 116 | ||
105 | struct audit_aux_data { | 117 | struct audit_aux_data { |
@@ -184,6 +196,20 @@ struct audit_aux_data_pids { | |||
184 | int pid_count; | 196 | int pid_count; |
185 | }; | 197 | }; |
186 | 198 | ||
199 | struct audit_aux_data_bprm_fcaps { | ||
200 | struct audit_aux_data d; | ||
201 | struct audit_cap_data fcap; | ||
202 | unsigned int fcap_ver; | ||
203 | struct audit_cap_data old_pcap; | ||
204 | struct audit_cap_data new_pcap; | ||
205 | }; | ||
206 | |||
207 | struct audit_aux_data_capset { | ||
208 | struct audit_aux_data d; | ||
209 | pid_t pid; | ||
210 | struct audit_cap_data cap; | ||
211 | }; | ||
212 | |||
187 | struct audit_tree_refs { | 213 | struct audit_tree_refs { |
188 | struct audit_tree_refs *next; | 214 | struct audit_tree_refs *next; |
189 | struct audit_chunk *c[31]; | 215 | struct audit_chunk *c[31]; |
@@ -421,6 +447,7 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
421 | struct audit_names *name, | 447 | struct audit_names *name, |
422 | enum audit_state *state) | 448 | enum audit_state *state) |
423 | { | 449 | { |
450 | const struct cred *cred = get_task_cred(tsk); | ||
424 | int i, j, need_sid = 1; | 451 | int i, j, need_sid = 1; |
425 | u32 sid; | 452 | u32 sid; |
426 | 453 | ||
@@ -440,28 +467,28 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
440 | } | 467 | } |
441 | break; | 468 | break; |
442 | case AUDIT_UID: | 469 | case AUDIT_UID: |
443 | result = audit_comparator(tsk->uid, f->op, f->val); | 470 | result = audit_comparator(cred->uid, f->op, f->val); |
444 | break; | 471 | break; |
445 | case AUDIT_EUID: | 472 | case AUDIT_EUID: |
446 | result = audit_comparator(tsk->euid, f->op, f->val); | 473 | result = audit_comparator(cred->euid, f->op, f->val); |
447 | break; | 474 | break; |
448 | case AUDIT_SUID: | 475 | case AUDIT_SUID: |
449 | result = audit_comparator(tsk->suid, f->op, f->val); | 476 | result = audit_comparator(cred->suid, f->op, f->val); |
450 | break; | 477 | break; |
451 | case AUDIT_FSUID: | 478 | case AUDIT_FSUID: |
452 | result = audit_comparator(tsk->fsuid, f->op, f->val); | 479 | result = audit_comparator(cred->fsuid, f->op, f->val); |
453 | break; | 480 | break; |
454 | case AUDIT_GID: | 481 | case AUDIT_GID: |
455 | result = audit_comparator(tsk->gid, f->op, f->val); | 482 | result = audit_comparator(cred->gid, f->op, f->val); |
456 | break; | 483 | break; |
457 | case AUDIT_EGID: | 484 | case AUDIT_EGID: |
458 | result = audit_comparator(tsk->egid, f->op, f->val); | 485 | result = audit_comparator(cred->egid, f->op, f->val); |
459 | break; | 486 | break; |
460 | case AUDIT_SGID: | 487 | case AUDIT_SGID: |
461 | result = audit_comparator(tsk->sgid, f->op, f->val); | 488 | result = audit_comparator(cred->sgid, f->op, f->val); |
462 | break; | 489 | break; |
463 | case AUDIT_FSGID: | 490 | case AUDIT_FSGID: |
464 | result = audit_comparator(tsk->fsgid, f->op, f->val); | 491 | result = audit_comparator(cred->fsgid, f->op, f->val); |
465 | break; | 492 | break; |
466 | case AUDIT_PERS: | 493 | case AUDIT_PERS: |
467 | result = audit_comparator(tsk->personality, f->op, f->val); | 494 | result = audit_comparator(tsk->personality, f->op, f->val); |
@@ -615,8 +642,10 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
615 | break; | 642 | break; |
616 | } | 643 | } |
617 | 644 | ||
618 | if (!result) | 645 | if (!result) { |
646 | put_cred(cred); | ||
619 | return 0; | 647 | return 0; |
648 | } | ||
620 | } | 649 | } |
621 | if (rule->filterkey && ctx) | 650 | if (rule->filterkey && ctx) |
622 | ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC); | 651 | ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC); |
@@ -624,6 +653,7 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
624 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; | 653 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; |
625 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; | 654 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; |
626 | } | 655 | } |
656 | put_cred(cred); | ||
627 | return 1; | 657 | return 1; |
628 | } | 658 | } |
629 | 659 | ||
@@ -1171,8 +1201,38 @@ static void audit_log_execve_info(struct audit_context *context, | |||
1171 | kfree(buf); | 1201 | kfree(buf); |
1172 | } | 1202 | } |
1173 | 1203 | ||
1204 | static void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap) | ||
1205 | { | ||
1206 | int i; | ||
1207 | |||
1208 | audit_log_format(ab, " %s=", prefix); | ||
1209 | CAP_FOR_EACH_U32(i) { | ||
1210 | audit_log_format(ab, "%08x", cap->cap[(_KERNEL_CAPABILITY_U32S-1) - i]); | ||
1211 | } | ||
1212 | } | ||
1213 | |||
1214 | static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) | ||
1215 | { | ||
1216 | kernel_cap_t *perm = &name->fcap.permitted; | ||
1217 | kernel_cap_t *inh = &name->fcap.inheritable; | ||
1218 | int log = 0; | ||
1219 | |||
1220 | if (!cap_isclear(*perm)) { | ||
1221 | audit_log_cap(ab, "cap_fp", perm); | ||
1222 | log = 1; | ||
1223 | } | ||
1224 | if (!cap_isclear(*inh)) { | ||
1225 | audit_log_cap(ab, "cap_fi", inh); | ||
1226 | log = 1; | ||
1227 | } | ||
1228 | |||
1229 | if (log) | ||
1230 | audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver); | ||
1231 | } | ||
1232 | |||
1174 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) | 1233 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) |
1175 | { | 1234 | { |
1235 | const struct cred *cred; | ||
1176 | int i, call_panic = 0; | 1236 | int i, call_panic = 0; |
1177 | struct audit_buffer *ab; | 1237 | struct audit_buffer *ab; |
1178 | struct audit_aux_data *aux; | 1238 | struct audit_aux_data *aux; |
@@ -1182,14 +1242,15 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1182 | context->pid = tsk->pid; | 1242 | context->pid = tsk->pid; |
1183 | if (!context->ppid) | 1243 | if (!context->ppid) |
1184 | context->ppid = sys_getppid(); | 1244 | context->ppid = sys_getppid(); |
1185 | context->uid = tsk->uid; | 1245 | cred = current_cred(); |
1186 | context->gid = tsk->gid; | 1246 | context->uid = cred->uid; |
1187 | context->euid = tsk->euid; | 1247 | context->gid = cred->gid; |
1188 | context->suid = tsk->suid; | 1248 | context->euid = cred->euid; |
1189 | context->fsuid = tsk->fsuid; | 1249 | context->suid = cred->suid; |
1190 | context->egid = tsk->egid; | 1250 | context->fsuid = cred->fsuid; |
1191 | context->sgid = tsk->sgid; | 1251 | context->egid = cred->egid; |
1192 | context->fsgid = tsk->fsgid; | 1252 | context->sgid = cred->sgid; |
1253 | context->fsgid = cred->fsgid; | ||
1193 | context->personality = tsk->personality; | 1254 | context->personality = tsk->personality; |
1194 | 1255 | ||
1195 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL); | 1256 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL); |
@@ -1334,6 +1395,28 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1334 | audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); | 1395 | audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); |
1335 | break; } | 1396 | break; } |
1336 | 1397 | ||
1398 | case AUDIT_BPRM_FCAPS: { | ||
1399 | struct audit_aux_data_bprm_fcaps *axs = (void *)aux; | ||
1400 | audit_log_format(ab, "fver=%x", axs->fcap_ver); | ||
1401 | audit_log_cap(ab, "fp", &axs->fcap.permitted); | ||
1402 | audit_log_cap(ab, "fi", &axs->fcap.inheritable); | ||
1403 | audit_log_format(ab, " fe=%d", axs->fcap.fE); | ||
1404 | audit_log_cap(ab, "old_pp", &axs->old_pcap.permitted); | ||
1405 | audit_log_cap(ab, "old_pi", &axs->old_pcap.inheritable); | ||
1406 | audit_log_cap(ab, "old_pe", &axs->old_pcap.effective); | ||
1407 | audit_log_cap(ab, "new_pp", &axs->new_pcap.permitted); | ||
1408 | audit_log_cap(ab, "new_pi", &axs->new_pcap.inheritable); | ||
1409 | audit_log_cap(ab, "new_pe", &axs->new_pcap.effective); | ||
1410 | break; } | ||
1411 | |||
1412 | case AUDIT_CAPSET: { | ||
1413 | struct audit_aux_data_capset *axs = (void *)aux; | ||
1414 | audit_log_format(ab, "pid=%d", axs->pid); | ||
1415 | audit_log_cap(ab, "cap_pi", &axs->cap.inheritable); | ||
1416 | audit_log_cap(ab, "cap_pp", &axs->cap.permitted); | ||
1417 | audit_log_cap(ab, "cap_pe", &axs->cap.effective); | ||
1418 | break; } | ||
1419 | |||
1337 | } | 1420 | } |
1338 | audit_log_end(ab); | 1421 | audit_log_end(ab); |
1339 | } | 1422 | } |
@@ -1421,6 +1504,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1421 | } | 1504 | } |
1422 | } | 1505 | } |
1423 | 1506 | ||
1507 | audit_log_fcaps(ab, n); | ||
1508 | |||
1424 | audit_log_end(ab); | 1509 | audit_log_end(ab); |
1425 | } | 1510 | } |
1426 | 1511 | ||
@@ -1787,8 +1872,36 @@ static int audit_inc_name_count(struct audit_context *context, | |||
1787 | return 0; | 1872 | return 0; |
1788 | } | 1873 | } |
1789 | 1874 | ||
1875 | |||
1876 | static inline int audit_copy_fcaps(struct audit_names *name, const struct dentry *dentry) | ||
1877 | { | ||
1878 | struct cpu_vfs_cap_data caps; | ||
1879 | int rc; | ||
1880 | |||
1881 | memset(&name->fcap.permitted, 0, sizeof(kernel_cap_t)); | ||
1882 | memset(&name->fcap.inheritable, 0, sizeof(kernel_cap_t)); | ||
1883 | name->fcap.fE = 0; | ||
1884 | name->fcap_ver = 0; | ||
1885 | |||
1886 | if (!dentry) | ||
1887 | return 0; | ||
1888 | |||
1889 | rc = get_vfs_caps_from_disk(dentry, &caps); | ||
1890 | if (rc) | ||
1891 | return rc; | ||
1892 | |||
1893 | name->fcap.permitted = caps.permitted; | ||
1894 | name->fcap.inheritable = caps.inheritable; | ||
1895 | name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); | ||
1896 | name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT; | ||
1897 | |||
1898 | return 0; | ||
1899 | } | ||
1900 | |||
1901 | |||
1790 | /* Copy inode data into an audit_names. */ | 1902 | /* Copy inode data into an audit_names. */ |
1791 | static void audit_copy_inode(struct audit_names *name, const struct inode *inode) | 1903 | static void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, |
1904 | const struct inode *inode) | ||
1792 | { | 1905 | { |
1793 | name->ino = inode->i_ino; | 1906 | name->ino = inode->i_ino; |
1794 | name->dev = inode->i_sb->s_dev; | 1907 | name->dev = inode->i_sb->s_dev; |
@@ -1797,6 +1910,7 @@ static void audit_copy_inode(struct audit_names *name, const struct inode *inode | |||
1797 | name->gid = inode->i_gid; | 1910 | name->gid = inode->i_gid; |
1798 | name->rdev = inode->i_rdev; | 1911 | name->rdev = inode->i_rdev; |
1799 | security_inode_getsecid(inode, &name->osid); | 1912 | security_inode_getsecid(inode, &name->osid); |
1913 | audit_copy_fcaps(name, dentry); | ||
1800 | } | 1914 | } |
1801 | 1915 | ||
1802 | /** | 1916 | /** |
@@ -1831,7 +1945,7 @@ void __audit_inode(const char *name, const struct dentry *dentry) | |||
1831 | context->names[idx].name = NULL; | 1945 | context->names[idx].name = NULL; |
1832 | } | 1946 | } |
1833 | handle_path(dentry); | 1947 | handle_path(dentry); |
1834 | audit_copy_inode(&context->names[idx], inode); | 1948 | audit_copy_inode(&context->names[idx], dentry, inode); |
1835 | } | 1949 | } |
1836 | 1950 | ||
1837 | /** | 1951 | /** |
@@ -1892,7 +2006,7 @@ void __audit_inode_child(const char *dname, const struct dentry *dentry, | |||
1892 | if (!strcmp(dname, n->name) || | 2006 | if (!strcmp(dname, n->name) || |
1893 | !audit_compare_dname_path(dname, n->name, &dirlen)) { | 2007 | !audit_compare_dname_path(dname, n->name, &dirlen)) { |
1894 | if (inode) | 2008 | if (inode) |
1895 | audit_copy_inode(n, inode); | 2009 | audit_copy_inode(n, NULL, inode); |
1896 | else | 2010 | else |
1897 | n->ino = (unsigned long)-1; | 2011 | n->ino = (unsigned long)-1; |
1898 | found_child = n->name; | 2012 | found_child = n->name; |
@@ -1906,7 +2020,7 @@ add_names: | |||
1906 | return; | 2020 | return; |
1907 | idx = context->name_count - 1; | 2021 | idx = context->name_count - 1; |
1908 | context->names[idx].name = NULL; | 2022 | context->names[idx].name = NULL; |
1909 | audit_copy_inode(&context->names[idx], parent); | 2023 | audit_copy_inode(&context->names[idx], NULL, parent); |
1910 | } | 2024 | } |
1911 | 2025 | ||
1912 | if (!found_child) { | 2026 | if (!found_child) { |
@@ -1927,7 +2041,7 @@ add_names: | |||
1927 | } | 2041 | } |
1928 | 2042 | ||
1929 | if (inode) | 2043 | if (inode) |
1930 | audit_copy_inode(&context->names[idx], inode); | 2044 | audit_copy_inode(&context->names[idx], NULL, inode); |
1931 | else | 2045 | else |
1932 | context->names[idx].ino = (unsigned long)-1; | 2046 | context->names[idx].ino = (unsigned long)-1; |
1933 | } | 2047 | } |
@@ -1978,7 +2092,7 @@ int audit_set_loginuid(struct task_struct *task, uid_t loginuid) | |||
1978 | audit_log_format(ab, "login pid=%d uid=%u " | 2092 | audit_log_format(ab, "login pid=%d uid=%u " |
1979 | "old auid=%u new auid=%u" | 2093 | "old auid=%u new auid=%u" |
1980 | " old ses=%u new ses=%u", | 2094 | " old ses=%u new ses=%u", |
1981 | task->pid, task->uid, | 2095 | task->pid, task_uid(task), |
1982 | task->loginuid, loginuid, | 2096 | task->loginuid, loginuid, |
1983 | task->sessionid, sessionid); | 2097 | task->sessionid, sessionid); |
1984 | audit_log_end(ab); | 2098 | audit_log_end(ab); |
@@ -2361,7 +2475,7 @@ void __audit_ptrace(struct task_struct *t) | |||
2361 | 2475 | ||
2362 | context->target_pid = t->pid; | 2476 | context->target_pid = t->pid; |
2363 | context->target_auid = audit_get_loginuid(t); | 2477 | context->target_auid = audit_get_loginuid(t); |
2364 | context->target_uid = t->uid; | 2478 | context->target_uid = task_uid(t); |
2365 | context->target_sessionid = audit_get_sessionid(t); | 2479 | context->target_sessionid = audit_get_sessionid(t); |
2366 | security_task_getsecid(t, &context->target_sid); | 2480 | security_task_getsecid(t, &context->target_sid); |
2367 | memcpy(context->target_comm, t->comm, TASK_COMM_LEN); | 2481 | memcpy(context->target_comm, t->comm, TASK_COMM_LEN); |
@@ -2380,6 +2494,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2380 | struct audit_aux_data_pids *axp; | 2494 | struct audit_aux_data_pids *axp; |
2381 | struct task_struct *tsk = current; | 2495 | struct task_struct *tsk = current; |
2382 | struct audit_context *ctx = tsk->audit_context; | 2496 | struct audit_context *ctx = tsk->audit_context; |
2497 | uid_t uid = current_uid(), t_uid = task_uid(t); | ||
2383 | 2498 | ||
2384 | if (audit_pid && t->tgid == audit_pid) { | 2499 | if (audit_pid && t->tgid == audit_pid) { |
2385 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) { | 2500 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) { |
@@ -2387,7 +2502,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2387 | if (tsk->loginuid != -1) | 2502 | if (tsk->loginuid != -1) |
2388 | audit_sig_uid = tsk->loginuid; | 2503 | audit_sig_uid = tsk->loginuid; |
2389 | else | 2504 | else |
2390 | audit_sig_uid = tsk->uid; | 2505 | audit_sig_uid = uid; |
2391 | security_task_getsecid(tsk, &audit_sig_sid); | 2506 | security_task_getsecid(tsk, &audit_sig_sid); |
2392 | } | 2507 | } |
2393 | if (!audit_signals || audit_dummy_context()) | 2508 | if (!audit_signals || audit_dummy_context()) |
@@ -2399,7 +2514,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2399 | if (!ctx->target_pid) { | 2514 | if (!ctx->target_pid) { |
2400 | ctx->target_pid = t->tgid; | 2515 | ctx->target_pid = t->tgid; |
2401 | ctx->target_auid = audit_get_loginuid(t); | 2516 | ctx->target_auid = audit_get_loginuid(t); |
2402 | ctx->target_uid = t->uid; | 2517 | ctx->target_uid = t_uid; |
2403 | ctx->target_sessionid = audit_get_sessionid(t); | 2518 | ctx->target_sessionid = audit_get_sessionid(t); |
2404 | security_task_getsecid(t, &ctx->target_sid); | 2519 | security_task_getsecid(t, &ctx->target_sid); |
2405 | memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); | 2520 | memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); |
@@ -2420,7 +2535,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2420 | 2535 | ||
2421 | axp->target_pid[axp->pid_count] = t->tgid; | 2536 | axp->target_pid[axp->pid_count] = t->tgid; |
2422 | axp->target_auid[axp->pid_count] = audit_get_loginuid(t); | 2537 | axp->target_auid[axp->pid_count] = audit_get_loginuid(t); |
2423 | axp->target_uid[axp->pid_count] = t->uid; | 2538 | axp->target_uid[axp->pid_count] = t_uid; |
2424 | axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); | 2539 | axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); |
2425 | security_task_getsecid(t, &axp->target_sid[axp->pid_count]); | 2540 | security_task_getsecid(t, &axp->target_sid[axp->pid_count]); |
2426 | memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); | 2541 | memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); |
@@ -2430,6 +2545,86 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2430 | } | 2545 | } |
2431 | 2546 | ||
2432 | /** | 2547 | /** |
2548 | * __audit_log_bprm_fcaps - store information about a loading bprm and relevant fcaps | ||
2549 | * @bprm: pointer to the bprm being processed | ||
2550 | * @new: the proposed new credentials | ||
2551 | * @old: the old credentials | ||
2552 | * | ||
2553 | * Simply check if the proc already has the caps given by the file and if not | ||
2554 | * store the priv escalation info for later auditing at the end of the syscall | ||
2555 | * | ||
2556 | * -Eric | ||
2557 | */ | ||
2558 | int __audit_log_bprm_fcaps(struct linux_binprm *bprm, | ||
2559 | const struct cred *new, const struct cred *old) | ||
2560 | { | ||
2561 | struct audit_aux_data_bprm_fcaps *ax; | ||
2562 | struct audit_context *context = current->audit_context; | ||
2563 | struct cpu_vfs_cap_data vcaps; | ||
2564 | struct dentry *dentry; | ||
2565 | |||
2566 | ax = kmalloc(sizeof(*ax), GFP_KERNEL); | ||
2567 | if (!ax) | ||
2568 | return -ENOMEM; | ||
2569 | |||
2570 | ax->d.type = AUDIT_BPRM_FCAPS; | ||
2571 | ax->d.next = context->aux; | ||
2572 | context->aux = (void *)ax; | ||
2573 | |||
2574 | dentry = dget(bprm->file->f_dentry); | ||
2575 | get_vfs_caps_from_disk(dentry, &vcaps); | ||
2576 | dput(dentry); | ||
2577 | |||
2578 | ax->fcap.permitted = vcaps.permitted; | ||
2579 | ax->fcap.inheritable = vcaps.inheritable; | ||
2580 | ax->fcap.fE = !!(vcaps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); | ||
2581 | ax->fcap_ver = (vcaps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT; | ||
2582 | |||
2583 | ax->old_pcap.permitted = old->cap_permitted; | ||
2584 | ax->old_pcap.inheritable = old->cap_inheritable; | ||
2585 | ax->old_pcap.effective = old->cap_effective; | ||
2586 | |||
2587 | ax->new_pcap.permitted = new->cap_permitted; | ||
2588 | ax->new_pcap.inheritable = new->cap_inheritable; | ||
2589 | ax->new_pcap.effective = new->cap_effective; | ||
2590 | return 0; | ||
2591 | } | ||
2592 | |||
2593 | /** | ||
2594 | * __audit_log_capset - store information about the arguments to the capset syscall | ||
2595 | * @pid: target pid of the capset call | ||
2596 | * @new: the new credentials | ||
2597 | * @old: the old (current) credentials | ||
2598 | * | ||
2599 | * Record the aguments userspace sent to sys_capset for later printing by the | ||
2600 | * audit system if applicable | ||
2601 | */ | ||
2602 | int __audit_log_capset(pid_t pid, | ||
2603 | const struct cred *new, const struct cred *old) | ||
2604 | { | ||
2605 | struct audit_aux_data_capset *ax; | ||
2606 | struct audit_context *context = current->audit_context; | ||
2607 | |||
2608 | if (likely(!audit_enabled || !context || context->dummy)) | ||
2609 | return 0; | ||
2610 | |||
2611 | ax = kmalloc(sizeof(*ax), GFP_KERNEL); | ||
2612 | if (!ax) | ||
2613 | return -ENOMEM; | ||
2614 | |||
2615 | ax->d.type = AUDIT_CAPSET; | ||
2616 | ax->d.next = context->aux; | ||
2617 | context->aux = (void *)ax; | ||
2618 | |||
2619 | ax->pid = pid; | ||
2620 | ax->cap.effective = new->cap_effective; | ||
2621 | ax->cap.inheritable = new->cap_effective; | ||
2622 | ax->cap.permitted = new->cap_permitted; | ||
2623 | |||
2624 | return 0; | ||
2625 | } | ||
2626 | |||
2627 | /** | ||
2433 | * audit_core_dumps - record information about processes that end abnormally | 2628 | * audit_core_dumps - record information about processes that end abnormally |
2434 | * @signr: signal value | 2629 | * @signr: signal value |
2435 | * | 2630 | * |
@@ -2440,7 +2635,8 @@ void audit_core_dumps(long signr) | |||
2440 | { | 2635 | { |
2441 | struct audit_buffer *ab; | 2636 | struct audit_buffer *ab; |
2442 | u32 sid; | 2637 | u32 sid; |
2443 | uid_t auid = audit_get_loginuid(current); | 2638 | uid_t auid = audit_get_loginuid(current), uid; |
2639 | gid_t gid; | ||
2444 | unsigned int sessionid = audit_get_sessionid(current); | 2640 | unsigned int sessionid = audit_get_sessionid(current); |
2445 | 2641 | ||
2446 | if (!audit_enabled) | 2642 | if (!audit_enabled) |
@@ -2450,8 +2646,9 @@ void audit_core_dumps(long signr) | |||
2450 | return; | 2646 | return; |
2451 | 2647 | ||
2452 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); | 2648 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); |
2649 | current_uid_gid(&uid, &gid); | ||
2453 | audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u", | 2650 | audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u", |
2454 | auid, current->uid, current->gid, sessionid); | 2651 | auid, uid, gid, sessionid); |
2455 | security_task_getsecid(current, &sid); | 2652 | security_task_getsecid(current, &sid); |
2456 | if (sid) { | 2653 | if (sid) { |
2457 | char *ctx = NULL; | 2654 | char *ctx = NULL; |