Commit b24a30a7305418ff138ff51776fc555ec57c011a
1 parent
7173c54e3a
Exists in
master
and in
20 other branches
audit: fix event coverage of AUDIT_ANOM_LINK
The userspace audit tools didn't like the existing formatting of the AUDIT_ANOM_LINK event. It needed to be expanded to emit an AUDIT_PATH event as well, so this implements the change. The bulk of the patch is moving code out of auditsc.c into audit.c and audit.h for general use. It expands audit_log_name to include an optional "struct path" argument for the simple case of just needing to report a pathname. This also makes audit_log_task_info available when syscall auditing is not enabled, since it is needed in either case for process details. Signed-off-by: Kees Cook <keescook@chromium.org> Reported-by: Steve Grubb <sgrubb@redhat.com>
Showing 4 changed files with 405 additions and 369 deletions Side-by-side Diff
include/linux/audit.h
... | ... | @@ -190,8 +190,6 @@ |
190 | 190 | return tsk->sessionid; |
191 | 191 | } |
192 | 192 | |
193 | -extern int audit_log_task_context(struct audit_buffer *ab); | |
194 | -extern void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk); | |
195 | 193 | extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp); |
196 | 194 | extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode); |
197 | 195 | extern int __audit_bprm(struct linux_binprm *bprm); |
... | ... | @@ -346,13 +344,6 @@ |
346 | 344 | { |
347 | 345 | return -1; |
348 | 346 | } |
349 | -static int void audit_log_task_context(struct audit_buffer *ab) | |
350 | -{ | |
351 | - return 0; | |
352 | -} | |
353 | -static inline void audit_log_task_info(struct audit_buffer *ab, | |
354 | - struct task_struct *tsk) | |
355 | -{ } | |
356 | 347 | static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) |
357 | 348 | { } |
358 | 349 | static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, |
... | ... | @@ -439,6 +430,10 @@ |
439 | 430 | { } |
440 | 431 | #endif |
441 | 432 | |
433 | +extern int audit_log_task_context(struct audit_buffer *ab); | |
434 | +extern void audit_log_task_info(struct audit_buffer *ab, | |
435 | + struct task_struct *tsk); | |
436 | + | |
442 | 437 | extern int audit_update_lsm_rules(void); |
443 | 438 | |
444 | 439 | /* Private API (for audit.c only) */ |
... | ... | @@ -484,6 +479,13 @@ |
484 | 479 | const struct path *link) |
485 | 480 | { } |
486 | 481 | static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) |
482 | +{ } | |
483 | +static inline int audit_log_task_context(struct audit_buffer *ab) | |
484 | +{ | |
485 | + return 0; | |
486 | +} | |
487 | +static inline void audit_log_task_info(struct audit_buffer *ab, | |
488 | + struct task_struct *tsk) | |
487 | 489 | { } |
488 | 490 | #define audit_enabled 0 |
489 | 491 | #endif /* CONFIG_AUDIT */ |
kernel/audit.c
... | ... | @@ -50,6 +50,7 @@ |
50 | 50 | #include <linux/err.h> |
51 | 51 | #include <linux/kthread.h> |
52 | 52 | #include <linux/kernel.h> |
53 | +#include <linux/syscalls.h> | |
53 | 54 | |
54 | 55 | #include <linux/audit.h> |
55 | 56 | |
56 | 57 | |
... | ... | @@ -1393,7 +1394,225 @@ |
1393 | 1394 | audit_log_format(ab, "(null)"); |
1394 | 1395 | } |
1395 | 1396 | |
1397 | +void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap) | |
1398 | +{ | |
1399 | + int i; | |
1400 | + | |
1401 | + audit_log_format(ab, " %s=", prefix); | |
1402 | + CAP_FOR_EACH_U32(i) { | |
1403 | + audit_log_format(ab, "%08x", | |
1404 | + cap->cap[(_KERNEL_CAPABILITY_U32S-1) - i]); | |
1405 | + } | |
1406 | +} | |
1407 | + | |
1408 | +void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) | |
1409 | +{ | |
1410 | + kernel_cap_t *perm = &name->fcap.permitted; | |
1411 | + kernel_cap_t *inh = &name->fcap.inheritable; | |
1412 | + int log = 0; | |
1413 | + | |
1414 | + if (!cap_isclear(*perm)) { | |
1415 | + audit_log_cap(ab, "cap_fp", perm); | |
1416 | + log = 1; | |
1417 | + } | |
1418 | + if (!cap_isclear(*inh)) { | |
1419 | + audit_log_cap(ab, "cap_fi", inh); | |
1420 | + log = 1; | |
1421 | + } | |
1422 | + | |
1423 | + if (log) | |
1424 | + audit_log_format(ab, " cap_fe=%d cap_fver=%x", | |
1425 | + name->fcap.fE, name->fcap_ver); | |
1426 | +} | |
1427 | + | |
1428 | +static inline int audit_copy_fcaps(struct audit_names *name, | |
1429 | + const struct dentry *dentry) | |
1430 | +{ | |
1431 | + struct cpu_vfs_cap_data caps; | |
1432 | + int rc; | |
1433 | + | |
1434 | + if (!dentry) | |
1435 | + return 0; | |
1436 | + | |
1437 | + rc = get_vfs_caps_from_disk(dentry, &caps); | |
1438 | + if (rc) | |
1439 | + return rc; | |
1440 | + | |
1441 | + name->fcap.permitted = caps.permitted; | |
1442 | + name->fcap.inheritable = caps.inheritable; | |
1443 | + name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); | |
1444 | + name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >> | |
1445 | + VFS_CAP_REVISION_SHIFT; | |
1446 | + | |
1447 | + return 0; | |
1448 | +} | |
1449 | + | |
1450 | +/* Copy inode data into an audit_names. */ | |
1451 | +void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, | |
1452 | + const struct inode *inode) | |
1453 | +{ | |
1454 | + name->ino = inode->i_ino; | |
1455 | + name->dev = inode->i_sb->s_dev; | |
1456 | + name->mode = inode->i_mode; | |
1457 | + name->uid = inode->i_uid; | |
1458 | + name->gid = inode->i_gid; | |
1459 | + name->rdev = inode->i_rdev; | |
1460 | + security_inode_getsecid(inode, &name->osid); | |
1461 | + audit_copy_fcaps(name, dentry); | |
1462 | +} | |
1463 | + | |
1396 | 1464 | /** |
1465 | + * audit_log_name - produce AUDIT_PATH record from struct audit_names | |
1466 | + * @context: audit_context for the task | |
1467 | + * @n: audit_names structure with reportable details | |
1468 | + * @path: optional path to report instead of audit_names->name | |
1469 | + * @record_num: record number to report when handling a list of names | |
1470 | + * @call_panic: optional pointer to int that will be updated if secid fails | |
1471 | + */ | |
1472 | +void audit_log_name(struct audit_context *context, struct audit_names *n, | |
1473 | + struct path *path, int record_num, int *call_panic) | |
1474 | +{ | |
1475 | + struct audit_buffer *ab; | |
1476 | + ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); | |
1477 | + if (!ab) | |
1478 | + return; | |
1479 | + | |
1480 | + audit_log_format(ab, "item=%d", record_num); | |
1481 | + | |
1482 | + if (path) | |
1483 | + audit_log_d_path(ab, " name=", path); | |
1484 | + else if (n->name) { | |
1485 | + switch (n->name_len) { | |
1486 | + case AUDIT_NAME_FULL: | |
1487 | + /* log the full path */ | |
1488 | + audit_log_format(ab, " name="); | |
1489 | + audit_log_untrustedstring(ab, n->name->name); | |
1490 | + break; | |
1491 | + case 0: | |
1492 | + /* name was specified as a relative path and the | |
1493 | + * directory component is the cwd */ | |
1494 | + audit_log_d_path(ab, " name=", &context->pwd); | |
1495 | + break; | |
1496 | + default: | |
1497 | + /* log the name's directory component */ | |
1498 | + audit_log_format(ab, " name="); | |
1499 | + audit_log_n_untrustedstring(ab, n->name->name, | |
1500 | + n->name_len); | |
1501 | + } | |
1502 | + } else | |
1503 | + audit_log_format(ab, " name=(null)"); | |
1504 | + | |
1505 | + if (n->ino != (unsigned long)-1) { | |
1506 | + audit_log_format(ab, " inode=%lu" | |
1507 | + " dev=%02x:%02x mode=%#ho" | |
1508 | + " ouid=%u ogid=%u rdev=%02x:%02x", | |
1509 | + n->ino, | |
1510 | + MAJOR(n->dev), | |
1511 | + MINOR(n->dev), | |
1512 | + n->mode, | |
1513 | + from_kuid(&init_user_ns, n->uid), | |
1514 | + from_kgid(&init_user_ns, n->gid), | |
1515 | + MAJOR(n->rdev), | |
1516 | + MINOR(n->rdev)); | |
1517 | + } | |
1518 | + if (n->osid != 0) { | |
1519 | + char *ctx = NULL; | |
1520 | + u32 len; | |
1521 | + if (security_secid_to_secctx( | |
1522 | + n->osid, &ctx, &len)) { | |
1523 | + audit_log_format(ab, " osid=%u", n->osid); | |
1524 | + if (call_panic) | |
1525 | + *call_panic = 2; | |
1526 | + } else { | |
1527 | + audit_log_format(ab, " obj=%s", ctx); | |
1528 | + security_release_secctx(ctx, len); | |
1529 | + } | |
1530 | + } | |
1531 | + | |
1532 | + audit_log_fcaps(ab, n); | |
1533 | + audit_log_end(ab); | |
1534 | +} | |
1535 | + | |
1536 | +int audit_log_task_context(struct audit_buffer *ab) | |
1537 | +{ | |
1538 | + char *ctx = NULL; | |
1539 | + unsigned len; | |
1540 | + int error; | |
1541 | + u32 sid; | |
1542 | + | |
1543 | + security_task_getsecid(current, &sid); | |
1544 | + if (!sid) | |
1545 | + return 0; | |
1546 | + | |
1547 | + error = security_secid_to_secctx(sid, &ctx, &len); | |
1548 | + if (error) { | |
1549 | + if (error != -EINVAL) | |
1550 | + goto error_path; | |
1551 | + return 0; | |
1552 | + } | |
1553 | + | |
1554 | + audit_log_format(ab, " subj=%s", ctx); | |
1555 | + security_release_secctx(ctx, len); | |
1556 | + return 0; | |
1557 | + | |
1558 | +error_path: | |
1559 | + audit_panic("error in audit_log_task_context"); | |
1560 | + return error; | |
1561 | +} | |
1562 | +EXPORT_SYMBOL(audit_log_task_context); | |
1563 | + | |
1564 | +void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) | |
1565 | +{ | |
1566 | + const struct cred *cred; | |
1567 | + char name[sizeof(tsk->comm)]; | |
1568 | + struct mm_struct *mm = tsk->mm; | |
1569 | + char *tty; | |
1570 | + | |
1571 | + if (!ab) | |
1572 | + return; | |
1573 | + | |
1574 | + /* tsk == current */ | |
1575 | + cred = current_cred(); | |
1576 | + | |
1577 | + spin_lock_irq(&tsk->sighand->siglock); | |
1578 | + if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) | |
1579 | + tty = tsk->signal->tty->name; | |
1580 | + else | |
1581 | + tty = "(none)"; | |
1582 | + spin_unlock_irq(&tsk->sighand->siglock); | |
1583 | + | |
1584 | + audit_log_format(ab, | |
1585 | + " ppid=%ld pid=%d auid=%u uid=%u gid=%u" | |
1586 | + " euid=%u suid=%u fsuid=%u" | |
1587 | + " egid=%u sgid=%u fsgid=%u ses=%u tty=%s", | |
1588 | + sys_getppid(), | |
1589 | + tsk->pid, | |
1590 | + from_kuid(&init_user_ns, audit_get_loginuid(tsk)), | |
1591 | + from_kuid(&init_user_ns, cred->uid), | |
1592 | + from_kgid(&init_user_ns, cred->gid), | |
1593 | + from_kuid(&init_user_ns, cred->euid), | |
1594 | + from_kuid(&init_user_ns, cred->suid), | |
1595 | + from_kuid(&init_user_ns, cred->fsuid), | |
1596 | + from_kgid(&init_user_ns, cred->egid), | |
1597 | + from_kgid(&init_user_ns, cred->sgid), | |
1598 | + from_kgid(&init_user_ns, cred->fsgid), | |
1599 | + audit_get_sessionid(tsk), tty); | |
1600 | + | |
1601 | + get_task_comm(name, tsk); | |
1602 | + audit_log_format(ab, " comm="); | |
1603 | + audit_log_untrustedstring(ab, name); | |
1604 | + | |
1605 | + if (mm) { | |
1606 | + down_read(&mm->mmap_sem); | |
1607 | + if (mm->exe_file) | |
1608 | + audit_log_d_path(ab, " exe=", &mm->exe_file->f_path); | |
1609 | + up_read(&mm->mmap_sem); | |
1610 | + } | |
1611 | + audit_log_task_context(ab); | |
1612 | +} | |
1613 | +EXPORT_SYMBOL(audit_log_task_info); | |
1614 | + | |
1615 | +/** | |
1397 | 1616 | * audit_log_link_denied - report a link restriction denial |
1398 | 1617 | * @operation: specific link opreation |
1399 | 1618 | * @link: the path that triggered the restriction |
1400 | 1619 | |
1401 | 1620 | |
1402 | 1621 | |
... | ... | @@ -1401,19 +1620,28 @@ |
1401 | 1620 | void audit_log_link_denied(const char *operation, struct path *link) |
1402 | 1621 | { |
1403 | 1622 | struct audit_buffer *ab; |
1623 | + struct audit_names *name; | |
1404 | 1624 | |
1625 | + name = kzalloc(sizeof(*name), GFP_NOFS); | |
1626 | + if (!name) | |
1627 | + return; | |
1628 | + | |
1629 | + /* Generate AUDIT_ANOM_LINK with subject, operation, outcome. */ | |
1405 | 1630 | ab = audit_log_start(current->audit_context, GFP_KERNEL, |
1406 | 1631 | AUDIT_ANOM_LINK); |
1407 | 1632 | if (!ab) |
1408 | - return; | |
1409 | - audit_log_format(ab, "op=%s action=denied", operation); | |
1410 | - audit_log_format(ab, " pid=%d comm=", current->pid); | |
1411 | - audit_log_untrustedstring(ab, current->comm); | |
1412 | - audit_log_d_path(ab, " path=", link); | |
1413 | - audit_log_format(ab, " dev="); | |
1414 | - audit_log_untrustedstring(ab, link->dentry->d_inode->i_sb->s_id); | |
1415 | - audit_log_format(ab, " ino=%lu", link->dentry->d_inode->i_ino); | |
1633 | + goto out; | |
1634 | + audit_log_format(ab, "op=%s", operation); | |
1635 | + audit_log_task_info(ab, current); | |
1636 | + audit_log_format(ab, " res=0"); | |
1416 | 1637 | audit_log_end(ab); |
1638 | + | |
1639 | + /* Generate AUDIT_PATH record with object. */ | |
1640 | + name->type = AUDIT_TYPE_NORMAL; | |
1641 | + audit_copy_inode(name, link->dentry, link->dentry->d_inode); | |
1642 | + audit_log_name(current->audit_context, name, link, 0, NULL); | |
1643 | +out: | |
1644 | + kfree(name); | |
1417 | 1645 | } |
1418 | 1646 | |
1419 | 1647 | /** |
kernel/audit.h
... | ... | @@ -22,6 +22,7 @@ |
22 | 22 | #include <linux/fs.h> |
23 | 23 | #include <linux/audit.h> |
24 | 24 | #include <linux/skbuff.h> |
25 | +#include <uapi/linux/mqueue.h> | |
25 | 26 | |
26 | 27 | /* 0 = no checking |
27 | 28 | 1 = put_count checking |
... | ... | @@ -29,6 +30,11 @@ |
29 | 30 | */ |
30 | 31 | #define AUDIT_DEBUG 0 |
31 | 32 | |
33 | +/* AUDIT_NAMES is the number of slots we reserve in the audit_context | |
34 | + * for saving names from getname(). If we get more names we will allocate | |
35 | + * a name dynamically and also add those to the list anchored by names_list. */ | |
36 | +#define AUDIT_NAMES 5 | |
37 | + | |
32 | 38 | /* At task start time, the audit_state is set in the audit_context using |
33 | 39 | a per-task filter. At syscall entry, the audit_state is augmented by |
34 | 40 | the syscall filter. */ |
35 | 41 | |
36 | 42 | |
... | ... | @@ -59,8 +65,159 @@ |
59 | 65 | struct audit_krule rule; |
60 | 66 | }; |
61 | 67 | |
68 | +struct audit_cap_data { | |
69 | + kernel_cap_t permitted; | |
70 | + kernel_cap_t inheritable; | |
71 | + union { | |
72 | + unsigned int fE; /* effective bit of file cap */ | |
73 | + kernel_cap_t effective; /* effective set of process */ | |
74 | + }; | |
75 | +}; | |
76 | + | |
77 | +/* When fs/namei.c:getname() is called, we store the pointer in name and | |
78 | + * we don't let putname() free it (instead we free all of the saved | |
79 | + * pointers at syscall exit time). | |
80 | + * | |
81 | + * Further, in fs/namei.c:path_lookup() we store the inode and device. | |
82 | + */ | |
83 | +struct audit_names { | |
84 | + struct list_head list; /* audit_context->names_list */ | |
85 | + | |
86 | + struct filename *name; | |
87 | + int name_len; /* number of chars to log */ | |
88 | + bool name_put; /* call __putname()? */ | |
89 | + | |
90 | + unsigned long ino; | |
91 | + dev_t dev; | |
92 | + umode_t mode; | |
93 | + kuid_t uid; | |
94 | + kgid_t gid; | |
95 | + dev_t rdev; | |
96 | + u32 osid; | |
97 | + struct audit_cap_data fcap; | |
98 | + unsigned int fcap_ver; | |
99 | + unsigned char type; /* record type */ | |
100 | + /* | |
101 | + * This was an allocated audit_names and not from the array of | |
102 | + * names allocated in the task audit context. Thus this name | |
103 | + * should be freed on syscall exit. | |
104 | + */ | |
105 | + bool should_free; | |
106 | +}; | |
107 | + | |
108 | +/* The per-task audit context. */ | |
109 | +struct audit_context { | |
110 | + int dummy; /* must be the first element */ | |
111 | + int in_syscall; /* 1 if task is in a syscall */ | |
112 | + enum audit_state state, current_state; | |
113 | + unsigned int serial; /* serial number for record */ | |
114 | + int major; /* syscall number */ | |
115 | + struct timespec ctime; /* time of syscall entry */ | |
116 | + unsigned long argv[4]; /* syscall arguments */ | |
117 | + long return_code;/* syscall return code */ | |
118 | + u64 prio; | |
119 | + int return_valid; /* return code is valid */ | |
120 | + /* | |
121 | + * The names_list is the list of all audit_names collected during this | |
122 | + * syscall. The first AUDIT_NAMES entries in the names_list will | |
123 | + * actually be from the preallocated_names array for performance | |
124 | + * reasons. Except during allocation they should never be referenced | |
125 | + * through the preallocated_names array and should only be found/used | |
126 | + * by running the names_list. | |
127 | + */ | |
128 | + struct audit_names preallocated_names[AUDIT_NAMES]; | |
129 | + int name_count; /* total records in names_list */ | |
130 | + struct list_head names_list; /* struct audit_names->list anchor */ | |
131 | + char *filterkey; /* key for rule that triggered record */ | |
132 | + struct path pwd; | |
133 | + struct audit_aux_data *aux; | |
134 | + struct audit_aux_data *aux_pids; | |
135 | + struct sockaddr_storage *sockaddr; | |
136 | + size_t sockaddr_len; | |
137 | + /* Save things to print about task_struct */ | |
138 | + pid_t pid, ppid; | |
139 | + kuid_t uid, euid, suid, fsuid; | |
140 | + kgid_t gid, egid, sgid, fsgid; | |
141 | + unsigned long personality; | |
142 | + int arch; | |
143 | + | |
144 | + pid_t target_pid; | |
145 | + kuid_t target_auid; | |
146 | + kuid_t target_uid; | |
147 | + unsigned int target_sessionid; | |
148 | + u32 target_sid; | |
149 | + char target_comm[TASK_COMM_LEN]; | |
150 | + | |
151 | + struct audit_tree_refs *trees, *first_trees; | |
152 | + struct list_head killed_trees; | |
153 | + int tree_count; | |
154 | + | |
155 | + int type; | |
156 | + union { | |
157 | + struct { | |
158 | + int nargs; | |
159 | + long args[6]; | |
160 | + } socketcall; | |
161 | + struct { | |
162 | + kuid_t uid; | |
163 | + kgid_t gid; | |
164 | + umode_t mode; | |
165 | + u32 osid; | |
166 | + int has_perm; | |
167 | + uid_t perm_uid; | |
168 | + gid_t perm_gid; | |
169 | + umode_t perm_mode; | |
170 | + unsigned long qbytes; | |
171 | + } ipc; | |
172 | + struct { | |
173 | + mqd_t mqdes; | |
174 | + struct mq_attr mqstat; | |
175 | + } mq_getsetattr; | |
176 | + struct { | |
177 | + mqd_t mqdes; | |
178 | + int sigev_signo; | |
179 | + } mq_notify; | |
180 | + struct { | |
181 | + mqd_t mqdes; | |
182 | + size_t msg_len; | |
183 | + unsigned int msg_prio; | |
184 | + struct timespec abs_timeout; | |
185 | + } mq_sendrecv; | |
186 | + struct { | |
187 | + int oflag; | |
188 | + umode_t mode; | |
189 | + struct mq_attr attr; | |
190 | + } mq_open; | |
191 | + struct { | |
192 | + pid_t pid; | |
193 | + struct audit_cap_data cap; | |
194 | + } capset; | |
195 | + struct { | |
196 | + int fd; | |
197 | + int flags; | |
198 | + } mmap; | |
199 | + }; | |
200 | + int fds[2]; | |
201 | + | |
202 | +#if AUDIT_DEBUG | |
203 | + int put_count; | |
204 | + int ino_count; | |
205 | +#endif | |
206 | +}; | |
207 | + | |
62 | 208 | #ifdef CONFIG_AUDIT |
209 | +extern int audit_enabled; | |
63 | 210 | extern int audit_ever_enabled; |
211 | + | |
212 | +extern void audit_copy_inode(struct audit_names *name, | |
213 | + const struct dentry *dentry, | |
214 | + const struct inode *inode); | |
215 | +extern void audit_log_cap(struct audit_buffer *ab, char *prefix, | |
216 | + kernel_cap_t *cap); | |
217 | +extern void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name); | |
218 | +extern void audit_log_name(struct audit_context *context, | |
219 | + struct audit_names *n, struct path *path, | |
220 | + int record_num, int *call_panic); | |
64 | 221 | #endif |
65 | 222 | |
66 | 223 | extern int audit_pid; |
kernel/auditsc.c
... | ... | @@ -76,11 +76,6 @@ |
76 | 76 | #define AUDITSC_SUCCESS 1 |
77 | 77 | #define AUDITSC_FAILURE 2 |
78 | 78 | |
79 | -/* AUDIT_NAMES is the number of slots we reserve in the audit_context | |
80 | - * for saving names from getname(). If we get more names we will allocate | |
81 | - * a name dynamically and also add those to the list anchored by names_list. */ | |
82 | -#define AUDIT_NAMES 5 | |
83 | - | |
84 | 79 | /* no execve audit message should be longer than this (userspace limits) */ |
85 | 80 | #define MAX_EXECVE_AUDIT_LEN 7500 |
86 | 81 | |
... | ... | @@ -90,44 +85,6 @@ |
90 | 85 | /* determines whether we collect data for signals sent */ |
91 | 86 | int audit_signals; |
92 | 87 | |
93 | -struct audit_cap_data { | |
94 | - kernel_cap_t permitted; | |
95 | - kernel_cap_t inheritable; | |
96 | - union { | |
97 | - unsigned int fE; /* effective bit of a file capability */ | |
98 | - kernel_cap_t effective; /* effective set of a process */ | |
99 | - }; | |
100 | -}; | |
101 | - | |
102 | -/* When fs/namei.c:getname() is called, we store the pointer in name and | |
103 | - * we don't let putname() free it (instead we free all of the saved | |
104 | - * pointers at syscall exit time). | |
105 | - * | |
106 | - * Further, in fs/namei.c:path_lookup() we store the inode and device. | |
107 | - */ | |
108 | -struct audit_names { | |
109 | - struct list_head list; /* audit_context->names_list */ | |
110 | - struct filename *name; | |
111 | - unsigned long ino; | |
112 | - dev_t dev; | |
113 | - umode_t mode; | |
114 | - kuid_t uid; | |
115 | - kgid_t gid; | |
116 | - dev_t rdev; | |
117 | - u32 osid; | |
118 | - struct audit_cap_data fcap; | |
119 | - unsigned int fcap_ver; | |
120 | - int name_len; /* number of name's characters to log */ | |
121 | - unsigned char type; /* record type */ | |
122 | - bool name_put; /* call __putname() for this name */ | |
123 | - /* | |
124 | - * This was an allocated audit_names and not from the array of | |
125 | - * names allocated in the task audit context. Thus this name | |
126 | - * should be freed on syscall exit | |
127 | - */ | |
128 | - bool should_free; | |
129 | -}; | |
130 | - | |
131 | 88 | struct audit_aux_data { |
132 | 89 | struct audit_aux_data *next; |
133 | 90 | int type; |
... | ... | @@ -175,106 +132,6 @@ |
175 | 132 | struct audit_chunk *c[31]; |
176 | 133 | }; |
177 | 134 | |
178 | -/* The per-task audit context. */ | |
179 | -struct audit_context { | |
180 | - int dummy; /* must be the first element */ | |
181 | - int in_syscall; /* 1 if task is in a syscall */ | |
182 | - enum audit_state state, current_state; | |
183 | - unsigned int serial; /* serial number for record */ | |
184 | - int major; /* syscall number */ | |
185 | - struct timespec ctime; /* time of syscall entry */ | |
186 | - unsigned long argv[4]; /* syscall arguments */ | |
187 | - long return_code;/* syscall return code */ | |
188 | - u64 prio; | |
189 | - int return_valid; /* return code is valid */ | |
190 | - /* | |
191 | - * The names_list is the list of all audit_names collected during this | |
192 | - * syscall. The first AUDIT_NAMES entries in the names_list will | |
193 | - * actually be from the preallocated_names array for performance | |
194 | - * reasons. Except during allocation they should never be referenced | |
195 | - * through the preallocated_names array and should only be found/used | |
196 | - * by running the names_list. | |
197 | - */ | |
198 | - struct audit_names preallocated_names[AUDIT_NAMES]; | |
199 | - int name_count; /* total records in names_list */ | |
200 | - struct list_head names_list; /* anchor for struct audit_names->list */ | |
201 | - char * filterkey; /* key for rule that triggered record */ | |
202 | - struct path pwd; | |
203 | - struct audit_aux_data *aux; | |
204 | - struct audit_aux_data *aux_pids; | |
205 | - struct sockaddr_storage *sockaddr; | |
206 | - size_t sockaddr_len; | |
207 | - /* Save things to print about task_struct */ | |
208 | - pid_t pid, ppid; | |
209 | - kuid_t uid, euid, suid, fsuid; | |
210 | - kgid_t gid, egid, sgid, fsgid; | |
211 | - unsigned long personality; | |
212 | - int arch; | |
213 | - | |
214 | - pid_t target_pid; | |
215 | - kuid_t target_auid; | |
216 | - kuid_t target_uid; | |
217 | - unsigned int target_sessionid; | |
218 | - u32 target_sid; | |
219 | - char target_comm[TASK_COMM_LEN]; | |
220 | - | |
221 | - struct audit_tree_refs *trees, *first_trees; | |
222 | - struct list_head killed_trees; | |
223 | - int tree_count; | |
224 | - | |
225 | - int type; | |
226 | - union { | |
227 | - struct { | |
228 | - int nargs; | |
229 | - long args[AUDITSC_ARGS]; | |
230 | - } socketcall; | |
231 | - struct { | |
232 | - kuid_t uid; | |
233 | - kgid_t gid; | |
234 | - umode_t mode; | |
235 | - u32 osid; | |
236 | - int has_perm; | |
237 | - uid_t perm_uid; | |
238 | - gid_t perm_gid; | |
239 | - umode_t perm_mode; | |
240 | - unsigned long qbytes; | |
241 | - } ipc; | |
242 | - struct { | |
243 | - mqd_t mqdes; | |
244 | - struct mq_attr mqstat; | |
245 | - } mq_getsetattr; | |
246 | - struct { | |
247 | - mqd_t mqdes; | |
248 | - int sigev_signo; | |
249 | - } mq_notify; | |
250 | - struct { | |
251 | - mqd_t mqdes; | |
252 | - size_t msg_len; | |
253 | - unsigned int msg_prio; | |
254 | - struct timespec abs_timeout; | |
255 | - } mq_sendrecv; | |
256 | - struct { | |
257 | - int oflag; | |
258 | - umode_t mode; | |
259 | - struct mq_attr attr; | |
260 | - } mq_open; | |
261 | - struct { | |
262 | - pid_t pid; | |
263 | - struct audit_cap_data cap; | |
264 | - } capset; | |
265 | - struct { | |
266 | - int fd; | |
267 | - int flags; | |
268 | - } mmap; | |
269 | - }; | |
270 | - int fds[2]; | |
271 | - | |
272 | -#if AUDIT_DEBUG | |
273 | - int put_count; | |
274 | - int ino_count; | |
275 | -#endif | |
276 | -}; | |
277 | - | |
278 | 135 | static inline int open_arg(int flags, int mask) |
279 | 136 | { |
280 | 137 | int n = ACC_MODE(flags); |
... | ... | @@ -1109,88 +966,6 @@ |
1109 | 966 | kfree(context); |
1110 | 967 | } |
1111 | 968 | |
1112 | -int audit_log_task_context(struct audit_buffer *ab) | |
1113 | -{ | |
1114 | - char *ctx = NULL; | |
1115 | - unsigned len; | |
1116 | - int error; | |
1117 | - u32 sid; | |
1118 | - | |
1119 | - security_task_getsecid(current, &sid); | |
1120 | - if (!sid) | |
1121 | - return 0; | |
1122 | - | |
1123 | - error = security_secid_to_secctx(sid, &ctx, &len); | |
1124 | - if (error) { | |
1125 | - if (error != -EINVAL) | |
1126 | - goto error_path; | |
1127 | - return 0; | |
1128 | - } | |
1129 | - | |
1130 | - audit_log_format(ab, " subj=%s", ctx); | |
1131 | - security_release_secctx(ctx, len); | |
1132 | - return 0; | |
1133 | - | |
1134 | -error_path: | |
1135 | - audit_panic("error in audit_log_task_context"); | |
1136 | - return error; | |
1137 | -} | |
1138 | - | |
1139 | -EXPORT_SYMBOL(audit_log_task_context); | |
1140 | - | |
1141 | -void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) | |
1142 | -{ | |
1143 | - const struct cred *cred; | |
1144 | - char name[sizeof(tsk->comm)]; | |
1145 | - struct mm_struct *mm = tsk->mm; | |
1146 | - char *tty; | |
1147 | - | |
1148 | - if (!ab) | |
1149 | - return; | |
1150 | - | |
1151 | - /* tsk == current */ | |
1152 | - cred = current_cred(); | |
1153 | - | |
1154 | - spin_lock_irq(&tsk->sighand->siglock); | |
1155 | - if (tsk->signal && tsk->signal->tty) | |
1156 | - tty = tsk->signal->tty->name; | |
1157 | - else | |
1158 | - tty = "(none)"; | |
1159 | - spin_unlock_irq(&tsk->sighand->siglock); | |
1160 | - | |
1161 | - | |
1162 | - audit_log_format(ab, | |
1163 | - " ppid=%ld pid=%d auid=%u uid=%u gid=%u" | |
1164 | - " euid=%u suid=%u fsuid=%u" | |
1165 | - " egid=%u sgid=%u fsgid=%u ses=%u tty=%s", | |
1166 | - sys_getppid(), | |
1167 | - tsk->pid, | |
1168 | - from_kuid(&init_user_ns, tsk->loginuid), | |
1169 | - from_kuid(&init_user_ns, cred->uid), | |
1170 | - from_kgid(&init_user_ns, cred->gid), | |
1171 | - from_kuid(&init_user_ns, cred->euid), | |
1172 | - from_kuid(&init_user_ns, cred->suid), | |
1173 | - from_kuid(&init_user_ns, cred->fsuid), | |
1174 | - from_kgid(&init_user_ns, cred->egid), | |
1175 | - from_kgid(&init_user_ns, cred->sgid), | |
1176 | - from_kgid(&init_user_ns, cred->fsgid), | |
1177 | - tsk->sessionid, tty); | |
1178 | - | |
1179 | - get_task_comm(name, tsk); | |
1180 | - audit_log_format(ab, " comm="); | |
1181 | - audit_log_untrustedstring(ab, name); | |
1182 | - | |
1183 | - if (mm) { | |
1184 | - down_read(&mm->mmap_sem); | |
1185 | - if (mm->exe_file) | |
1186 | - audit_log_d_path(ab, " exe=", &mm->exe_file->f_path); | |
1187 | - up_read(&mm->mmap_sem); | |
1188 | - } | |
1189 | - audit_log_task_context(ab); | |
1190 | -} | |
1191 | - | |
1192 | -EXPORT_SYMBOL(audit_log_task_info); | |
1193 | - | |
1194 | 969 | static int audit_log_pid_context(struct audit_context *context, pid_t pid, |
1195 | 970 | kuid_t auid, kuid_t uid, unsigned int sessionid, |
1196 | 971 | u32 sid, char *comm) |
... | ... | @@ -1408,35 +1183,6 @@ |
1408 | 1183 | kfree(buf); |
1409 | 1184 | } |
1410 | 1185 | |
1411 | -static void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap) | |
1412 | -{ | |
1413 | - int i; | |
1414 | - | |
1415 | - audit_log_format(ab, " %s=", prefix); | |
1416 | - CAP_FOR_EACH_U32(i) { | |
1417 | - audit_log_format(ab, "%08x", cap->cap[(_KERNEL_CAPABILITY_U32S-1) - i]); | |
1418 | - } | |
1419 | -} | |
1420 | - | |
1421 | -static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) | |
1422 | -{ | |
1423 | - kernel_cap_t *perm = &name->fcap.permitted; | |
1424 | - kernel_cap_t *inh = &name->fcap.inheritable; | |
1425 | - int log = 0; | |
1426 | - | |
1427 | - if (!cap_isclear(*perm)) { | |
1428 | - audit_log_cap(ab, "cap_fp", perm); | |
1429 | - log = 1; | |
1430 | - } | |
1431 | - if (!cap_isclear(*inh)) { | |
1432 | - audit_log_cap(ab, "cap_fi", inh); | |
1433 | - log = 1; | |
1434 | - } | |
1435 | - | |
1436 | - if (log) | |
1437 | - audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver); | |
1438 | -} | |
1439 | - | |
1440 | 1186 | static void show_special(struct audit_context *context, int *call_panic) |
1441 | 1187 | { |
1442 | 1188 | struct audit_buffer *ab; |
... | ... | @@ -1534,68 +1280,6 @@ |
1534 | 1280 | audit_log_end(ab); |
1535 | 1281 | } |
1536 | 1282 | |
1537 | -static void audit_log_name(struct audit_context *context, struct audit_names *n, | |
1538 | - int record_num, int *call_panic) | |
1539 | -{ | |
1540 | - struct audit_buffer *ab; | |
1541 | - ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); | |
1542 | - if (!ab) | |
1543 | - return; /* audit_panic has been called */ | |
1544 | - | |
1545 | - audit_log_format(ab, "item=%d", record_num); | |
1546 | - | |
1547 | - if (n->name) { | |
1548 | - switch (n->name_len) { | |
1549 | - case AUDIT_NAME_FULL: | |
1550 | - /* log the full path */ | |
1551 | - audit_log_format(ab, " name="); | |
1552 | - audit_log_untrustedstring(ab, n->name->name); | |
1553 | - break; | |
1554 | - case 0: | |
1555 | - /* name was specified as a relative path and the | |
1556 | - * directory component is the cwd */ | |
1557 | - audit_log_d_path(ab, " name=", &context->pwd); | |
1558 | - break; | |
1559 | - default: | |
1560 | - /* log the name's directory component */ | |
1561 | - audit_log_format(ab, " name="); | |
1562 | - audit_log_n_untrustedstring(ab, n->name->name, | |
1563 | - n->name_len); | |
1564 | - } | |
1565 | - } else | |
1566 | - audit_log_format(ab, " name=(null)"); | |
1567 | - | |
1568 | - if (n->ino != (unsigned long)-1) { | |
1569 | - audit_log_format(ab, " inode=%lu" | |
1570 | - " dev=%02x:%02x mode=%#ho" | |
1571 | - " ouid=%u ogid=%u rdev=%02x:%02x", | |
1572 | - n->ino, | |
1573 | - MAJOR(n->dev), | |
1574 | - MINOR(n->dev), | |
1575 | - n->mode, | |
1576 | - from_kuid(&init_user_ns, n->uid), | |
1577 | - from_kgid(&init_user_ns, n->gid), | |
1578 | - MAJOR(n->rdev), | |
1579 | - MINOR(n->rdev)); | |
1580 | - } | |
1581 | - if (n->osid != 0) { | |
1582 | - char *ctx = NULL; | |
1583 | - u32 len; | |
1584 | - if (security_secid_to_secctx( | |
1585 | - n->osid, &ctx, &len)) { | |
1586 | - audit_log_format(ab, " osid=%u", n->osid); | |
1587 | - *call_panic = 2; | |
1588 | - } else { | |
1589 | - audit_log_format(ab, " obj=%s", ctx); | |
1590 | - security_release_secctx(ctx, len); | |
1591 | - } | |
1592 | - } | |
1593 | - | |
1594 | - audit_log_fcaps(ab, n); | |
1595 | - | |
1596 | - audit_log_end(ab); | |
1597 | -} | |
1598 | - | |
1599 | 1283 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) |
1600 | 1284 | { |
1601 | 1285 | int i, call_panic = 0; |
... | ... | @@ -1713,7 +1397,7 @@ |
1713 | 1397 | |
1714 | 1398 | i = 0; |
1715 | 1399 | list_for_each_entry(n, &context->names_list, list) |
1716 | - audit_log_name(context, n, i++, &call_panic); | |
1400 | + audit_log_name(context, n, NULL, i++, &call_panic); | |
1717 | 1401 | |
1718 | 1402 | /* Send end of event record to help user space know we are finished */ |
1719 | 1403 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); |
... | ... | @@ -2076,41 +1760,6 @@ |
2076 | 1760 | } |
2077 | 1761 | } |
2078 | 1762 | #endif |
2079 | -} | |
2080 | - | |
2081 | -static inline int audit_copy_fcaps(struct audit_names *name, const struct dentry *dentry) | |
2082 | -{ | |
2083 | - struct cpu_vfs_cap_data caps; | |
2084 | - int rc; | |
2085 | - | |
2086 | - if (!dentry) | |
2087 | - return 0; | |
2088 | - | |
2089 | - rc = get_vfs_caps_from_disk(dentry, &caps); | |
2090 | - if (rc) | |
2091 | - return rc; | |
2092 | - | |
2093 | - name->fcap.permitted = caps.permitted; | |
2094 | - name->fcap.inheritable = caps.inheritable; | |
2095 | - name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); | |
2096 | - name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT; | |
2097 | - | |
2098 | - return 0; | |
2099 | -} | |
2100 | - | |
2101 | - | |
2102 | -/* Copy inode data into an audit_names. */ | |
2103 | -static void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, | |
2104 | - const struct inode *inode) | |
2105 | -{ | |
2106 | - name->ino = inode->i_ino; | |
2107 | - name->dev = inode->i_sb->s_dev; | |
2108 | - name->mode = inode->i_mode; | |
2109 | - name->uid = inode->i_uid; | |
2110 | - name->gid = inode->i_gid; | |
2111 | - name->rdev = inode->i_rdev; | |
2112 | - security_inode_getsecid(inode, &name->osid); | |
2113 | - audit_copy_fcaps(name, dentry); | |
2114 | 1763 | } |
2115 | 1764 | |
2116 | 1765 | /** |