.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* audit.c -- Auditing support |
---|
2 | 3 | * Gateway between the kernel (e.g., selinux) and the user-space audit daemon. |
---|
3 | 4 | * System-call specific features have moved to auditsc.c |
---|
4 | 5 | * |
---|
5 | 6 | * Copyright 2003-2007 Red Hat Inc., Durham, North Carolina. |
---|
6 | 7 | * All Rights Reserved. |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License as published by |
---|
10 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
11 | | - * (at your option) any later version. |
---|
12 | | - * |
---|
13 | | - * This program is distributed in the hope that it will be useful, |
---|
14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
16 | | - * GNU General Public License for more details. |
---|
17 | | - * |
---|
18 | | - * You should have received a copy of the GNU General Public License |
---|
19 | | - * along with this program; if not, write to the Free Software |
---|
20 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
21 | 8 | * |
---|
22 | 9 | * Written by Rickard E. (Rik) Faith <faith@redhat.com> |
---|
23 | 10 | * |
---|
.. | .. |
---|
60 | 47 | #include <linux/mutex.h> |
---|
61 | 48 | #include <linux/gfp.h> |
---|
62 | 49 | #include <linux/pid.h> |
---|
63 | | -#include <linux/slab.h> |
---|
64 | 50 | |
---|
65 | 51 | #include <linux/audit.h> |
---|
66 | 52 | |
---|
.. | .. |
---|
116 | 102 | * This struct is RCU protected; you must either hold the RCU lock for reading |
---|
117 | 103 | * or the associated spinlock for writing. |
---|
118 | 104 | */ |
---|
119 | | -static struct auditd_connection { |
---|
| 105 | +struct auditd_connection { |
---|
120 | 106 | struct pid *pid; |
---|
121 | 107 | u32 portid; |
---|
122 | 108 | struct net *net; |
---|
123 | 109 | struct rcu_head rcu; |
---|
124 | | -} *auditd_conn = NULL; |
---|
| 110 | +}; |
---|
| 111 | +static struct auditd_connection __rcu *auditd_conn; |
---|
125 | 112 | static DEFINE_SPINLOCK(auditd_conn_lock); |
---|
126 | 113 | |
---|
127 | 114 | /* If audit_rate_limit is non-zero, limit the rate of sending audit records |
---|
.. | .. |
---|
136 | 123 | static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; |
---|
137 | 124 | |
---|
138 | 125 | /* The identity of the user shutting down the audit system. */ |
---|
139 | | -kuid_t audit_sig_uid = INVALID_UID; |
---|
140 | | -pid_t audit_sig_pid = -1; |
---|
141 | | -u32 audit_sig_sid = 0; |
---|
| 126 | +static kuid_t audit_sig_uid = INVALID_UID; |
---|
| 127 | +static pid_t audit_sig_pid = -1; |
---|
| 128 | +static u32 audit_sig_sid; |
---|
142 | 129 | |
---|
143 | 130 | /* Records can be lost in several ways: |
---|
144 | 131 | 0) [suppressed in audit_alloc] |
---|
.. | .. |
---|
148 | 135 | 4) suppressed due to audit_backlog_limit |
---|
149 | 136 | */ |
---|
150 | 137 | static atomic_t audit_lost = ATOMIC_INIT(0); |
---|
| 138 | + |
---|
| 139 | +/* Monotonically increasing sum of time the kernel has spent |
---|
| 140 | + * waiting while the backlog limit is exceeded. |
---|
| 141 | + */ |
---|
| 142 | +static atomic_t audit_backlog_wait_time_actual = ATOMIC_INIT(0); |
---|
151 | 143 | |
---|
152 | 144 | /* Hash for inode-based rules */ |
---|
153 | 145 | struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; |
---|
.. | .. |
---|
397 | 389 | struct audit_buffer *ab; |
---|
398 | 390 | int rc = 0; |
---|
399 | 391 | |
---|
400 | | - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
---|
| 392 | + ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
---|
401 | 393 | if (unlikely(!ab)) |
---|
402 | 394 | return rc; |
---|
403 | | - audit_log_format(ab, "%s=%u old=%u", function_name, new, old); |
---|
| 395 | + audit_log_format(ab, "op=set %s=%u old=%u ", function_name, new, old); |
---|
404 | 396 | audit_log_session_info(ab); |
---|
405 | 397 | rc = audit_log_task_context(ab); |
---|
406 | 398 | if (rc) |
---|
.. | .. |
---|
866 | 858 | rc = kauditd_send_queue(sk, portid, |
---|
867 | 859 | &audit_hold_queue, UNICAST_RETRIES, |
---|
868 | 860 | NULL, kauditd_rehold_skb); |
---|
869 | | - if (ac && rc < 0) { |
---|
| 861 | + if (rc < 0) { |
---|
870 | 862 | sk = NULL; |
---|
871 | 863 | auditd_reset(ac); |
---|
872 | 864 | goto main_queue; |
---|
.. | .. |
---|
876 | 868 | rc = kauditd_send_queue(sk, portid, |
---|
877 | 869 | &audit_retry_queue, UNICAST_RETRIES, |
---|
878 | 870 | NULL, kauditd_hold_skb); |
---|
879 | | - if (ac && rc < 0) { |
---|
| 871 | + if (rc < 0) { |
---|
880 | 872 | sk = NULL; |
---|
881 | 873 | auditd_reset(ac); |
---|
882 | 874 | goto main_queue; |
---|
.. | .. |
---|
964 | 956 | if (!reply) |
---|
965 | 957 | return; |
---|
966 | 958 | |
---|
967 | | - if (reply->skb) |
---|
968 | | - kfree_skb(reply->skb); |
---|
| 959 | + kfree_skb(reply->skb); |
---|
969 | 960 | if (reply->net) |
---|
970 | 961 | put_net(reply->net); |
---|
971 | 962 | kfree(reply); |
---|
.. | .. |
---|
1084 | 1075 | return err; |
---|
1085 | 1076 | } |
---|
1086 | 1077 | |
---|
1087 | | -static void audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type) |
---|
| 1078 | +static void audit_log_common_recv_msg(struct audit_context *context, |
---|
| 1079 | + struct audit_buffer **ab, u16 msg_type) |
---|
1088 | 1080 | { |
---|
1089 | 1081 | uid_t uid = from_kuid(&init_user_ns, current_uid()); |
---|
1090 | 1082 | pid_t pid = task_tgid_nr(current); |
---|
.. | .. |
---|
1094 | 1086 | return; |
---|
1095 | 1087 | } |
---|
1096 | 1088 | |
---|
1097 | | - *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
---|
| 1089 | + *ab = audit_log_start(context, GFP_KERNEL, msg_type); |
---|
1098 | 1090 | if (unlikely(!*ab)) |
---|
1099 | 1091 | return; |
---|
1100 | | - audit_log_format(*ab, "pid=%d uid=%u", pid, uid); |
---|
| 1092 | + audit_log_format(*ab, "pid=%d uid=%u ", pid, uid); |
---|
1101 | 1093 | audit_log_session_info(*ab); |
---|
1102 | 1094 | audit_log_task_context(*ab); |
---|
| 1095 | +} |
---|
| 1096 | + |
---|
| 1097 | +static inline void audit_log_user_recv_msg(struct audit_buffer **ab, |
---|
| 1098 | + u16 msg_type) |
---|
| 1099 | +{ |
---|
| 1100 | + audit_log_common_recv_msg(NULL, ab, msg_type); |
---|
1103 | 1101 | } |
---|
1104 | 1102 | |
---|
1105 | 1103 | int is_audit_feature_set(int i) |
---|
.. | .. |
---|
1126 | 1124 | |
---|
1127 | 1125 | if (audit_enabled == AUDIT_OFF) |
---|
1128 | 1126 | return; |
---|
| 1127 | + |
---|
1129 | 1128 | ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_FEATURE_CHANGE); |
---|
1130 | 1129 | if (!ab) |
---|
1131 | 1130 | return; |
---|
1132 | | - audit_log_task_info(ab, current); |
---|
| 1131 | + audit_log_task_info(ab); |
---|
1133 | 1132 | audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", |
---|
1134 | 1133 | audit_feature_names[which], !!old_feature, !!new_feature, |
---|
1135 | 1134 | !!old_lock, !!new_lock, res); |
---|
.. | .. |
---|
1228 | 1227 | case AUDIT_GET: { |
---|
1229 | 1228 | struct audit_status s; |
---|
1230 | 1229 | memset(&s, 0, sizeof(s)); |
---|
1231 | | - s.enabled = audit_enabled; |
---|
1232 | | - s.failure = audit_failure; |
---|
| 1230 | + s.enabled = audit_enabled; |
---|
| 1231 | + s.failure = audit_failure; |
---|
1233 | 1232 | /* NOTE: use pid_vnr() so the PID is relative to the current |
---|
1234 | 1233 | * namespace */ |
---|
1235 | | - s.pid = auditd_pid_vnr(); |
---|
1236 | | - s.rate_limit = audit_rate_limit; |
---|
1237 | | - s.backlog_limit = audit_backlog_limit; |
---|
1238 | | - s.lost = atomic_read(&audit_lost); |
---|
1239 | | - s.backlog = skb_queue_len(&audit_queue); |
---|
1240 | | - s.feature_bitmap = AUDIT_FEATURE_BITMAP_ALL; |
---|
1241 | | - s.backlog_wait_time = audit_backlog_wait_time; |
---|
| 1234 | + s.pid = auditd_pid_vnr(); |
---|
| 1235 | + s.rate_limit = audit_rate_limit; |
---|
| 1236 | + s.backlog_limit = audit_backlog_limit; |
---|
| 1237 | + s.lost = atomic_read(&audit_lost); |
---|
| 1238 | + s.backlog = skb_queue_len(&audit_queue); |
---|
| 1239 | + s.feature_bitmap = AUDIT_FEATURE_BITMAP_ALL; |
---|
| 1240 | + s.backlog_wait_time = audit_backlog_wait_time; |
---|
| 1241 | + s.backlog_wait_time_actual = atomic_read(&audit_backlog_wait_time_actual); |
---|
1242 | 1242 | audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s)); |
---|
1243 | 1243 | break; |
---|
1244 | 1244 | } |
---|
.. | .. |
---|
1342 | 1342 | audit_log_config_change("lost", 0, lost, 1); |
---|
1343 | 1343 | return lost; |
---|
1344 | 1344 | } |
---|
| 1345 | + if (s.mask == AUDIT_STATUS_BACKLOG_WAIT_TIME_ACTUAL) { |
---|
| 1346 | + u32 actual = atomic_xchg(&audit_backlog_wait_time_actual, 0); |
---|
| 1347 | + |
---|
| 1348 | + audit_log_config_change("backlog_wait_time_actual", 0, actual, 1); |
---|
| 1349 | + return actual; |
---|
| 1350 | + } |
---|
1345 | 1351 | break; |
---|
1346 | 1352 | } |
---|
1347 | 1353 | case AUDIT_GET_FEATURE: |
---|
.. | .. |
---|
1375 | 1381 | if (err) |
---|
1376 | 1382 | break; |
---|
1377 | 1383 | } |
---|
1378 | | - audit_log_common_recv_msg(&ab, msg_type); |
---|
| 1384 | + audit_log_user_recv_msg(&ab, msg_type); |
---|
1379 | 1385 | if (msg_type != AUDIT_USER_TTY) { |
---|
1380 | 1386 | /* ensure NULL termination */ |
---|
1381 | 1387 | str[data_len - 1] = '\0'; |
---|
.. | .. |
---|
1396 | 1402 | if (data_len < sizeof(struct audit_rule_data)) |
---|
1397 | 1403 | return -EINVAL; |
---|
1398 | 1404 | if (audit_enabled == AUDIT_LOCKED) { |
---|
1399 | | - audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); |
---|
1400 | | - audit_log_format(ab, " audit_enabled=%d res=0", audit_enabled); |
---|
| 1405 | + audit_log_common_recv_msg(audit_context(), &ab, |
---|
| 1406 | + AUDIT_CONFIG_CHANGE); |
---|
| 1407 | + audit_log_format(ab, " op=%s audit_enabled=%d res=0", |
---|
| 1408 | + msg_type == AUDIT_ADD_RULE ? |
---|
| 1409 | + "add_rule" : "remove_rule", |
---|
| 1410 | + audit_enabled); |
---|
1401 | 1411 | audit_log_end(ab); |
---|
1402 | 1412 | return -EPERM; |
---|
1403 | 1413 | } |
---|
.. | .. |
---|
1408 | 1418 | break; |
---|
1409 | 1419 | case AUDIT_TRIM: |
---|
1410 | 1420 | audit_trim_trees(); |
---|
1411 | | - audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); |
---|
| 1421 | + audit_log_common_recv_msg(audit_context(), &ab, |
---|
| 1422 | + AUDIT_CONFIG_CHANGE); |
---|
1412 | 1423 | audit_log_format(ab, " op=trim res=1"); |
---|
1413 | 1424 | audit_log_end(ab); |
---|
1414 | 1425 | break; |
---|
.. | .. |
---|
1438 | 1449 | /* OK, here comes... */ |
---|
1439 | 1450 | err = audit_tag_tree(old, new); |
---|
1440 | 1451 | |
---|
1441 | | - audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); |
---|
1442 | | - |
---|
| 1452 | + audit_log_common_recv_msg(audit_context(), &ab, |
---|
| 1453 | + AUDIT_CONFIG_CHANGE); |
---|
1443 | 1454 | audit_log_format(ab, " op=make_equiv old="); |
---|
1444 | 1455 | audit_log_untrustedstring(ab, old); |
---|
1445 | 1456 | audit_log_format(ab, " new="); |
---|
.. | .. |
---|
1506 | 1517 | old.enabled = t & AUDIT_TTY_ENABLE; |
---|
1507 | 1518 | old.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD); |
---|
1508 | 1519 | |
---|
1509 | | - audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); |
---|
| 1520 | + audit_log_common_recv_msg(audit_context(), &ab, |
---|
| 1521 | + AUDIT_CONFIG_CHANGE); |
---|
1510 | 1522 | audit_log_format(ab, " op=tty_set old-enabled=%d new-enabled=%d" |
---|
1511 | 1523 | " old-log_passwd=%d new-log_passwd=%d res=%d", |
---|
1512 | 1524 | old.enabled, s.enabled, old.log_passwd, |
---|
.. | .. |
---|
1568 | 1580 | } |
---|
1569 | 1581 | } |
---|
1570 | 1582 | |
---|
1571 | | -/* Run custom bind function on netlink socket group connect or bind requests. */ |
---|
1572 | | -static int audit_bind(struct net *net, int group) |
---|
| 1583 | +/* Log information about who is connecting to the audit multicast socket */ |
---|
| 1584 | +static void audit_log_multicast(int group, const char *op, int err) |
---|
1573 | 1585 | { |
---|
1574 | | - if (!capable(CAP_AUDIT_READ)) |
---|
1575 | | - return -EPERM; |
---|
| 1586 | + const struct cred *cred; |
---|
| 1587 | + struct tty_struct *tty; |
---|
| 1588 | + char comm[sizeof(current->comm)]; |
---|
| 1589 | + struct audit_buffer *ab; |
---|
1576 | 1590 | |
---|
1577 | | - return 0; |
---|
| 1591 | + if (!audit_enabled) |
---|
| 1592 | + return; |
---|
| 1593 | + |
---|
| 1594 | + ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_EVENT_LISTENER); |
---|
| 1595 | + if (!ab) |
---|
| 1596 | + return; |
---|
| 1597 | + |
---|
| 1598 | + cred = current_cred(); |
---|
| 1599 | + tty = audit_get_tty(); |
---|
| 1600 | + audit_log_format(ab, "pid=%u uid=%u auid=%u tty=%s ses=%u", |
---|
| 1601 | + task_pid_nr(current), |
---|
| 1602 | + from_kuid(&init_user_ns, cred->uid), |
---|
| 1603 | + from_kuid(&init_user_ns, audit_get_loginuid(current)), |
---|
| 1604 | + tty ? tty_name(tty) : "(none)", |
---|
| 1605 | + audit_get_sessionid(current)); |
---|
| 1606 | + audit_put_tty(tty); |
---|
| 1607 | + audit_log_task_context(ab); /* subj= */ |
---|
| 1608 | + audit_log_format(ab, " comm="); |
---|
| 1609 | + audit_log_untrustedstring(ab, get_task_comm(comm, current)); |
---|
| 1610 | + audit_log_d_path_exe(ab, current->mm); /* exe= */ |
---|
| 1611 | + audit_log_format(ab, " nl-mcgrp=%d op=%s res=%d", group, op, !err); |
---|
| 1612 | + audit_log_end(ab); |
---|
| 1613 | +} |
---|
| 1614 | + |
---|
| 1615 | +/* Run custom bind function on netlink socket group connect or bind requests. */ |
---|
| 1616 | +static int audit_multicast_bind(struct net *net, int group) |
---|
| 1617 | +{ |
---|
| 1618 | + int err = 0; |
---|
| 1619 | + |
---|
| 1620 | + if (!capable(CAP_AUDIT_READ)) |
---|
| 1621 | + err = -EPERM; |
---|
| 1622 | + audit_log_multicast(group, "connect", err); |
---|
| 1623 | + return err; |
---|
| 1624 | +} |
---|
| 1625 | + |
---|
| 1626 | +static void audit_multicast_unbind(struct net *net, int group) |
---|
| 1627 | +{ |
---|
| 1628 | + audit_log_multicast(group, "disconnect", 0); |
---|
1578 | 1629 | } |
---|
1579 | 1630 | |
---|
1580 | 1631 | static int __net_init audit_net_init(struct net *net) |
---|
1581 | 1632 | { |
---|
1582 | 1633 | struct netlink_kernel_cfg cfg = { |
---|
1583 | 1634 | .input = audit_receive, |
---|
1584 | | - .bind = audit_bind, |
---|
| 1635 | + .bind = audit_multicast_bind, |
---|
| 1636 | + .unbind = audit_multicast_unbind, |
---|
1585 | 1637 | .flags = NL_CFG_F_NONROOT_RECV, |
---|
1586 | 1638 | .groups = AUDIT_NLGRP_MAX, |
---|
1587 | 1639 | }; |
---|
.. | .. |
---|
1796 | 1848 | { |
---|
1797 | 1849 | struct audit_buffer *ab; |
---|
1798 | 1850 | struct timespec64 t; |
---|
1799 | | - unsigned int uninitialized_var(serial); |
---|
| 1851 | + unsigned int serial; |
---|
1800 | 1852 | |
---|
1801 | 1853 | if (audit_initialized != AUDIT_INITIALIZED) |
---|
1802 | 1854 | return NULL; |
---|
.. | .. |
---|
1824 | 1876 | /* sleep if we are allowed and we haven't exhausted our |
---|
1825 | 1877 | * backlog wait limit */ |
---|
1826 | 1878 | if (gfpflags_allow_blocking(gfp_mask) && (stime > 0)) { |
---|
| 1879 | + long rtime = stime; |
---|
| 1880 | + |
---|
1827 | 1881 | DECLARE_WAITQUEUE(wait, current); |
---|
1828 | 1882 | |
---|
1829 | 1883 | add_wait_queue_exclusive(&audit_backlog_wait, |
---|
1830 | 1884 | &wait); |
---|
1831 | 1885 | set_current_state(TASK_UNINTERRUPTIBLE); |
---|
1832 | | - stime = schedule_timeout(stime); |
---|
| 1886 | + stime = schedule_timeout(rtime); |
---|
| 1887 | + atomic_add(rtime - stime, &audit_backlog_wait_time_actual); |
---|
1833 | 1888 | remove_wait_queue(&audit_backlog_wait, &wait); |
---|
1834 | 1889 | } else { |
---|
1835 | 1890 | if (audit_rate_check() && printk_ratelimit()) |
---|
.. | .. |
---|
2077 | 2132 | /* We will allow 11 spaces for ' (deleted)' to be appended */ |
---|
2078 | 2133 | pathname = kmalloc(PATH_MAX+11, ab->gfp_mask); |
---|
2079 | 2134 | if (!pathname) { |
---|
2080 | | - audit_log_string(ab, "<no_memory>"); |
---|
| 2135 | + audit_log_format(ab, "\"<no_memory>\""); |
---|
2081 | 2136 | return; |
---|
2082 | 2137 | } |
---|
2083 | 2138 | p = d_path(path, pathname, PATH_MAX+11); |
---|
2084 | 2139 | if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */ |
---|
2085 | 2140 | /* FIXME: can we save some information here? */ |
---|
2086 | | - audit_log_string(ab, "<too_long>"); |
---|
| 2141 | + audit_log_format(ab, "\"<too_long>\""); |
---|
2087 | 2142 | } else |
---|
2088 | 2143 | audit_log_untrustedstring(ab, p); |
---|
2089 | 2144 | kfree(pathname); |
---|
.. | .. |
---|
2094 | 2149 | unsigned int sessionid = audit_get_sessionid(current); |
---|
2095 | 2150 | uid_t auid = from_kuid(&init_user_ns, audit_get_loginuid(current)); |
---|
2096 | 2151 | |
---|
2097 | | - audit_log_format(ab, " auid=%u ses=%u", auid, sessionid); |
---|
| 2152 | + audit_log_format(ab, "auid=%u ses=%u", auid, sessionid); |
---|
2098 | 2153 | } |
---|
2099 | 2154 | |
---|
2100 | 2155 | void audit_log_key(struct audit_buffer *ab, char *key) |
---|
.. | .. |
---|
2104 | 2159 | audit_log_untrustedstring(ab, key); |
---|
2105 | 2160 | else |
---|
2106 | 2161 | audit_log_format(ab, "(null)"); |
---|
2107 | | -} |
---|
2108 | | - |
---|
2109 | | -void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap) |
---|
2110 | | -{ |
---|
2111 | | - int i; |
---|
2112 | | - |
---|
2113 | | - audit_log_format(ab, " %s=", prefix); |
---|
2114 | | - CAP_FOR_EACH_U32(i) { |
---|
2115 | | - audit_log_format(ab, "%08x", |
---|
2116 | | - cap->cap[CAP_LAST_U32 - i]); |
---|
2117 | | - } |
---|
2118 | | -} |
---|
2119 | | - |
---|
2120 | | -static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) |
---|
2121 | | -{ |
---|
2122 | | - audit_log_cap(ab, "cap_fp", &name->fcap.permitted); |
---|
2123 | | - audit_log_cap(ab, "cap_fi", &name->fcap.inheritable); |
---|
2124 | | - audit_log_format(ab, " cap_fe=%d cap_fver=%x", |
---|
2125 | | - name->fcap.fE, name->fcap_ver); |
---|
2126 | | -} |
---|
2127 | | - |
---|
2128 | | -static inline int audit_copy_fcaps(struct audit_names *name, |
---|
2129 | | - const struct dentry *dentry) |
---|
2130 | | -{ |
---|
2131 | | - struct cpu_vfs_cap_data caps; |
---|
2132 | | - int rc; |
---|
2133 | | - |
---|
2134 | | - if (!dentry) |
---|
2135 | | - return 0; |
---|
2136 | | - |
---|
2137 | | - rc = get_vfs_caps_from_disk(dentry, &caps); |
---|
2138 | | - if (rc) |
---|
2139 | | - return rc; |
---|
2140 | | - |
---|
2141 | | - name->fcap.permitted = caps.permitted; |
---|
2142 | | - name->fcap.inheritable = caps.inheritable; |
---|
2143 | | - name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); |
---|
2144 | | - name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >> |
---|
2145 | | - VFS_CAP_REVISION_SHIFT; |
---|
2146 | | - |
---|
2147 | | - return 0; |
---|
2148 | | -} |
---|
2149 | | - |
---|
2150 | | -/* Copy inode data into an audit_names. */ |
---|
2151 | | -void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, |
---|
2152 | | - struct inode *inode) |
---|
2153 | | -{ |
---|
2154 | | - name->ino = inode->i_ino; |
---|
2155 | | - name->dev = inode->i_sb->s_dev; |
---|
2156 | | - name->mode = inode->i_mode; |
---|
2157 | | - name->uid = inode->i_uid; |
---|
2158 | | - name->gid = inode->i_gid; |
---|
2159 | | - name->rdev = inode->i_rdev; |
---|
2160 | | - security_inode_getsecid(inode, &name->osid); |
---|
2161 | | - audit_copy_fcaps(name, dentry); |
---|
2162 | | -} |
---|
2163 | | - |
---|
2164 | | -/** |
---|
2165 | | - * audit_log_name - produce AUDIT_PATH record from struct audit_names |
---|
2166 | | - * @context: audit_context for the task |
---|
2167 | | - * @n: audit_names structure with reportable details |
---|
2168 | | - * @path: optional path to report instead of audit_names->name |
---|
2169 | | - * @record_num: record number to report when handling a list of names |
---|
2170 | | - * @call_panic: optional pointer to int that will be updated if secid fails |
---|
2171 | | - */ |
---|
2172 | | -void audit_log_name(struct audit_context *context, struct audit_names *n, |
---|
2173 | | - const struct path *path, int record_num, int *call_panic) |
---|
2174 | | -{ |
---|
2175 | | - struct audit_buffer *ab; |
---|
2176 | | - ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); |
---|
2177 | | - if (!ab) |
---|
2178 | | - return; |
---|
2179 | | - |
---|
2180 | | - audit_log_format(ab, "item=%d", record_num); |
---|
2181 | | - |
---|
2182 | | - if (path) |
---|
2183 | | - audit_log_d_path(ab, " name=", path); |
---|
2184 | | - else if (n->name) { |
---|
2185 | | - switch (n->name_len) { |
---|
2186 | | - case AUDIT_NAME_FULL: |
---|
2187 | | - /* log the full path */ |
---|
2188 | | - audit_log_format(ab, " name="); |
---|
2189 | | - audit_log_untrustedstring(ab, n->name->name); |
---|
2190 | | - break; |
---|
2191 | | - case 0: |
---|
2192 | | - /* name was specified as a relative path and the |
---|
2193 | | - * directory component is the cwd */ |
---|
2194 | | - audit_log_d_path(ab, " name=", &context->pwd); |
---|
2195 | | - break; |
---|
2196 | | - default: |
---|
2197 | | - /* log the name's directory component */ |
---|
2198 | | - audit_log_format(ab, " name="); |
---|
2199 | | - audit_log_n_untrustedstring(ab, n->name->name, |
---|
2200 | | - n->name_len); |
---|
2201 | | - } |
---|
2202 | | - } else |
---|
2203 | | - audit_log_format(ab, " name=(null)"); |
---|
2204 | | - |
---|
2205 | | - if (n->ino != AUDIT_INO_UNSET) |
---|
2206 | | - audit_log_format(ab, " inode=%lu" |
---|
2207 | | - " dev=%02x:%02x mode=%#ho" |
---|
2208 | | - " ouid=%u ogid=%u rdev=%02x:%02x", |
---|
2209 | | - n->ino, |
---|
2210 | | - MAJOR(n->dev), |
---|
2211 | | - MINOR(n->dev), |
---|
2212 | | - n->mode, |
---|
2213 | | - from_kuid(&init_user_ns, n->uid), |
---|
2214 | | - from_kgid(&init_user_ns, n->gid), |
---|
2215 | | - MAJOR(n->rdev), |
---|
2216 | | - MINOR(n->rdev)); |
---|
2217 | | - if (n->osid != 0) { |
---|
2218 | | - char *ctx = NULL; |
---|
2219 | | - u32 len; |
---|
2220 | | - if (security_secid_to_secctx( |
---|
2221 | | - n->osid, &ctx, &len)) { |
---|
2222 | | - audit_log_format(ab, " osid=%u", n->osid); |
---|
2223 | | - if (call_panic) |
---|
2224 | | - *call_panic = 2; |
---|
2225 | | - } else { |
---|
2226 | | - audit_log_format(ab, " obj=%s", ctx); |
---|
2227 | | - security_release_secctx(ctx, len); |
---|
2228 | | - } |
---|
2229 | | - } |
---|
2230 | | - |
---|
2231 | | - /* log the audit_names record type */ |
---|
2232 | | - audit_log_format(ab, " nametype="); |
---|
2233 | | - switch(n->type) { |
---|
2234 | | - case AUDIT_TYPE_NORMAL: |
---|
2235 | | - audit_log_format(ab, "NORMAL"); |
---|
2236 | | - break; |
---|
2237 | | - case AUDIT_TYPE_PARENT: |
---|
2238 | | - audit_log_format(ab, "PARENT"); |
---|
2239 | | - break; |
---|
2240 | | - case AUDIT_TYPE_CHILD_DELETE: |
---|
2241 | | - audit_log_format(ab, "DELETE"); |
---|
2242 | | - break; |
---|
2243 | | - case AUDIT_TYPE_CHILD_CREATE: |
---|
2244 | | - audit_log_format(ab, "CREATE"); |
---|
2245 | | - break; |
---|
2246 | | - default: |
---|
2247 | | - audit_log_format(ab, "UNKNOWN"); |
---|
2248 | | - break; |
---|
2249 | | - } |
---|
2250 | | - |
---|
2251 | | - audit_log_fcaps(ab, n); |
---|
2252 | | - audit_log_end(ab); |
---|
2253 | 2162 | } |
---|
2254 | 2163 | |
---|
2255 | 2164 | int audit_log_task_context(struct audit_buffer *ab) |
---|
.. | .. |
---|
2299 | 2208 | audit_log_format(ab, " exe=(null)"); |
---|
2300 | 2209 | } |
---|
2301 | 2210 | |
---|
2302 | | -struct tty_struct *audit_get_tty(struct task_struct *tsk) |
---|
| 2211 | +struct tty_struct *audit_get_tty(void) |
---|
2303 | 2212 | { |
---|
2304 | 2213 | struct tty_struct *tty = NULL; |
---|
2305 | 2214 | unsigned long flags; |
---|
2306 | 2215 | |
---|
2307 | | - spin_lock_irqsave(&tsk->sighand->siglock, flags); |
---|
2308 | | - if (tsk->signal) |
---|
2309 | | - tty = tty_kref_get(tsk->signal->tty); |
---|
2310 | | - spin_unlock_irqrestore(&tsk->sighand->siglock, flags); |
---|
| 2216 | + spin_lock_irqsave(¤t->sighand->siglock, flags); |
---|
| 2217 | + if (current->signal) |
---|
| 2218 | + tty = tty_kref_get(current->signal->tty); |
---|
| 2219 | + spin_unlock_irqrestore(¤t->sighand->siglock, flags); |
---|
2311 | 2220 | return tty; |
---|
2312 | 2221 | } |
---|
2313 | 2222 | |
---|
.. | .. |
---|
2316 | 2225 | tty_kref_put(tty); |
---|
2317 | 2226 | } |
---|
2318 | 2227 | |
---|
2319 | | -void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) |
---|
| 2228 | +void audit_log_task_info(struct audit_buffer *ab) |
---|
2320 | 2229 | { |
---|
2321 | 2230 | const struct cred *cred; |
---|
2322 | | - char comm[sizeof(tsk->comm)]; |
---|
| 2231 | + char comm[sizeof(current->comm)]; |
---|
2323 | 2232 | struct tty_struct *tty; |
---|
2324 | 2233 | |
---|
2325 | 2234 | if (!ab) |
---|
2326 | 2235 | return; |
---|
2327 | 2236 | |
---|
2328 | | - /* tsk == current */ |
---|
2329 | 2237 | cred = current_cred(); |
---|
2330 | | - tty = audit_get_tty(tsk); |
---|
| 2238 | + tty = audit_get_tty(); |
---|
2331 | 2239 | audit_log_format(ab, |
---|
2332 | 2240 | " ppid=%d pid=%d auid=%u uid=%u gid=%u" |
---|
2333 | 2241 | " euid=%u suid=%u fsuid=%u" |
---|
2334 | 2242 | " egid=%u sgid=%u fsgid=%u tty=%s ses=%u", |
---|
2335 | | - task_ppid_nr(tsk), |
---|
2336 | | - task_tgid_nr(tsk), |
---|
2337 | | - from_kuid(&init_user_ns, audit_get_loginuid(tsk)), |
---|
| 2243 | + task_ppid_nr(current), |
---|
| 2244 | + task_tgid_nr(current), |
---|
| 2245 | + from_kuid(&init_user_ns, audit_get_loginuid(current)), |
---|
2338 | 2246 | from_kuid(&init_user_ns, cred->uid), |
---|
2339 | 2247 | from_kgid(&init_user_ns, cred->gid), |
---|
2340 | 2248 | from_kuid(&init_user_ns, cred->euid), |
---|
.. | .. |
---|
2344 | 2252 | from_kgid(&init_user_ns, cred->sgid), |
---|
2345 | 2253 | from_kgid(&init_user_ns, cred->fsgid), |
---|
2346 | 2254 | tty ? tty_name(tty) : "(none)", |
---|
2347 | | - audit_get_sessionid(tsk)); |
---|
| 2255 | + audit_get_sessionid(current)); |
---|
2348 | 2256 | audit_put_tty(tty); |
---|
2349 | 2257 | audit_log_format(ab, " comm="); |
---|
2350 | | - audit_log_untrustedstring(ab, get_task_comm(comm, tsk)); |
---|
2351 | | - audit_log_d_path_exe(ab, tsk->mm); |
---|
| 2258 | + audit_log_untrustedstring(ab, get_task_comm(comm, current)); |
---|
| 2259 | + audit_log_d_path_exe(ab, current->mm); |
---|
2352 | 2260 | audit_log_task_context(ab); |
---|
2353 | 2261 | } |
---|
2354 | 2262 | EXPORT_SYMBOL(audit_log_task_info); |
---|
2355 | 2263 | |
---|
2356 | 2264 | /** |
---|
2357 | | - * audit_log_link_denied - report a link restriction denial |
---|
2358 | | - * @operation: specific link operation |
---|
| 2265 | + * audit_log_path_denied - report a path restriction denial |
---|
| 2266 | + * @type: audit message type (AUDIT_ANOM_LINK, AUDIT_ANOM_CREAT, etc) |
---|
| 2267 | + * @operation: specific operation name |
---|
2359 | 2268 | */ |
---|
2360 | | -void audit_log_link_denied(const char *operation) |
---|
| 2269 | +void audit_log_path_denied(int type, const char *operation) |
---|
2361 | 2270 | { |
---|
2362 | 2271 | struct audit_buffer *ab; |
---|
2363 | 2272 | |
---|
2364 | 2273 | if (!audit_enabled || audit_dummy_context()) |
---|
2365 | 2274 | return; |
---|
2366 | 2275 | |
---|
2367 | | - /* Generate AUDIT_ANOM_LINK with subject, operation, outcome. */ |
---|
2368 | | - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_ANOM_LINK); |
---|
| 2276 | + /* Generate log with subject, operation, outcome. */ |
---|
| 2277 | + ab = audit_log_start(audit_context(), GFP_KERNEL, type); |
---|
2369 | 2278 | if (!ab) |
---|
2370 | 2279 | return; |
---|
2371 | 2280 | audit_log_format(ab, "op=%s", operation); |
---|
2372 | | - audit_log_task_info(ab, current); |
---|
| 2281 | + audit_log_task_info(ab); |
---|
2373 | 2282 | audit_log_format(ab, " res=0"); |
---|
2374 | 2283 | audit_log_end(ab); |
---|
2375 | 2284 | } |
---|
2376 | 2285 | |
---|
| 2286 | +/* global counter which is incremented every time something logs in */ |
---|
| 2287 | +static atomic_t session_id = ATOMIC_INIT(0); |
---|
| 2288 | + |
---|
| 2289 | +static int audit_set_loginuid_perm(kuid_t loginuid) |
---|
| 2290 | +{ |
---|
| 2291 | + /* if we are unset, we don't need privs */ |
---|
| 2292 | + if (!audit_loginuid_set(current)) |
---|
| 2293 | + return 0; |
---|
| 2294 | + /* if AUDIT_FEATURE_LOGINUID_IMMUTABLE means never ever allow a change*/ |
---|
| 2295 | + if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE)) |
---|
| 2296 | + return -EPERM; |
---|
| 2297 | + /* it is set, you need permission */ |
---|
| 2298 | + if (!capable(CAP_AUDIT_CONTROL)) |
---|
| 2299 | + return -EPERM; |
---|
| 2300 | + /* reject if this is not an unset and we don't allow that */ |
---|
| 2301 | + if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) |
---|
| 2302 | + && uid_valid(loginuid)) |
---|
| 2303 | + return -EPERM; |
---|
| 2304 | + return 0; |
---|
| 2305 | +} |
---|
| 2306 | + |
---|
| 2307 | +static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, |
---|
| 2308 | + unsigned int oldsessionid, |
---|
| 2309 | + unsigned int sessionid, int rc) |
---|
| 2310 | +{ |
---|
| 2311 | + struct audit_buffer *ab; |
---|
| 2312 | + uid_t uid, oldloginuid, loginuid; |
---|
| 2313 | + struct tty_struct *tty; |
---|
| 2314 | + |
---|
| 2315 | + if (!audit_enabled) |
---|
| 2316 | + return; |
---|
| 2317 | + |
---|
| 2318 | + ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_LOGIN); |
---|
| 2319 | + if (!ab) |
---|
| 2320 | + return; |
---|
| 2321 | + |
---|
| 2322 | + uid = from_kuid(&init_user_ns, task_uid(current)); |
---|
| 2323 | + oldloginuid = from_kuid(&init_user_ns, koldloginuid); |
---|
| 2324 | + loginuid = from_kuid(&init_user_ns, kloginuid), |
---|
| 2325 | + tty = audit_get_tty(); |
---|
| 2326 | + |
---|
| 2327 | + audit_log_format(ab, "pid=%d uid=%u", task_tgid_nr(current), uid); |
---|
| 2328 | + audit_log_task_context(ab); |
---|
| 2329 | + audit_log_format(ab, " old-auid=%u auid=%u tty=%s old-ses=%u ses=%u res=%d", |
---|
| 2330 | + oldloginuid, loginuid, tty ? tty_name(tty) : "(none)", |
---|
| 2331 | + oldsessionid, sessionid, !rc); |
---|
| 2332 | + audit_put_tty(tty); |
---|
| 2333 | + audit_log_end(ab); |
---|
| 2334 | +} |
---|
| 2335 | + |
---|
| 2336 | +/** |
---|
| 2337 | + * audit_set_loginuid - set current task's loginuid |
---|
| 2338 | + * @loginuid: loginuid value |
---|
| 2339 | + * |
---|
| 2340 | + * Returns 0. |
---|
| 2341 | + * |
---|
| 2342 | + * Called (set) from fs/proc/base.c::proc_loginuid_write(). |
---|
| 2343 | + */ |
---|
| 2344 | +int audit_set_loginuid(kuid_t loginuid) |
---|
| 2345 | +{ |
---|
| 2346 | + unsigned int oldsessionid, sessionid = AUDIT_SID_UNSET; |
---|
| 2347 | + kuid_t oldloginuid; |
---|
| 2348 | + int rc; |
---|
| 2349 | + |
---|
| 2350 | + oldloginuid = audit_get_loginuid(current); |
---|
| 2351 | + oldsessionid = audit_get_sessionid(current); |
---|
| 2352 | + |
---|
| 2353 | + rc = audit_set_loginuid_perm(loginuid); |
---|
| 2354 | + if (rc) |
---|
| 2355 | + goto out; |
---|
| 2356 | + |
---|
| 2357 | + /* are we setting or clearing? */ |
---|
| 2358 | + if (uid_valid(loginuid)) { |
---|
| 2359 | + sessionid = (unsigned int)atomic_inc_return(&session_id); |
---|
| 2360 | + if (unlikely(sessionid == AUDIT_SID_UNSET)) |
---|
| 2361 | + sessionid = (unsigned int)atomic_inc_return(&session_id); |
---|
| 2362 | + } |
---|
| 2363 | + |
---|
| 2364 | + current->sessionid = sessionid; |
---|
| 2365 | + current->loginuid = loginuid; |
---|
| 2366 | +out: |
---|
| 2367 | + audit_log_set_loginuid(oldloginuid, loginuid, oldsessionid, sessionid, rc); |
---|
| 2368 | + return rc; |
---|
| 2369 | +} |
---|
| 2370 | + |
---|
| 2371 | +/** |
---|
| 2372 | + * audit_signal_info - record signal info for shutting down audit subsystem |
---|
| 2373 | + * @sig: signal value |
---|
| 2374 | + * @t: task being signaled |
---|
| 2375 | + * |
---|
| 2376 | + * If the audit subsystem is being terminated, record the task (pid) |
---|
| 2377 | + * and uid that is doing that. |
---|
| 2378 | + */ |
---|
| 2379 | +int audit_signal_info(int sig, struct task_struct *t) |
---|
| 2380 | +{ |
---|
| 2381 | + kuid_t uid = current_uid(), auid; |
---|
| 2382 | + |
---|
| 2383 | + if (auditd_test_task(t) && |
---|
| 2384 | + (sig == SIGTERM || sig == SIGHUP || |
---|
| 2385 | + sig == SIGUSR1 || sig == SIGUSR2)) { |
---|
| 2386 | + audit_sig_pid = task_tgid_nr(current); |
---|
| 2387 | + auid = audit_get_loginuid(current); |
---|
| 2388 | + if (uid_valid(auid)) |
---|
| 2389 | + audit_sig_uid = auid; |
---|
| 2390 | + else |
---|
| 2391 | + audit_sig_uid = uid; |
---|
| 2392 | + security_task_getsecid(current, &audit_sig_sid); |
---|
| 2393 | + } |
---|
| 2394 | + |
---|
| 2395 | + return audit_signal_info_syscall(t); |
---|
| 2396 | +} |
---|
| 2397 | + |
---|
2377 | 2398 | /** |
---|
2378 | 2399 | * audit_log_end - end one audit record |
---|
2379 | 2400 | * @ab: the audit_buffer |
---|