185c8721fS /* audit.c -- Auditing support 21da177e4SLinus Torvalds * Gateway between the kernel (e.g., selinux) and the user-space audit daemon. 31da177e4SLinus Torvalds * System-call specific features have moved to auditsc.c 41da177e4SLinus Torvalds * 56a01b07fSSteve Grubb * Copyright 2003-2007 Red Hat Inc., Durham, North Carolina. 61da177e4SLinus Torvalds * All Rights Reserved. 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 91da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 101da177e4SLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 111da177e4SLinus Torvalds * (at your option) any later version. 121da177e4SLinus Torvalds * 131da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful, 141da177e4SLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 151da177e4SLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 161da177e4SLinus Torvalds * GNU General Public License for more details. 171da177e4SLinus Torvalds * 181da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 191da177e4SLinus Torvalds * along with this program; if not, write to the Free Software 201da177e4SLinus Torvalds * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 211da177e4SLinus Torvalds * 221da177e4SLinus Torvalds * Written by Rickard E. (Rik) Faith <faith@redhat.com> 231da177e4SLinus Torvalds * 24d7a96f3aSAhmed S. Darwish * Goals: 1) Integrate fully with Security Modules. 251da177e4SLinus Torvalds * 2) Minimal run-time overhead: 261da177e4SLinus Torvalds * a) Minimal when syscall auditing is disabled (audit_enable=0). 271da177e4SLinus Torvalds * b) Small when syscall auditing is enabled and no audit record 281da177e4SLinus Torvalds * is generated (defer as much work as possible to record 291da177e4SLinus Torvalds * generation time): 301da177e4SLinus Torvalds * i) context is allocated, 311da177e4SLinus Torvalds * ii) names from getname are stored without a copy, and 321da177e4SLinus Torvalds * iii) inode information stored from path_lookup. 331da177e4SLinus Torvalds * 3) Ability to disable syscall auditing at boot time (audit=0). 341da177e4SLinus Torvalds * 4) Usable by other parts of the kernel (if audit_log* is called, 351da177e4SLinus Torvalds * then a syscall record will be generated automatically for the 361da177e4SLinus Torvalds * current syscall). 371da177e4SLinus Torvalds * 5) Netlink interface to user-space. 381da177e4SLinus Torvalds * 6) Support low-overhead kernel-based filtering to minimize the 391da177e4SLinus Torvalds * information that must be passed to user-space. 401da177e4SLinus Torvalds * 4185c8721fS * Example user-space utilities: http://people.redhat.com/sgrubb/audit/ 421da177e4SLinus Torvalds */ 431da177e4SLinus Torvalds 44d957f7b7SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 45d957f7b7SJoe Perches 465b282552SDavidlohr Bueso #include <linux/file.h> 471da177e4SLinus Torvalds #include <linux/init.h> 487153e402SPaul McQuade #include <linux/types.h> 4960063497SArun Sharma #include <linux/atomic.h> 501da177e4SLinus Torvalds #include <linux/mm.h> 519984de1aSPaul Gortmaker #include <linux/export.h> 525a0e3ad6STejun Heo #include <linux/slab.h> 53b7d11258SDavid Woodhouse #include <linux/err.h> 54b7d11258SDavid Woodhouse #include <linux/kthread.h> 5546e959eaSRichard Guy Briggs #include <linux/kernel.h> 56b24a30a7SEric Paris #include <linux/syscalls.h> 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds #include <linux/audit.h> 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds #include <net/sock.h> 6193315ed6SAmy Griffis #include <net/netlink.h> 621da177e4SLinus Torvalds #include <linux/skbuff.h> 63131ad62dSMr Dash Four #ifdef CONFIG_SECURITY 64131ad62dSMr Dash Four #include <linux/security.h> 65131ad62dSMr Dash Four #endif 667dfb7103SNigel Cunningham #include <linux/freezer.h> 6734e36d8eSEric W. Biederman #include <linux/pid_namespace.h> 6833faba7fSRichard Guy Briggs #include <net/netns/generic.h> 693dc7e315SDarrel Goeddel 703dc7e315SDarrel Goeddel #include "audit.h" 711da177e4SLinus Torvalds 72a3f07114SEric Paris /* No auditing will take place until audit_initialized == AUDIT_INITIALIZED. 731da177e4SLinus Torvalds * (Initialization happens after skb_init is called.) */ 74a3f07114SEric Paris #define AUDIT_DISABLED -1 75a3f07114SEric Paris #define AUDIT_UNINITIALIZED 0 76a3f07114SEric Paris #define AUDIT_INITIALIZED 1 771da177e4SLinus Torvalds static int audit_initialized; 781da177e4SLinus Torvalds 791a6b9f23SEric Paris #define AUDIT_OFF 0 801a6b9f23SEric Paris #define AUDIT_ON 1 811a6b9f23SEric Paris #define AUDIT_LOCKED 2 823e1d0bb6SJoe Perches u32 audit_enabled; 833e1d0bb6SJoe Perches u32 audit_ever_enabled; 841da177e4SLinus Torvalds 85ae9d67afSJan Engelhardt EXPORT_SYMBOL_GPL(audit_enabled); 86ae9d67afSJan Engelhardt 871da177e4SLinus Torvalds /* Default state when kernel boots without any parameters. */ 883e1d0bb6SJoe Perches static u32 audit_default; 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds /* If auditing cannot proceed, audit_failure selects what happens. */ 913e1d0bb6SJoe Perches static u32 audit_failure = AUDIT_FAIL_PRINTK; 921da177e4SLinus Torvalds 9375c0371aSPavel Emelyanov /* 9475c0371aSPavel Emelyanov * If audit records are to be written to the netlink socket, audit_pid 9515e47304SEric W. Biederman * contains the pid of the auditd process and audit_nlk_portid contains 9615e47304SEric W. Biederman * the portid to use to send netlink messages to that process. 9775c0371aSPavel Emelyanov */ 98c2f0c7c3SSteve Grubb int audit_pid; 99f9441639SRichard Guy Briggs static __u32 audit_nlk_portid; 1001da177e4SLinus Torvalds 101b0dd25a8SRandy Dunlap /* If audit_rate_limit is non-zero, limit the rate of sending audit records 1021da177e4SLinus Torvalds * to that number per second. This prevents DoS attacks, but results in 1031da177e4SLinus Torvalds * audit records being dropped. */ 1043e1d0bb6SJoe Perches static u32 audit_rate_limit; 1051da177e4SLinus Torvalds 10640c0775eSRichard Guy Briggs /* Number of outstanding audit_buffers allowed. 10740c0775eSRichard Guy Briggs * When set to zero, this means unlimited. */ 1083e1d0bb6SJoe Perches static u32 audit_backlog_limit = 64; 109e789e561SRichard Guy Briggs #define AUDIT_BACKLOG_WAIT_TIME (60 * HZ) 1103e1d0bb6SJoe Perches static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; 1111da177e4SLinus Torvalds 112c2f0c7c3SSteve Grubb /* The identity of the user shutting down the audit system. */ 113cca080d9SEric W. Biederman kuid_t audit_sig_uid = INVALID_UID; 114c2f0c7c3SSteve Grubb pid_t audit_sig_pid = -1; 115e1396065SAl Viro u32 audit_sig_sid = 0; 116c2f0c7c3SSteve Grubb 1171da177e4SLinus Torvalds /* Records can be lost in several ways: 1181da177e4SLinus Torvalds 0) [suppressed in audit_alloc] 1191da177e4SLinus Torvalds 1) out of memory in audit_log_start [kmalloc of struct audit_buffer] 1201da177e4SLinus Torvalds 2) out of memory in audit_log_move [alloc_skb] 1211da177e4SLinus Torvalds 3) suppressed due to audit_rate_limit 1221da177e4SLinus Torvalds 4) suppressed due to audit_backlog_limit 1231da177e4SLinus Torvalds */ 1241da177e4SLinus Torvalds static atomic_t audit_lost = ATOMIC_INIT(0); 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds /* The netlink socket. */ 1271da177e4SLinus Torvalds static struct sock *audit_sock; 128c0a8d9b0SRichard Guy Briggs static int audit_net_id; 1291da177e4SLinus Torvalds 130f368c07dSAmy Griffis /* Hash for inode-based rules */ 131f368c07dSAmy Griffis struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; 132f368c07dSAmy Griffis 133b7d11258SDavid Woodhouse /* The audit_freelist is a list of pre-allocated audit buffers (if more 1341da177e4SLinus Torvalds * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of 1351da177e4SLinus Torvalds * being placed on the freelist). */ 1361da177e4SLinus Torvalds static DEFINE_SPINLOCK(audit_freelist_lock); 137b0dd25a8SRandy Dunlap static int audit_freelist_count; 1381da177e4SLinus Torvalds static LIST_HEAD(audit_freelist); 1391da177e4SLinus Torvalds 140c6480207SPaul Moore /* queue msgs to send via kauditd_task */ 141af8b824fSPaul Moore static struct sk_buff_head audit_queue; 142c6480207SPaul Moore /* queue msgs due to temporary unicast send problems */ 143c6480207SPaul Moore static struct sk_buff_head audit_retry_queue; 144c6480207SPaul Moore /* queue msgs waiting for new auditd connection */ 145af8b824fSPaul Moore static struct sk_buff_head audit_hold_queue; 146c6480207SPaul Moore 147c6480207SPaul Moore /* queue servicing thread */ 148b7d11258SDavid Woodhouse static struct task_struct *kauditd_task; 149b7d11258SDavid Woodhouse static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); 150c6480207SPaul Moore 151c6480207SPaul Moore /* waitqueue for callers who are blocked on the audit backlog */ 1529ad9ad38SDavid Woodhouse static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); 1531da177e4SLinus Torvalds 154b0fed402SEric Paris static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION, 155b0fed402SEric Paris .mask = -1, 156b0fed402SEric Paris .features = 0, 157b0fed402SEric Paris .lock = 0,}; 158b0fed402SEric Paris 15921b85c31SEric Paris static char *audit_feature_names[2] = { 160d040e5afSEric Paris "only_unset_loginuid", 16121b85c31SEric Paris "loginuid_immutable", 162b0fed402SEric Paris }; 163b0fed402SEric Paris 164b0fed402SEric Paris 165f368c07dSAmy Griffis /* Serialize requests from userspace. */ 166916d7576SAl Viro DEFINE_MUTEX(audit_cmd_mutex); 1671da177e4SLinus Torvalds 1681da177e4SLinus Torvalds /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting 1691da177e4SLinus Torvalds * audit records. Since printk uses a 1024 byte buffer, this buffer 1701da177e4SLinus Torvalds * should be at least that large. */ 1711da177e4SLinus Torvalds #define AUDIT_BUFSIZ 1024 1721da177e4SLinus Torvalds 1731da177e4SLinus Torvalds /* AUDIT_MAXFREE is the number of empty audit_buffers we keep on the 1741da177e4SLinus Torvalds * audit_freelist. Doing so eliminates many kmalloc/kfree calls. */ 1751da177e4SLinus Torvalds #define AUDIT_MAXFREE (2*NR_CPUS) 1761da177e4SLinus Torvalds 1771da177e4SLinus Torvalds /* The audit_buffer is used when formatting an audit record. The caller 1781da177e4SLinus Torvalds * locks briefly to get the record off the freelist or to allocate the 1791da177e4SLinus Torvalds * buffer, and locks briefly to send the buffer to the netlink layer or 1801da177e4SLinus Torvalds * to place it on a transmit queue. Multiple audit_buffers can be in 1811da177e4SLinus Torvalds * use simultaneously. */ 1821da177e4SLinus Torvalds struct audit_buffer { 1831da177e4SLinus Torvalds struct list_head list; 1848fc6115cSChris Wright struct sk_buff *skb; /* formatted skb ready to send */ 1851da177e4SLinus Torvalds struct audit_context *ctx; /* NULL or associated context */ 1869796fdd8SAl Viro gfp_t gfp_mask; 1871da177e4SLinus Torvalds }; 1881da177e4SLinus Torvalds 189f09ac9dbSEric Paris struct audit_reply { 190f9441639SRichard Guy Briggs __u32 portid; 19148095d99SEric W. Biederman struct net *net; 192f09ac9dbSEric Paris struct sk_buff *skb; 193f09ac9dbSEric Paris }; 194f09ac9dbSEric Paris 195f9441639SRichard Guy Briggs static void audit_set_portid(struct audit_buffer *ab, __u32 portid) 196c0404993SSteve Grubb { 19750397bd1SEric Paris if (ab) { 198b529ccf2SArnaldo Carvalho de Melo struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); 199f9441639SRichard Guy Briggs nlh->nlmsg_pid = portid; 200c0404993SSteve Grubb } 20150397bd1SEric Paris } 202c0404993SSteve Grubb 2038c8570fbSDustin Kirkland void audit_panic(const char *message) 2041da177e4SLinus Torvalds { 205d957f7b7SJoe Perches switch (audit_failure) { 2061da177e4SLinus Torvalds case AUDIT_FAIL_SILENT: 2071da177e4SLinus Torvalds break; 2081da177e4SLinus Torvalds case AUDIT_FAIL_PRINTK: 209320f1b1eSEric Paris if (printk_ratelimit()) 210d957f7b7SJoe Perches pr_err("%s\n", message); 2111da177e4SLinus Torvalds break; 2121da177e4SLinus Torvalds case AUDIT_FAIL_PANIC: 213b29ee87eSEric Paris /* test audit_pid since printk is always losey, why bother? */ 214b29ee87eSEric Paris if (audit_pid) 2151da177e4SLinus Torvalds panic("audit: %s\n", message); 2161da177e4SLinus Torvalds break; 2171da177e4SLinus Torvalds } 2181da177e4SLinus Torvalds } 2191da177e4SLinus Torvalds 2201da177e4SLinus Torvalds static inline int audit_rate_check(void) 2211da177e4SLinus Torvalds { 2221da177e4SLinus Torvalds static unsigned long last_check = 0; 2231da177e4SLinus Torvalds static int messages = 0; 2241da177e4SLinus Torvalds static DEFINE_SPINLOCK(lock); 2251da177e4SLinus Torvalds unsigned long flags; 2261da177e4SLinus Torvalds unsigned long now; 2271da177e4SLinus Torvalds unsigned long elapsed; 2281da177e4SLinus Torvalds int retval = 0; 2291da177e4SLinus Torvalds 2301da177e4SLinus Torvalds if (!audit_rate_limit) return 1; 2311da177e4SLinus Torvalds 2321da177e4SLinus Torvalds spin_lock_irqsave(&lock, flags); 2331da177e4SLinus Torvalds if (++messages < audit_rate_limit) { 2341da177e4SLinus Torvalds retval = 1; 2351da177e4SLinus Torvalds } else { 2361da177e4SLinus Torvalds now = jiffies; 2371da177e4SLinus Torvalds elapsed = now - last_check; 2381da177e4SLinus Torvalds if (elapsed > HZ) { 2391da177e4SLinus Torvalds last_check = now; 2401da177e4SLinus Torvalds messages = 0; 2411da177e4SLinus Torvalds retval = 1; 2421da177e4SLinus Torvalds } 2431da177e4SLinus Torvalds } 2441da177e4SLinus Torvalds spin_unlock_irqrestore(&lock, flags); 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds return retval; 2471da177e4SLinus Torvalds } 2481da177e4SLinus Torvalds 249b0dd25a8SRandy Dunlap /** 250b0dd25a8SRandy Dunlap * audit_log_lost - conditionally log lost audit message event 251b0dd25a8SRandy Dunlap * @message: the message stating reason for lost audit message 252b0dd25a8SRandy Dunlap * 253b0dd25a8SRandy Dunlap * Emit at least 1 message per second, even if audit_rate_check is 254b0dd25a8SRandy Dunlap * throttling. 255b0dd25a8SRandy Dunlap * Always increment the lost messages counter. 256b0dd25a8SRandy Dunlap */ 2571da177e4SLinus Torvalds void audit_log_lost(const char *message) 2581da177e4SLinus Torvalds { 2591da177e4SLinus Torvalds static unsigned long last_msg = 0; 2601da177e4SLinus Torvalds static DEFINE_SPINLOCK(lock); 2611da177e4SLinus Torvalds unsigned long flags; 2621da177e4SLinus Torvalds unsigned long now; 2631da177e4SLinus Torvalds int print; 2641da177e4SLinus Torvalds 2651da177e4SLinus Torvalds atomic_inc(&audit_lost); 2661da177e4SLinus Torvalds 2671da177e4SLinus Torvalds print = (audit_failure == AUDIT_FAIL_PANIC || !audit_rate_limit); 2681da177e4SLinus Torvalds 2691da177e4SLinus Torvalds if (!print) { 2701da177e4SLinus Torvalds spin_lock_irqsave(&lock, flags); 2711da177e4SLinus Torvalds now = jiffies; 2721da177e4SLinus Torvalds if (now - last_msg > HZ) { 2731da177e4SLinus Torvalds print = 1; 2741da177e4SLinus Torvalds last_msg = now; 2751da177e4SLinus Torvalds } 2761da177e4SLinus Torvalds spin_unlock_irqrestore(&lock, flags); 2771da177e4SLinus Torvalds } 2781da177e4SLinus Torvalds 2791da177e4SLinus Torvalds if (print) { 280320f1b1eSEric Paris if (printk_ratelimit()) 2813e1d0bb6SJoe Perches pr_warn("audit_lost=%u audit_rate_limit=%u audit_backlog_limit=%u\n", 2821da177e4SLinus Torvalds atomic_read(&audit_lost), 2831da177e4SLinus Torvalds audit_rate_limit, 2841da177e4SLinus Torvalds audit_backlog_limit); 2851da177e4SLinus Torvalds audit_panic(message); 2861da177e4SLinus Torvalds } 2871da177e4SLinus Torvalds } 2881da177e4SLinus Torvalds 2893e1d0bb6SJoe Perches static int audit_log_config_change(char *function_name, u32 new, u32 old, 2902532386fSEric Paris int allow_changes) 2911da177e4SLinus Torvalds { 2921a6b9f23SEric Paris struct audit_buffer *ab; 2931a6b9f23SEric Paris int rc = 0; 2946a01b07fSSteve Grubb 2951a6b9f23SEric Paris ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); 2960644ec0cSKees Cook if (unlikely(!ab)) 2970644ec0cSKees Cook return rc; 2983e1d0bb6SJoe Perches audit_log_format(ab, "%s=%u old=%u", function_name, new, old); 2994d3fb709SEric Paris audit_log_session_info(ab); 300b122c376SEric Paris rc = audit_log_task_context(ab); 301b122c376SEric Paris if (rc) 3021a6b9f23SEric Paris allow_changes = 0; /* Something weird, deny request */ 3031a6b9f23SEric Paris audit_log_format(ab, " res=%d", allow_changes); 3041a6b9f23SEric Paris audit_log_end(ab); 3051a6b9f23SEric Paris return rc; 3061a6b9f23SEric Paris } 3071a6b9f23SEric Paris 3083e1d0bb6SJoe Perches static int audit_do_config_change(char *function_name, u32 *to_change, u32 new) 3091a6b9f23SEric Paris { 3103e1d0bb6SJoe Perches int allow_changes, rc = 0; 3113e1d0bb6SJoe Perches u32 old = *to_change; 3121a6b9f23SEric Paris 3131a6b9f23SEric Paris /* check if we are locked */ 3141a6b9f23SEric Paris if (audit_enabled == AUDIT_LOCKED) 3151a6b9f23SEric Paris allow_changes = 0; 3161a6b9f23SEric Paris else 3171a6b9f23SEric Paris allow_changes = 1; 3181a6b9f23SEric Paris 3191a6b9f23SEric Paris if (audit_enabled != AUDIT_OFF) { 320dc9eb698SEric Paris rc = audit_log_config_change(function_name, new, old, allow_changes); 3211a6b9f23SEric Paris if (rc) 3221a6b9f23SEric Paris allow_changes = 0; 3231a6b9f23SEric Paris } 3246a01b07fSSteve Grubb 3256a01b07fSSteve Grubb /* If we are allowed, make the change */ 3261a6b9f23SEric Paris if (allow_changes == 1) 3271a6b9f23SEric Paris *to_change = new; 3286a01b07fSSteve Grubb /* Not allowed, update reason */ 3296a01b07fSSteve Grubb else if (rc == 0) 3306a01b07fSSteve Grubb rc = -EPERM; 3316a01b07fSSteve Grubb return rc; 3321da177e4SLinus Torvalds } 3331da177e4SLinus Torvalds 3343e1d0bb6SJoe Perches static int audit_set_rate_limit(u32 limit) 3351a6b9f23SEric Paris { 336dc9eb698SEric Paris return audit_do_config_change("audit_rate_limit", &audit_rate_limit, limit); 3371a6b9f23SEric Paris } 3381a6b9f23SEric Paris 3393e1d0bb6SJoe Perches static int audit_set_backlog_limit(u32 limit) 3401da177e4SLinus Torvalds { 341dc9eb698SEric Paris return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, limit); 3421da177e4SLinus Torvalds } 3431da177e4SLinus Torvalds 3443e1d0bb6SJoe Perches static int audit_set_backlog_wait_time(u32 timeout) 34551cc83f0SRichard Guy Briggs { 34651cc83f0SRichard Guy Briggs return audit_do_config_change("audit_backlog_wait_time", 34731975424SPaul Moore &audit_backlog_wait_time, timeout); 34851cc83f0SRichard Guy Briggs } 34951cc83f0SRichard Guy Briggs 3503e1d0bb6SJoe Perches static int audit_set_enabled(u32 state) 3511da177e4SLinus Torvalds { 352b593d384SEric Paris int rc; 353724e7bfcSPranith Kumar if (state > AUDIT_LOCKED) 3541da177e4SLinus Torvalds return -EINVAL; 355ce29b682SSteve Grubb 356dc9eb698SEric Paris rc = audit_do_config_change("audit_enabled", &audit_enabled, state); 357b593d384SEric Paris if (!rc) 358b593d384SEric Paris audit_ever_enabled |= !!state; 359b593d384SEric Paris 360b593d384SEric Paris return rc; 3611da177e4SLinus Torvalds } 3621da177e4SLinus Torvalds 3633e1d0bb6SJoe Perches static int audit_set_failure(u32 state) 3641da177e4SLinus Torvalds { 3651da177e4SLinus Torvalds if (state != AUDIT_FAIL_SILENT 3661da177e4SLinus Torvalds && state != AUDIT_FAIL_PRINTK 3671da177e4SLinus Torvalds && state != AUDIT_FAIL_PANIC) 3681da177e4SLinus Torvalds return -EINVAL; 369ce29b682SSteve Grubb 370dc9eb698SEric Paris return audit_do_config_change("audit_failure", &audit_failure, state); 3711da177e4SLinus Torvalds } 3721da177e4SLinus Torvalds 373f3d357b0SEric Paris /* 374038cbcf6SEric Paris * For one reason or another this nlh isn't getting delivered to the userspace 375038cbcf6SEric Paris * audit daemon, just send it to printk. 376038cbcf6SEric Paris */ 377af8b824fSPaul Moore static void kauditd_printk_skb(struct sk_buff *skb) 378038cbcf6SEric Paris { 379038cbcf6SEric Paris struct nlmsghdr *nlh = nlmsg_hdr(skb); 380c64e66c6SDavid S. Miller char *data = nlmsg_data(nlh); 381038cbcf6SEric Paris 382038cbcf6SEric Paris if (nlh->nlmsg_type != AUDIT_EOE) { 383038cbcf6SEric Paris if (printk_ratelimit()) 384d957f7b7SJoe Perches pr_notice("type=%d %s\n", nlh->nlmsg_type, data); 385038cbcf6SEric Paris else 386f1283527SJosh Boyer audit_log_lost("printk limit exceeded"); 387038cbcf6SEric Paris } 388038cbcf6SEric Paris } 389038cbcf6SEric Paris 390c6480207SPaul Moore /** 391c6480207SPaul Moore * kauditd_hold_skb - Queue an audit record, waiting for auditd 392c6480207SPaul Moore * @skb: audit record 393c6480207SPaul Moore * 394c6480207SPaul Moore * Description: 395c6480207SPaul Moore * Queue the audit record, waiting for an instance of auditd. When this 396c6480207SPaul Moore * function is called we haven't given up yet on sending the record, but things 397c6480207SPaul Moore * are not looking good. The first thing we want to do is try to write the 398c6480207SPaul Moore * record via printk and then see if we want to try and hold on to the record 399c6480207SPaul Moore * and queue it, if we have room. If we want to hold on to the record, but we 400c6480207SPaul Moore * don't have room, record a record lost message. 401c6480207SPaul Moore */ 402c6480207SPaul Moore static void kauditd_hold_skb(struct sk_buff *skb) 403f3d357b0SEric Paris { 404c6480207SPaul Moore /* at this point it is uncertain if we will ever send this to auditd so 405c6480207SPaul Moore * try to send the message via printk before we go any further */ 406c6480207SPaul Moore kauditd_printk_skb(skb); 40732a1dbaeSRichard Guy Briggs 408c6480207SPaul Moore /* can we just silently drop the message? */ 409c6480207SPaul Moore if (!audit_default) { 410c6480207SPaul Moore kfree_skb(skb); 411c6480207SPaul Moore return; 412c6480207SPaul Moore } 41332a1dbaeSRichard Guy Briggs 414c6480207SPaul Moore /* if we have room, queue the message */ 415c6480207SPaul Moore if (!audit_backlog_limit || 416c6480207SPaul Moore skb_queue_len(&audit_hold_queue) < audit_backlog_limit) { 417c6480207SPaul Moore skb_queue_tail(&audit_hold_queue, skb); 418c6480207SPaul Moore return; 419c6480207SPaul Moore } 420c6480207SPaul Moore 421c6480207SPaul Moore /* we have no other options - drop the message */ 422c6480207SPaul Moore audit_log_lost("kauditd hold queue overflow"); 423c6480207SPaul Moore kfree_skb(skb); 424c6480207SPaul Moore } 425c6480207SPaul Moore 426c6480207SPaul Moore /** 427c6480207SPaul Moore * kauditd_retry_skb - Queue an audit record, attempt to send again to auditd 428c6480207SPaul Moore * @skb: audit record 429c6480207SPaul Moore * 430c6480207SPaul Moore * Description: 431c6480207SPaul Moore * Not as serious as kauditd_hold_skb() as we still have a connected auditd, 432c6480207SPaul Moore * but for some reason we are having problems sending it audit records so 433c6480207SPaul Moore * queue the given record and attempt to resend. 434c6480207SPaul Moore */ 435c6480207SPaul Moore static void kauditd_retry_skb(struct sk_buff *skb) 436c6480207SPaul Moore { 437c6480207SPaul Moore /* NOTE: because records should only live in the retry queue for a 438c6480207SPaul Moore * short period of time, before either being sent or moved to the hold 439c6480207SPaul Moore * queue, we don't currently enforce a limit on this queue */ 440c6480207SPaul Moore skb_queue_tail(&audit_retry_queue, skb); 441c6480207SPaul Moore } 442c6480207SPaul Moore 443c6480207SPaul Moore /** 444c6480207SPaul Moore * auditd_reset - Disconnect the auditd connection 445c6480207SPaul Moore * 446c6480207SPaul Moore * Description: 447c6480207SPaul Moore * Break the auditd/kauditd connection and move all the records in the retry 448*533c7b69SRichard Guy Briggs * queue into the hold queue in case auditd reconnects. The audit_cmd_mutex 449*533c7b69SRichard Guy Briggs * must be held when calling this function. 450c6480207SPaul Moore */ 451c6480207SPaul Moore static void auditd_reset(void) 452c6480207SPaul Moore { 453c6480207SPaul Moore struct sk_buff *skb; 454c6480207SPaul Moore 455c6480207SPaul Moore /* break the connection */ 456*533c7b69SRichard Guy Briggs if (audit_sock) { 457*533c7b69SRichard Guy Briggs sock_put(audit_sock); 45833faba7fSRichard Guy Briggs audit_sock = NULL; 459*533c7b69SRichard Guy Briggs } 460*533c7b69SRichard Guy Briggs audit_pid = 0; 461*533c7b69SRichard Guy Briggs audit_nlk_portid = 0; 462c6480207SPaul Moore 463c6480207SPaul Moore /* flush all of the retry queue to the hold queue */ 464c6480207SPaul Moore while ((skb = skb_dequeue(&audit_retry_queue))) 465c6480207SPaul Moore kauditd_hold_skb(skb); 46632a1dbaeSRichard Guy Briggs } 467c6480207SPaul Moore 468c6480207SPaul Moore /** 469c6480207SPaul Moore * kauditd_send_unicast_skb - Send a record via unicast to auditd 470c6480207SPaul Moore * @skb: audit record 471c6480207SPaul Moore */ 472c6480207SPaul Moore static int kauditd_send_unicast_skb(struct sk_buff *skb) 473c6480207SPaul Moore { 474c6480207SPaul Moore int rc; 475c6480207SPaul Moore 4766c54e789SPaul Moore /* if we know nothing is connected, don't even try the netlink call */ 4776c54e789SPaul Moore if (!audit_pid) 4786c54e789SPaul Moore return -ECONNREFUSED; 4796c54e789SPaul Moore 480c6480207SPaul Moore /* get an extra skb reference in case we fail to send */ 481c6480207SPaul Moore skb_get(skb); 482c6480207SPaul Moore rc = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0); 483c6480207SPaul Moore if (rc >= 0) { 48470d4bf6dSNeil Horman consume_skb(skb); 485c6480207SPaul Moore rc = 0; 486c6480207SPaul Moore } 487c6480207SPaul Moore 488c6480207SPaul Moore return rc; 489f3d357b0SEric Paris } 490f3d357b0SEric Paris 491f3d357b0SEric Paris /* 492c6480207SPaul Moore * kauditd_send_multicast_skb - Send a record to any multicast listeners 493c6480207SPaul Moore * @skb: audit record 494451f9216SRichard Guy Briggs * 495c6480207SPaul Moore * Description: 496451f9216SRichard Guy Briggs * This function doesn't consume an skb as might be expected since it has to 497451f9216SRichard Guy Briggs * copy it anyways. 498451f9216SRichard Guy Briggs */ 499c6480207SPaul Moore static void kauditd_send_multicast_skb(struct sk_buff *skb) 500451f9216SRichard Guy Briggs { 501451f9216SRichard Guy Briggs struct sk_buff *copy; 502451f9216SRichard Guy Briggs struct audit_net *aunet = net_generic(&init_net, audit_net_id); 503451f9216SRichard Guy Briggs struct sock *sock = aunet->nlsk; 504c6480207SPaul Moore struct nlmsghdr *nlh; 505451f9216SRichard Guy Briggs 5067f74ecd7SRichard Guy Briggs if (!netlink_has_listeners(sock, AUDIT_NLGRP_READLOG)) 5077f74ecd7SRichard Guy Briggs return; 5087f74ecd7SRichard Guy Briggs 509451f9216SRichard Guy Briggs /* 510451f9216SRichard Guy Briggs * The seemingly wasteful skb_copy() rather than bumping the refcount 511451f9216SRichard Guy Briggs * using skb_get() is necessary because non-standard mods are made to 512451f9216SRichard Guy Briggs * the skb by the original kaudit unicast socket send routine. The 513451f9216SRichard Guy Briggs * existing auditd daemon assumes this breakage. Fixing this would 514451f9216SRichard Guy Briggs * require co-ordinating a change in the established protocol between 515451f9216SRichard Guy Briggs * the kaudit kernel subsystem and the auditd userspace code. There is 516451f9216SRichard Guy Briggs * no reason for new multicast clients to continue with this 517451f9216SRichard Guy Briggs * non-compliance. 518451f9216SRichard Guy Briggs */ 519c6480207SPaul Moore copy = skb_copy(skb, GFP_KERNEL); 520451f9216SRichard Guy Briggs if (!copy) 521451f9216SRichard Guy Briggs return; 522c6480207SPaul Moore nlh = nlmsg_hdr(copy); 523c6480207SPaul Moore nlh->nlmsg_len = skb->len; 524451f9216SRichard Guy Briggs 525c6480207SPaul Moore nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, GFP_KERNEL); 526451f9216SRichard Guy Briggs } 527451f9216SRichard Guy Briggs 528c6480207SPaul Moore /** 529c6480207SPaul Moore * kauditd_wake_condition - Return true when it is time to wake kauditd_thread 530b551d1d9SRichard Guy Briggs * 531c6480207SPaul Moore * Description: 532c6480207SPaul Moore * This function is for use by the wait_event_freezable() call in 533c6480207SPaul Moore * kauditd_thread(). 534f3d357b0SEric Paris */ 535c6480207SPaul Moore static int kauditd_wake_condition(void) 536b551d1d9SRichard Guy Briggs { 537c6480207SPaul Moore static int pid_last = 0; 538c6480207SPaul Moore int rc; 539c6480207SPaul Moore int pid = audit_pid; 540b551d1d9SRichard Guy Briggs 541c6480207SPaul Moore /* wake on new messages or a change in the connected auditd */ 542c6480207SPaul Moore rc = skb_queue_len(&audit_queue) || (pid && pid != pid_last); 543c6480207SPaul Moore if (rc) 544c6480207SPaul Moore pid_last = pid; 545b551d1d9SRichard Guy Briggs 546c6480207SPaul Moore return rc; 547f3d357b0SEric Paris } 548b551d1d9SRichard Guy Briggs 54997a41e26SAdrian Bunk static int kauditd_thread(void *dummy) 550b7d11258SDavid Woodhouse { 551c6480207SPaul Moore int rc; 552c6480207SPaul Moore int auditd = 0; 553c6480207SPaul Moore int reschedule = 0; 5544aa83872SPaul Moore struct sk_buff *skb; 5554aa83872SPaul Moore struct nlmsghdr *nlh; 5564aa83872SPaul Moore 557c6480207SPaul Moore #define UNICAST_RETRIES 5 558c6480207SPaul Moore #define AUDITD_BAD(x,y) \ 559c6480207SPaul Moore ((x) == -ECONNREFUSED || (x) == -EPERM || ++(y) >= UNICAST_RETRIES) 560c6480207SPaul Moore 561c6480207SPaul Moore /* NOTE: we do invalidate the auditd connection flag on any sending 562c6480207SPaul Moore * errors, but we only "restore" the connection flag at specific places 563c6480207SPaul Moore * in the loop in order to help ensure proper ordering of audit 564c6480207SPaul Moore * records */ 565c6480207SPaul Moore 56683144186SRafael J. Wysocki set_freezable(); 5674899b8b1SAndrew Morton while (!kthread_should_stop()) { 568c6480207SPaul Moore /* NOTE: possible area for future improvement is to look at 569c6480207SPaul Moore * the hold and retry queues, since only this thread 570c6480207SPaul Moore * has access to these queues we might be able to do 571c6480207SPaul Moore * our own queuing and skip some/all of the locking */ 572f3d357b0SEric Paris 573c6480207SPaul Moore /* NOTE: it might be a fun experiment to split the hold and 574c6480207SPaul Moore * retry queue handling to another thread, but the 575c6480207SPaul Moore * synchronization issues and other overhead might kill 576c6480207SPaul Moore * any performance gains */ 577c6480207SPaul Moore 578c6480207SPaul Moore /* attempt to flush the hold queue */ 579c6480207SPaul Moore while (auditd && (skb = skb_dequeue(&audit_hold_queue))) { 580c6480207SPaul Moore rc = kauditd_send_unicast_skb(skb); 581c6480207SPaul Moore if (rc) { 582c6480207SPaul Moore /* requeue to the same spot */ 583c6480207SPaul Moore skb_queue_head(&audit_hold_queue, skb); 584c6480207SPaul Moore 585c6480207SPaul Moore auditd = 0; 586c6480207SPaul Moore if (AUDITD_BAD(rc, reschedule)) { 587*533c7b69SRichard Guy Briggs mutex_lock(&audit_cmd_mutex); 588c6480207SPaul Moore auditd_reset(); 589*533c7b69SRichard Guy Briggs mutex_unlock(&audit_cmd_mutex); 590c6480207SPaul Moore reschedule = 0; 591c6480207SPaul Moore } 592c6480207SPaul Moore } else 593c6480207SPaul Moore /* we were able to send successfully */ 594c6480207SPaul Moore reschedule = 0; 595c6480207SPaul Moore } 596c6480207SPaul Moore 597c6480207SPaul Moore /* attempt to flush the retry queue */ 598c6480207SPaul Moore while (auditd && (skb = skb_dequeue(&audit_retry_queue))) { 599c6480207SPaul Moore rc = kauditd_send_unicast_skb(skb); 600c6480207SPaul Moore if (rc) { 601c6480207SPaul Moore auditd = 0; 602c6480207SPaul Moore if (AUDITD_BAD(rc, reschedule)) { 603c6480207SPaul Moore kauditd_hold_skb(skb); 604*533c7b69SRichard Guy Briggs mutex_lock(&audit_cmd_mutex); 605c6480207SPaul Moore auditd_reset(); 606*533c7b69SRichard Guy Briggs mutex_unlock(&audit_cmd_mutex); 607c6480207SPaul Moore reschedule = 0; 608c6480207SPaul Moore } else 609c6480207SPaul Moore /* temporary problem (we hope), queue 610c6480207SPaul Moore * to the same spot and retry */ 611c6480207SPaul Moore skb_queue_head(&audit_retry_queue, skb); 612c6480207SPaul Moore } else 613c6480207SPaul Moore /* we were able to send successfully */ 614c6480207SPaul Moore reschedule = 0; 615c6480207SPaul Moore } 616c6480207SPaul Moore 617c6480207SPaul Moore /* standard queue processing, try to be as quick as possible */ 618c6480207SPaul Moore quick_loop: 619af8b824fSPaul Moore skb = skb_dequeue(&audit_queue); 620b7d11258SDavid Woodhouse if (skb) { 621c6480207SPaul Moore /* setup the netlink header, see the comments in 622c6480207SPaul Moore * kauditd_send_multicast_skb() for length quirks */ 6234aa83872SPaul Moore nlh = nlmsg_hdr(skb); 624c6480207SPaul Moore nlh->nlmsg_len = skb->len - NLMSG_HDRLEN; 6254aa83872SPaul Moore 626c6480207SPaul Moore /* attempt to send to any multicast listeners */ 627c6480207SPaul Moore kauditd_send_multicast_skb(skb); 6284aa83872SPaul Moore 629c6480207SPaul Moore /* attempt to send to auditd, queue on failure */ 630c6480207SPaul Moore if (auditd) { 631c6480207SPaul Moore rc = kauditd_send_unicast_skb(skb); 632c6480207SPaul Moore if (rc) { 633c6480207SPaul Moore auditd = 0; 634c6480207SPaul Moore if (AUDITD_BAD(rc, reschedule)) { 635*533c7b69SRichard Guy Briggs mutex_lock(&audit_cmd_mutex); 636c6480207SPaul Moore auditd_reset(); 637*533c7b69SRichard Guy Briggs mutex_unlock(&audit_cmd_mutex); 638c6480207SPaul Moore reschedule = 0; 6394aa83872SPaul Moore } 6404aa83872SPaul Moore 641c6480207SPaul Moore /* move to the retry queue */ 642c6480207SPaul Moore kauditd_retry_skb(skb); 643c6480207SPaul Moore } else 644c6480207SPaul Moore /* everything is working so go fast! */ 645c6480207SPaul Moore goto quick_loop; 646c6480207SPaul Moore } else if (reschedule) 647c6480207SPaul Moore /* we are currently having problems, move to 648c6480207SPaul Moore * the retry queue */ 649c6480207SPaul Moore kauditd_retry_skb(skb); 650320f1b1eSEric Paris else 651c6480207SPaul Moore /* dump the message via printk and hold it */ 652c6480207SPaul Moore kauditd_hold_skb(skb); 6534aa83872SPaul Moore } else { 654c6480207SPaul Moore /* we have flushed the backlog so wake everyone */ 6554aa83872SPaul Moore wake_up(&audit_backlog_wait); 656c6480207SPaul Moore 657c6480207SPaul Moore /* if everything is okay with auditd (if present), go 658c6480207SPaul Moore * to sleep until there is something new in the queue 659c6480207SPaul Moore * or we have a change in the connected auditd; 660c6480207SPaul Moore * otherwise simply reschedule to give things a chance 661c6480207SPaul Moore * to recover */ 662c6480207SPaul Moore if (reschedule) { 663c6480207SPaul Moore set_current_state(TASK_INTERRUPTIBLE); 664c6480207SPaul Moore schedule(); 665c6480207SPaul Moore } else 6664aa83872SPaul Moore wait_event_freezable(kauditd_wait, 667c6480207SPaul Moore kauditd_wake_condition()); 668c6480207SPaul Moore 669c6480207SPaul Moore /* update the auditd connection status */ 670c6480207SPaul Moore auditd = (audit_pid ? 1 : 0); 6713320c513SRichard Guy Briggs } 672b7d11258SDavid Woodhouse } 673c6480207SPaul Moore 6744899b8b1SAndrew Morton return 0; 675b7d11258SDavid Woodhouse } 676b7d11258SDavid Woodhouse 6779044e6bcSAl Viro int audit_send_list(void *_dest) 6789044e6bcSAl Viro { 6799044e6bcSAl Viro struct audit_netlink_list *dest = _dest; 6809044e6bcSAl Viro struct sk_buff *skb; 68148095d99SEric W. Biederman struct net *net = dest->net; 68233faba7fSRichard Guy Briggs struct audit_net *aunet = net_generic(net, audit_net_id); 6839044e6bcSAl Viro 6849044e6bcSAl Viro /* wait for parent to finish and send an ACK */ 685f368c07dSAmy Griffis mutex_lock(&audit_cmd_mutex); 686f368c07dSAmy Griffis mutex_unlock(&audit_cmd_mutex); 6879044e6bcSAl Viro 6889044e6bcSAl Viro while ((skb = __skb_dequeue(&dest->q)) != NULL) 68933faba7fSRichard Guy Briggs netlink_unicast(aunet->nlsk, skb, dest->portid, 0); 6909044e6bcSAl Viro 69148095d99SEric W. Biederman put_net(net); 6929044e6bcSAl Viro kfree(dest); 6939044e6bcSAl Viro 6949044e6bcSAl Viro return 0; 6959044e6bcSAl Viro } 6969044e6bcSAl Viro 697f9441639SRichard Guy Briggs struct sk_buff *audit_make_reply(__u32 portid, int seq, int type, int done, 698b8800aa5SStephen Hemminger int multi, const void *payload, int size) 6999044e6bcSAl Viro { 7009044e6bcSAl Viro struct sk_buff *skb; 7019044e6bcSAl Viro struct nlmsghdr *nlh; 7029044e6bcSAl Viro void *data; 7039044e6bcSAl Viro int flags = multi ? NLM_F_MULTI : 0; 7049044e6bcSAl Viro int t = done ? NLMSG_DONE : type; 7059044e6bcSAl Viro 706ee080e6cSEric Paris skb = nlmsg_new(size, GFP_KERNEL); 7079044e6bcSAl Viro if (!skb) 7089044e6bcSAl Viro return NULL; 7099044e6bcSAl Viro 710f9441639SRichard Guy Briggs nlh = nlmsg_put(skb, portid, seq, t, size, flags); 711c64e66c6SDavid S. Miller if (!nlh) 712c64e66c6SDavid S. Miller goto out_kfree_skb; 713c64e66c6SDavid S. Miller data = nlmsg_data(nlh); 7149044e6bcSAl Viro memcpy(data, payload, size); 7159044e6bcSAl Viro return skb; 7169044e6bcSAl Viro 717c64e66c6SDavid S. Miller out_kfree_skb: 7189044e6bcSAl Viro kfree_skb(skb); 7199044e6bcSAl Viro return NULL; 7209044e6bcSAl Viro } 7219044e6bcSAl Viro 722f09ac9dbSEric Paris static int audit_send_reply_thread(void *arg) 723f09ac9dbSEric Paris { 724f09ac9dbSEric Paris struct audit_reply *reply = (struct audit_reply *)arg; 72548095d99SEric W. Biederman struct net *net = reply->net; 72633faba7fSRichard Guy Briggs struct audit_net *aunet = net_generic(net, audit_net_id); 727f09ac9dbSEric Paris 728f09ac9dbSEric Paris mutex_lock(&audit_cmd_mutex); 729f09ac9dbSEric Paris mutex_unlock(&audit_cmd_mutex); 730f09ac9dbSEric Paris 731f09ac9dbSEric Paris /* Ignore failure. It'll only happen if the sender goes away, 732f09ac9dbSEric Paris because our timeout is set to infinite. */ 73333faba7fSRichard Guy Briggs netlink_unicast(aunet->nlsk , reply->skb, reply->portid, 0); 73448095d99SEric W. Biederman put_net(net); 735f09ac9dbSEric Paris kfree(reply); 736f09ac9dbSEric Paris return 0; 737f09ac9dbSEric Paris } 738c6480207SPaul Moore 739b0dd25a8SRandy Dunlap /** 740b0dd25a8SRandy Dunlap * audit_send_reply - send an audit reply message via netlink 741d211f177SEric W. Biederman * @request_skb: skb of request we are replying to (used to target the reply) 742b0dd25a8SRandy Dunlap * @seq: sequence number 743b0dd25a8SRandy Dunlap * @type: audit message type 744b0dd25a8SRandy Dunlap * @done: done (last) flag 745b0dd25a8SRandy Dunlap * @multi: multi-part message flag 746b0dd25a8SRandy Dunlap * @payload: payload data 747b0dd25a8SRandy Dunlap * @size: payload size 748b0dd25a8SRandy Dunlap * 749f9441639SRichard Guy Briggs * Allocates an skb, builds the netlink message, and sends it to the port id. 750b0dd25a8SRandy Dunlap * No failure notifications. 751b0dd25a8SRandy Dunlap */ 7526f285b19SEric W. Biederman static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done, 753f9441639SRichard Guy Briggs int multi, const void *payload, int size) 7541da177e4SLinus Torvalds { 7556f285b19SEric W. Biederman u32 portid = NETLINK_CB(request_skb).portid; 7566f285b19SEric W. Biederman struct net *net = sock_net(NETLINK_CB(request_skb).sk); 7571da177e4SLinus Torvalds struct sk_buff *skb; 758f09ac9dbSEric Paris struct task_struct *tsk; 759f09ac9dbSEric Paris struct audit_reply *reply = kmalloc(sizeof(struct audit_reply), 760f09ac9dbSEric Paris GFP_KERNEL); 761f09ac9dbSEric Paris 762f09ac9dbSEric Paris if (!reply) 763f09ac9dbSEric Paris return; 764f09ac9dbSEric Paris 765f9441639SRichard Guy Briggs skb = audit_make_reply(portid, seq, type, done, multi, payload, size); 7661da177e4SLinus Torvalds if (!skb) 767fcaf1eb8SAndrew Morton goto out; 768f09ac9dbSEric Paris 7696f285b19SEric W. Biederman reply->net = get_net(net); 770f9441639SRichard Guy Briggs reply->portid = portid; 771f09ac9dbSEric Paris reply->skb = skb; 772f09ac9dbSEric Paris 773f09ac9dbSEric Paris tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply"); 774fcaf1eb8SAndrew Morton if (!IS_ERR(tsk)) 775fcaf1eb8SAndrew Morton return; 776f09ac9dbSEric Paris kfree_skb(skb); 777fcaf1eb8SAndrew Morton out: 778fcaf1eb8SAndrew Morton kfree(reply); 7791da177e4SLinus Torvalds } 7801da177e4SLinus Torvalds 7811da177e4SLinus Torvalds /* 7821da177e4SLinus Torvalds * Check for appropriate CAP_AUDIT_ capabilities on incoming audit 7831da177e4SLinus Torvalds * control messages. 7841da177e4SLinus Torvalds */ 785c7bdb545SDarrel Goeddel static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) 7861da177e4SLinus Torvalds { 7871da177e4SLinus Torvalds int err = 0; 7881da177e4SLinus Torvalds 7895a3cb3b6SRichard Guy Briggs /* Only support initial user namespace for now. */ 790aa4af831SEric Paris /* 791aa4af831SEric Paris * We return ECONNREFUSED because it tricks userspace into thinking 792aa4af831SEric Paris * that audit was not configured into the kernel. Lots of users 793aa4af831SEric Paris * configure their PAM stack (because that's what the distro does) 794aa4af831SEric Paris * to reject login if unable to send messages to audit. If we return 795aa4af831SEric Paris * ECONNREFUSED the PAM stack thinks the kernel does not have audit 796aa4af831SEric Paris * configured in and will let login proceed. If we return EPERM 797aa4af831SEric Paris * userspace will reject all logins. This should be removed when we 798aa4af831SEric Paris * support non init namespaces!! 799aa4af831SEric Paris */ 8000b747172SLinus Torvalds if (current_user_ns() != &init_user_ns) 801aa4af831SEric Paris return -ECONNREFUSED; 80234e36d8eSEric W. Biederman 8031da177e4SLinus Torvalds switch (msg_type) { 8041da177e4SLinus Torvalds case AUDIT_LIST: 8051da177e4SLinus Torvalds case AUDIT_ADD: 8061da177e4SLinus Torvalds case AUDIT_DEL: 80718900909SEric Paris return -EOPNOTSUPP; 80818900909SEric Paris case AUDIT_GET: 80918900909SEric Paris case AUDIT_SET: 810b0fed402SEric Paris case AUDIT_GET_FEATURE: 811b0fed402SEric Paris case AUDIT_SET_FEATURE: 81218900909SEric Paris case AUDIT_LIST_RULES: 81318900909SEric Paris case AUDIT_ADD_RULE: 81493315ed6SAmy Griffis case AUDIT_DEL_RULE: 815c2f0c7c3SSteve Grubb case AUDIT_SIGNAL_INFO: 816522ed776SMiloslav Trmac case AUDIT_TTY_GET: 817522ed776SMiloslav Trmac case AUDIT_TTY_SET: 81874c3cbe3SAl Viro case AUDIT_TRIM: 81974c3cbe3SAl Viro case AUDIT_MAKE_EQUIV: 8205a3cb3b6SRichard Guy Briggs /* Only support auditd and auditctl in initial pid namespace 8215a3cb3b6SRichard Guy Briggs * for now. */ 8225985de67SAmeen Ali if (task_active_pid_ns(current) != &init_pid_ns) 8235a3cb3b6SRichard Guy Briggs return -EPERM; 8245a3cb3b6SRichard Guy Briggs 82590f62cf3SEric W. Biederman if (!netlink_capable(skb, CAP_AUDIT_CONTROL)) 8261da177e4SLinus Torvalds err = -EPERM; 8271da177e4SLinus Torvalds break; 82805474106SSteve Grubb case AUDIT_USER: 829209aba03SDavid Woodhouse case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: 83090d526c0SSteve Grubb case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: 83190f62cf3SEric W. Biederman if (!netlink_capable(skb, CAP_AUDIT_WRITE)) 8321da177e4SLinus Torvalds err = -EPERM; 8331da177e4SLinus Torvalds break; 8341da177e4SLinus Torvalds default: /* bad msg */ 8351da177e4SLinus Torvalds err = -EINVAL; 8361da177e4SLinus Torvalds } 8371da177e4SLinus Torvalds 8381da177e4SLinus Torvalds return err; 8391da177e4SLinus Torvalds } 8401da177e4SLinus Torvalds 841233a6866SPaul Moore static void audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type) 84250397bd1SEric Paris { 843dc9eb698SEric Paris uid_t uid = from_kuid(&init_user_ns, current_uid()); 844f1dc4867SRichard Guy Briggs pid_t pid = task_tgid_nr(current); 84550397bd1SEric Paris 8460868a5e1STyler Hicks if (!audit_enabled && msg_type != AUDIT_USER_AVC) { 84750397bd1SEric Paris *ab = NULL; 848233a6866SPaul Moore return; 84950397bd1SEric Paris } 85050397bd1SEric Paris 85150397bd1SEric Paris *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); 8520644ec0cSKees Cook if (unlikely(!*ab)) 853233a6866SPaul Moore return; 854f1dc4867SRichard Guy Briggs audit_log_format(*ab, "pid=%d uid=%u", pid, uid); 8554d3fb709SEric Paris audit_log_session_info(*ab); 856b122c376SEric Paris audit_log_task_context(*ab); 85750397bd1SEric Paris } 85850397bd1SEric Paris 859b0fed402SEric Paris int is_audit_feature_set(int i) 860b0fed402SEric Paris { 861b0fed402SEric Paris return af.features & AUDIT_FEATURE_TO_MASK(i); 862b0fed402SEric Paris } 863b0fed402SEric Paris 864b0fed402SEric Paris 865b0fed402SEric Paris static int audit_get_feature(struct sk_buff *skb) 866b0fed402SEric Paris { 867b0fed402SEric Paris u32 seq; 868b0fed402SEric Paris 869b0fed402SEric Paris seq = nlmsg_hdr(skb)->nlmsg_seq; 870b0fed402SEric Paris 8719ef91514SRichard Guy Briggs audit_send_reply(skb, seq, AUDIT_GET_FEATURE, 0, 0, &af, sizeof(af)); 872b0fed402SEric Paris 873b0fed402SEric Paris return 0; 874b0fed402SEric Paris } 875b0fed402SEric Paris 876b0fed402SEric Paris static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature, 877b0fed402SEric Paris u32 old_lock, u32 new_lock, int res) 878b0fed402SEric Paris { 879b0fed402SEric Paris struct audit_buffer *ab; 880b0fed402SEric Paris 881b6c50fe0SGao feng if (audit_enabled == AUDIT_OFF) 882b6c50fe0SGao feng return; 883b6c50fe0SGao feng 884b0fed402SEric Paris ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE); 885ad2ac263SRichard Guy Briggs audit_log_task_info(ab, current); 8863e1d0bb6SJoe Perches audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", 887b0fed402SEric Paris audit_feature_names[which], !!old_feature, !!new_feature, 888b0fed402SEric Paris !!old_lock, !!new_lock, res); 889b0fed402SEric Paris audit_log_end(ab); 890b0fed402SEric Paris } 891b0fed402SEric Paris 892b0fed402SEric Paris static int audit_set_feature(struct sk_buff *skb) 893b0fed402SEric Paris { 894b0fed402SEric Paris struct audit_features *uaf; 895b0fed402SEric Paris int i; 896b0fed402SEric Paris 8976eed9b26SFabian Frederick BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > ARRAY_SIZE(audit_feature_names)); 898b0fed402SEric Paris uaf = nlmsg_data(nlmsg_hdr(skb)); 899b0fed402SEric Paris 900b0fed402SEric Paris /* if there is ever a version 2 we should handle that here */ 901b0fed402SEric Paris 902b0fed402SEric Paris for (i = 0; i <= AUDIT_LAST_FEATURE; i++) { 903b0fed402SEric Paris u32 feature = AUDIT_FEATURE_TO_MASK(i); 904b0fed402SEric Paris u32 old_feature, new_feature, old_lock, new_lock; 905b0fed402SEric Paris 906b0fed402SEric Paris /* if we are not changing this feature, move along */ 907b0fed402SEric Paris if (!(feature & uaf->mask)) 908b0fed402SEric Paris continue; 909b0fed402SEric Paris 910b0fed402SEric Paris old_feature = af.features & feature; 911b0fed402SEric Paris new_feature = uaf->features & feature; 912b0fed402SEric Paris new_lock = (uaf->lock | af.lock) & feature; 913b0fed402SEric Paris old_lock = af.lock & feature; 914b0fed402SEric Paris 915b0fed402SEric Paris /* are we changing a locked feature? */ 9164547b3bcSGao feng if (old_lock && (new_feature != old_feature)) { 917b0fed402SEric Paris audit_log_feature_change(i, old_feature, new_feature, 918b0fed402SEric Paris old_lock, new_lock, 0); 919b0fed402SEric Paris return -EPERM; 920b0fed402SEric Paris } 921b0fed402SEric Paris } 922b0fed402SEric Paris /* nothing invalid, do the changes */ 923b0fed402SEric Paris for (i = 0; i <= AUDIT_LAST_FEATURE; i++) { 924b0fed402SEric Paris u32 feature = AUDIT_FEATURE_TO_MASK(i); 925b0fed402SEric Paris u32 old_feature, new_feature, old_lock, new_lock; 926b0fed402SEric Paris 927b0fed402SEric Paris /* if we are not changing this feature, move along */ 928b0fed402SEric Paris if (!(feature & uaf->mask)) 929b0fed402SEric Paris continue; 930b0fed402SEric Paris 931b0fed402SEric Paris old_feature = af.features & feature; 932b0fed402SEric Paris new_feature = uaf->features & feature; 933b0fed402SEric Paris old_lock = af.lock & feature; 934b0fed402SEric Paris new_lock = (uaf->lock | af.lock) & feature; 935b0fed402SEric Paris 936b0fed402SEric Paris if (new_feature != old_feature) 937b0fed402SEric Paris audit_log_feature_change(i, old_feature, new_feature, 938b0fed402SEric Paris old_lock, new_lock, 1); 939b0fed402SEric Paris 940b0fed402SEric Paris if (new_feature) 941b0fed402SEric Paris af.features |= feature; 942b0fed402SEric Paris else 943b0fed402SEric Paris af.features &= ~feature; 944b0fed402SEric Paris af.lock |= new_lock; 945b0fed402SEric Paris } 946b0fed402SEric Paris 947b0fed402SEric Paris return 0; 948b0fed402SEric Paris } 949b0fed402SEric Paris 950133e1e5aSRichard Guy Briggs static int audit_replace(pid_t pid) 951133e1e5aSRichard Guy Briggs { 952133e1e5aSRichard Guy Briggs struct sk_buff *skb = audit_make_reply(0, 0, AUDIT_REPLACE, 0, 0, 953133e1e5aSRichard Guy Briggs &pid, sizeof(pid)); 954133e1e5aSRichard Guy Briggs 955133e1e5aSRichard Guy Briggs if (!skb) 956133e1e5aSRichard Guy Briggs return -ENOMEM; 957133e1e5aSRichard Guy Briggs return netlink_unicast(audit_sock, skb, audit_nlk_portid, 0); 958133e1e5aSRichard Guy Briggs } 959133e1e5aSRichard Guy Briggs 9601da177e4SLinus Torvalds static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) 9611da177e4SLinus Torvalds { 962dc9eb698SEric Paris u32 seq; 9631da177e4SLinus Torvalds void *data; 9641da177e4SLinus Torvalds int err; 965c0404993SSteve Grubb struct audit_buffer *ab; 9661da177e4SLinus Torvalds u16 msg_type = nlh->nlmsg_type; 967e1396065SAl Viro struct audit_sig_info *sig_data; 96850397bd1SEric Paris char *ctx = NULL; 969e1396065SAl Viro u32 len; 9701da177e4SLinus Torvalds 971c7bdb545SDarrel Goeddel err = audit_netlink_ok(skb, msg_type); 9721da177e4SLinus Torvalds if (err) 9731da177e4SLinus Torvalds return err; 9741da177e4SLinus Torvalds 9751da177e4SLinus Torvalds seq = nlh->nlmsg_seq; 976c64e66c6SDavid S. Miller data = nlmsg_data(nlh); 9771da177e4SLinus Torvalds 9781da177e4SLinus Torvalds switch (msg_type) { 97909f883a9SRichard Guy Briggs case AUDIT_GET: { 98009f883a9SRichard Guy Briggs struct audit_status s; 98109f883a9SRichard Guy Briggs memset(&s, 0, sizeof(s)); 98209f883a9SRichard Guy Briggs s.enabled = audit_enabled; 98309f883a9SRichard Guy Briggs s.failure = audit_failure; 98409f883a9SRichard Guy Briggs s.pid = audit_pid; 98509f883a9SRichard Guy Briggs s.rate_limit = audit_rate_limit; 98609f883a9SRichard Guy Briggs s.backlog_limit = audit_backlog_limit; 98709f883a9SRichard Guy Briggs s.lost = atomic_read(&audit_lost); 988af8b824fSPaul Moore s.backlog = skb_queue_len(&audit_queue); 9890288d718SRichard Guy Briggs s.feature_bitmap = AUDIT_FEATURE_BITMAP_ALL; 99031975424SPaul Moore s.backlog_wait_time = audit_backlog_wait_time; 9916f285b19SEric W. Biederman audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s)); 9921da177e4SLinus Torvalds break; 99309f883a9SRichard Guy Briggs } 99409f883a9SRichard Guy Briggs case AUDIT_SET: { 99509f883a9SRichard Guy Briggs struct audit_status s; 99609f883a9SRichard Guy Briggs memset(&s, 0, sizeof(s)); 99709f883a9SRichard Guy Briggs /* guard against past and future API changes */ 99809f883a9SRichard Guy Briggs memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); 99909f883a9SRichard Guy Briggs if (s.mask & AUDIT_STATUS_ENABLED) { 100009f883a9SRichard Guy Briggs err = audit_set_enabled(s.enabled); 100120c6aaa3Szhangxiliang if (err < 0) 100220c6aaa3Szhangxiliang return err; 10031da177e4SLinus Torvalds } 100409f883a9SRichard Guy Briggs if (s.mask & AUDIT_STATUS_FAILURE) { 100509f883a9SRichard Guy Briggs err = audit_set_failure(s.failure); 100620c6aaa3Szhangxiliang if (err < 0) 100720c6aaa3Szhangxiliang return err; 10081da177e4SLinus Torvalds } 100909f883a9SRichard Guy Briggs if (s.mask & AUDIT_STATUS_PID) { 101009f883a9SRichard Guy Briggs int new_pid = s.pid; 1011133e1e5aSRichard Guy Briggs pid_t requesting_pid = task_tgid_vnr(current); 10121a6b9f23SEric Paris 1013935c9e7fSRichard Guy Briggs if ((!new_pid) && (requesting_pid != audit_pid)) { 1014935c9e7fSRichard Guy Briggs audit_log_config_change("audit_pid", new_pid, audit_pid, 0); 101534eab0a7SRichard Guy Briggs return -EACCES; 1016935c9e7fSRichard Guy Briggs } 1017133e1e5aSRichard Guy Briggs if (audit_pid && new_pid && 1018935c9e7fSRichard Guy Briggs audit_replace(requesting_pid) != -ECONNREFUSED) { 1019935c9e7fSRichard Guy Briggs audit_log_config_change("audit_pid", new_pid, audit_pid, 0); 1020133e1e5aSRichard Guy Briggs return -EEXIST; 1021935c9e7fSRichard Guy Briggs } 10221a6b9f23SEric Paris if (audit_enabled != AUDIT_OFF) 1023dc9eb698SEric Paris audit_log_config_change("audit_pid", new_pid, audit_pid, 1); 1024*533c7b69SRichard Guy Briggs if (new_pid) { 1025*533c7b69SRichard Guy Briggs if (audit_sock) 1026*533c7b69SRichard Guy Briggs sock_put(audit_sock); 10271a6b9f23SEric Paris audit_pid = new_pid; 102815e47304SEric W. Biederman audit_nlk_portid = NETLINK_CB(skb).portid; 1029*533c7b69SRichard Guy Briggs sock_hold(skb->sk); 1030de92fc97SGao feng audit_sock = skb->sk; 1031*533c7b69SRichard Guy Briggs } else { 10326c54e789SPaul Moore auditd_reset(); 1033*533c7b69SRichard Guy Briggs } 1034e1d16621SPaul Moore wake_up_interruptible(&kauditd_wait); 10351da177e4SLinus Torvalds } 103609f883a9SRichard Guy Briggs if (s.mask & AUDIT_STATUS_RATE_LIMIT) { 103709f883a9SRichard Guy Briggs err = audit_set_rate_limit(s.rate_limit); 103820c6aaa3Szhangxiliang if (err < 0) 103920c6aaa3Szhangxiliang return err; 104020c6aaa3Szhangxiliang } 104151cc83f0SRichard Guy Briggs if (s.mask & AUDIT_STATUS_BACKLOG_LIMIT) { 104209f883a9SRichard Guy Briggs err = audit_set_backlog_limit(s.backlog_limit); 104351cc83f0SRichard Guy Briggs if (err < 0) 104451cc83f0SRichard Guy Briggs return err; 104551cc83f0SRichard Guy Briggs } 104651cc83f0SRichard Guy Briggs if (s.mask & AUDIT_STATUS_BACKLOG_WAIT_TIME) { 104751cc83f0SRichard Guy Briggs if (sizeof(s) > (size_t)nlh->nlmsg_len) 104851cc83f0SRichard Guy Briggs return -EINVAL; 1049724e7bfcSPranith Kumar if (s.backlog_wait_time > 10*AUDIT_BACKLOG_WAIT_TIME) 105051cc83f0SRichard Guy Briggs return -EINVAL; 105151cc83f0SRichard Guy Briggs err = audit_set_backlog_wait_time(s.backlog_wait_time); 105251cc83f0SRichard Guy Briggs if (err < 0) 105351cc83f0SRichard Guy Briggs return err; 105451cc83f0SRichard Guy Briggs } 10551da177e4SLinus Torvalds break; 105609f883a9SRichard Guy Briggs } 1057b0fed402SEric Paris case AUDIT_GET_FEATURE: 1058b0fed402SEric Paris err = audit_get_feature(skb); 1059b0fed402SEric Paris if (err) 1060b0fed402SEric Paris return err; 1061b0fed402SEric Paris break; 1062b0fed402SEric Paris case AUDIT_SET_FEATURE: 1063b0fed402SEric Paris err = audit_set_feature(skb); 1064b0fed402SEric Paris if (err) 1065b0fed402SEric Paris return err; 1066b0fed402SEric Paris break; 106705474106SSteve Grubb case AUDIT_USER: 1068209aba03SDavid Woodhouse case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: 106990d526c0SSteve Grubb case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: 10704a4cd633SDavid Woodhouse if (!audit_enabled && msg_type != AUDIT_USER_AVC) 10714a4cd633SDavid Woodhouse return 0; 10720f45aa18SDavid Woodhouse 107386b2efbeSRichard Guy Briggs err = audit_filter(msg_type, AUDIT_FILTER_USER); 1074724e4fccSRichard Guy Briggs if (err == 1) { /* match or error */ 10754a4cd633SDavid Woodhouse err = 0; 1076522ed776SMiloslav Trmac if (msg_type == AUDIT_USER_TTY) { 107737282a77SPeter Hurley err = tty_audit_push(); 1078522ed776SMiloslav Trmac if (err) 1079522ed776SMiloslav Trmac break; 1080522ed776SMiloslav Trmac } 10811b7b533fSRichard Guy Briggs mutex_unlock(&audit_cmd_mutex); 1082dc9eb698SEric Paris audit_log_common_recv_msg(&ab, msg_type); 1083522ed776SMiloslav Trmac if (msg_type != AUDIT_USER_TTY) 1084b50eba7eSRichard Guy Briggs audit_log_format(ab, " msg='%.*s'", 1085b50eba7eSRichard Guy Briggs AUDIT_MESSAGE_TEXT_MAX, 1086e7c34970SSteve Grubb (char *)data); 1087522ed776SMiloslav Trmac else { 1088522ed776SMiloslav Trmac int size; 1089522ed776SMiloslav Trmac 1090f7616102SEric Paris audit_log_format(ab, " data="); 1091522ed776SMiloslav Trmac size = nlmsg_len(nlh); 109255ad2f8dSMiloslav Trmac if (size > 0 && 109355ad2f8dSMiloslav Trmac ((unsigned char *)data)[size - 1] == '\0') 109455ad2f8dSMiloslav Trmac size--; 1095b556f8adSEric Paris audit_log_n_untrustedstring(ab, data, size); 1096522ed776SMiloslav Trmac } 1097f9441639SRichard Guy Briggs audit_set_portid(ab, NETLINK_CB(skb).portid); 1098c0404993SSteve Grubb audit_log_end(ab); 10991b7b533fSRichard Guy Briggs mutex_lock(&audit_cmd_mutex); 11000f45aa18SDavid Woodhouse } 11011da177e4SLinus Torvalds break; 110293315ed6SAmy Griffis case AUDIT_ADD_RULE: 110393315ed6SAmy Griffis case AUDIT_DEL_RULE: 110493315ed6SAmy Griffis if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) 110593315ed6SAmy Griffis return -EINVAL; 11061a6b9f23SEric Paris if (audit_enabled == AUDIT_LOCKED) { 1107dc9eb698SEric Paris audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); 1108dc9eb698SEric Paris audit_log_format(ab, " audit_enabled=%d res=0", audit_enabled); 11096a01b07fSSteve Grubb audit_log_end(ab); 11106a01b07fSSteve Grubb return -EPERM; 11116a01b07fSSteve Grubb } 1112ce0d9f04SRichard Guy Briggs err = audit_rule_change(msg_type, NETLINK_CB(skb).portid, 1113dc9eb698SEric Paris seq, data, nlmsg_len(nlh)); 11141da177e4SLinus Torvalds break; 1115ce0d9f04SRichard Guy Briggs case AUDIT_LIST_RULES: 11166f285b19SEric W. Biederman err = audit_list_rules_send(skb, seq); 1117ce0d9f04SRichard Guy Briggs break; 111874c3cbe3SAl Viro case AUDIT_TRIM: 111974c3cbe3SAl Viro audit_trim_trees(); 1120dc9eb698SEric Paris audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); 112174c3cbe3SAl Viro audit_log_format(ab, " op=trim res=1"); 112274c3cbe3SAl Viro audit_log_end(ab); 112374c3cbe3SAl Viro break; 112474c3cbe3SAl Viro case AUDIT_MAKE_EQUIV: { 112574c3cbe3SAl Viro void *bufp = data; 112674c3cbe3SAl Viro u32 sizes[2]; 11277719e437SHarvey Harrison size_t msglen = nlmsg_len(nlh); 112874c3cbe3SAl Viro char *old, *new; 112974c3cbe3SAl Viro 113074c3cbe3SAl Viro err = -EINVAL; 11317719e437SHarvey Harrison if (msglen < 2 * sizeof(u32)) 113274c3cbe3SAl Viro break; 113374c3cbe3SAl Viro memcpy(sizes, bufp, 2 * sizeof(u32)); 113474c3cbe3SAl Viro bufp += 2 * sizeof(u32); 11357719e437SHarvey Harrison msglen -= 2 * sizeof(u32); 11367719e437SHarvey Harrison old = audit_unpack_string(&bufp, &msglen, sizes[0]); 113774c3cbe3SAl Viro if (IS_ERR(old)) { 113874c3cbe3SAl Viro err = PTR_ERR(old); 113974c3cbe3SAl Viro break; 114074c3cbe3SAl Viro } 11417719e437SHarvey Harrison new = audit_unpack_string(&bufp, &msglen, sizes[1]); 114274c3cbe3SAl Viro if (IS_ERR(new)) { 114374c3cbe3SAl Viro err = PTR_ERR(new); 114474c3cbe3SAl Viro kfree(old); 114574c3cbe3SAl Viro break; 114674c3cbe3SAl Viro } 114774c3cbe3SAl Viro /* OK, here comes... */ 114874c3cbe3SAl Viro err = audit_tag_tree(old, new); 114974c3cbe3SAl Viro 1150dc9eb698SEric Paris audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); 115150397bd1SEric Paris 115274c3cbe3SAl Viro audit_log_format(ab, " op=make_equiv old="); 115374c3cbe3SAl Viro audit_log_untrustedstring(ab, old); 115474c3cbe3SAl Viro audit_log_format(ab, " new="); 115574c3cbe3SAl Viro audit_log_untrustedstring(ab, new); 115674c3cbe3SAl Viro audit_log_format(ab, " res=%d", !err); 115774c3cbe3SAl Viro audit_log_end(ab); 115874c3cbe3SAl Viro kfree(old); 115974c3cbe3SAl Viro kfree(new); 116074c3cbe3SAl Viro break; 116174c3cbe3SAl Viro } 1162c2f0c7c3SSteve Grubb case AUDIT_SIGNAL_INFO: 1163939cbf26SEric Paris len = 0; 1164939cbf26SEric Paris if (audit_sig_sid) { 11652a862b32SAhmed S. Darwish err = security_secid_to_secctx(audit_sig_sid, &ctx, &len); 1166e1396065SAl Viro if (err) 1167e1396065SAl Viro return err; 1168939cbf26SEric Paris } 1169e1396065SAl Viro sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); 1170e1396065SAl Viro if (!sig_data) { 1171939cbf26SEric Paris if (audit_sig_sid) 11722a862b32SAhmed S. Darwish security_release_secctx(ctx, len); 1173e1396065SAl Viro return -ENOMEM; 1174e1396065SAl Viro } 1175cca080d9SEric W. Biederman sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid); 1176e1396065SAl Viro sig_data->pid = audit_sig_pid; 1177939cbf26SEric Paris if (audit_sig_sid) { 1178e1396065SAl Viro memcpy(sig_data->ctx, ctx, len); 11792a862b32SAhmed S. Darwish security_release_secctx(ctx, len); 1180939cbf26SEric Paris } 11816f285b19SEric W. Biederman audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, 11826f285b19SEric W. Biederman sig_data, sizeof(*sig_data) + len); 1183e1396065SAl Viro kfree(sig_data); 1184c2f0c7c3SSteve Grubb break; 1185522ed776SMiloslav Trmac case AUDIT_TTY_GET: { 1186522ed776SMiloslav Trmac struct audit_tty_status s; 11872e28d38aSPeter Hurley unsigned int t; 1188522ed776SMiloslav Trmac 11892e28d38aSPeter Hurley t = READ_ONCE(current->signal->audit_tty); 11902e28d38aSPeter Hurley s.enabled = t & AUDIT_TTY_ENABLE; 11912e28d38aSPeter Hurley s.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD); 119220703205SThomas Gleixner 11936f285b19SEric W. Biederman audit_send_reply(skb, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); 1194522ed776SMiloslav Trmac break; 1195522ed776SMiloslav Trmac } 1196522ed776SMiloslav Trmac case AUDIT_TTY_SET: { 1197a06e56b2SRichard Guy Briggs struct audit_tty_status s, old; 1198a06e56b2SRichard Guy Briggs struct audit_buffer *ab; 11992e28d38aSPeter Hurley unsigned int t; 1200522ed776SMiloslav Trmac 120146e959eaSRichard Guy Briggs memset(&s, 0, sizeof(s)); 120246e959eaSRichard Guy Briggs /* guard against past and future API changes */ 12034d8fe737SMathias Krause memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); 12040e23baccSEric Paris /* check if new data is valid */ 12050e23baccSEric Paris if ((s.enabled != 0 && s.enabled != 1) || 12060e23baccSEric Paris (s.log_passwd != 0 && s.log_passwd != 1)) 12070e23baccSEric Paris err = -EINVAL; 12080e23baccSEric Paris 12092e28d38aSPeter Hurley if (err) 12102e28d38aSPeter Hurley t = READ_ONCE(current->signal->audit_tty); 12112e28d38aSPeter Hurley else { 12122e28d38aSPeter Hurley t = s.enabled | (-s.log_passwd & AUDIT_TTY_LOG_PASSWD); 12132e28d38aSPeter Hurley t = xchg(¤t->signal->audit_tty, t); 12140e23baccSEric Paris } 12152e28d38aSPeter Hurley old.enabled = t & AUDIT_TTY_ENABLE; 12162e28d38aSPeter Hurley old.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD); 12170e23baccSEric Paris 1218a06e56b2SRichard Guy Briggs audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); 12191ce319f1SEric Paris audit_log_format(ab, " op=tty_set old-enabled=%d new-enabled=%d" 12201ce319f1SEric Paris " old-log_passwd=%d new-log_passwd=%d res=%d", 12211ce319f1SEric Paris old.enabled, s.enabled, old.log_passwd, 12221ce319f1SEric Paris s.log_passwd, !err); 1223a06e56b2SRichard Guy Briggs audit_log_end(ab); 1224522ed776SMiloslav Trmac break; 1225522ed776SMiloslav Trmac } 12261da177e4SLinus Torvalds default: 12271da177e4SLinus Torvalds err = -EINVAL; 12281da177e4SLinus Torvalds break; 12291da177e4SLinus Torvalds } 12301da177e4SLinus Torvalds 12311da177e4SLinus Torvalds return err < 0 ? err : 0; 12321da177e4SLinus Torvalds } 12331da177e4SLinus Torvalds 1234b0dd25a8SRandy Dunlap /* 1235ea7ae60bSEric Paris * Get message from skb. Each message is processed by audit_receive_msg. 1236ea7ae60bSEric Paris * Malformed skbs with wrong length are discarded silently. 1237b0dd25a8SRandy Dunlap */ 12382a0a6ebeSHerbert Xu static void audit_receive_skb(struct sk_buff *skb) 12391da177e4SLinus Torvalds { 12401da177e4SLinus Torvalds struct nlmsghdr *nlh; 1241ea7ae60bSEric Paris /* 124294191213SHong zhi guo * len MUST be signed for nlmsg_next to be able to dec it below 0 1243ea7ae60bSEric Paris * if the nlmsg_len was not aligned 1244ea7ae60bSEric Paris */ 1245ea7ae60bSEric Paris int len; 1246ea7ae60bSEric Paris int err; 12471da177e4SLinus Torvalds 1248b529ccf2SArnaldo Carvalho de Melo nlh = nlmsg_hdr(skb); 1249ea7ae60bSEric Paris len = skb->len; 1250ea7ae60bSEric Paris 125194191213SHong zhi guo while (nlmsg_ok(nlh, len)) { 1252ea7ae60bSEric Paris err = audit_receive_msg(skb, nlh); 1253ea7ae60bSEric Paris /* if err or if this message says it wants a response */ 1254ea7ae60bSEric Paris if (err || (nlh->nlmsg_flags & NLM_F_ACK)) 12551da177e4SLinus Torvalds netlink_ack(skb, nlh, err); 1256ea7ae60bSEric Paris 12572851da57SAlexandru Copot nlh = nlmsg_next(nlh, &len); 12581da177e4SLinus Torvalds } 12591da177e4SLinus Torvalds } 12601da177e4SLinus Torvalds 12611da177e4SLinus Torvalds /* Receive messages from netlink socket. */ 1262cd40b7d3SDenis V. Lunev static void audit_receive(struct sk_buff *skb) 12631da177e4SLinus Torvalds { 1264f368c07dSAmy Griffis mutex_lock(&audit_cmd_mutex); 12652a0a6ebeSHerbert Xu audit_receive_skb(skb); 1266f368c07dSAmy Griffis mutex_unlock(&audit_cmd_mutex); 12671da177e4SLinus Torvalds } 12681da177e4SLinus Torvalds 12693a101b8dSRichard Guy Briggs /* Run custom bind function on netlink socket group connect or bind requests. */ 1270023e2cfaSJohannes Berg static int audit_bind(struct net *net, int group) 12713a101b8dSRichard Guy Briggs { 12723a101b8dSRichard Guy Briggs if (!capable(CAP_AUDIT_READ)) 12733a101b8dSRichard Guy Briggs return -EPERM; 12743a101b8dSRichard Guy Briggs 12753a101b8dSRichard Guy Briggs return 0; 12763a101b8dSRichard Guy Briggs } 12773a101b8dSRichard Guy Briggs 127833faba7fSRichard Guy Briggs static int __net_init audit_net_init(struct net *net) 12791da177e4SLinus Torvalds { 1280a31f2d17SPablo Neira Ayuso struct netlink_kernel_cfg cfg = { 1281a31f2d17SPablo Neira Ayuso .input = audit_receive, 12823a101b8dSRichard Guy Briggs .bind = audit_bind, 1283451f9216SRichard Guy Briggs .flags = NL_CFG_F_NONROOT_RECV, 1284451f9216SRichard Guy Briggs .groups = AUDIT_NLGRP_MAX, 1285a31f2d17SPablo Neira Ayuso }; 1286f368c07dSAmy Griffis 128733faba7fSRichard Guy Briggs struct audit_net *aunet = net_generic(net, audit_net_id); 128833faba7fSRichard Guy Briggs 128933faba7fSRichard Guy Briggs aunet->nlsk = netlink_kernel_create(net, NETLINK_AUDIT, &cfg); 129011ee39ebSGao feng if (aunet->nlsk == NULL) { 129133faba7fSRichard Guy Briggs audit_panic("cannot initialize netlink socket in namespace"); 129211ee39ebSGao feng return -ENOMEM; 129311ee39ebSGao feng } 129433faba7fSRichard Guy Briggs aunet->nlsk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; 129533faba7fSRichard Guy Briggs return 0; 129633faba7fSRichard Guy Briggs } 129733faba7fSRichard Guy Briggs 129833faba7fSRichard Guy Briggs static void __net_exit audit_net_exit(struct net *net) 129933faba7fSRichard Guy Briggs { 130033faba7fSRichard Guy Briggs struct audit_net *aunet = net_generic(net, audit_net_id); 130133faba7fSRichard Guy Briggs struct sock *sock = aunet->nlsk; 1302*533c7b69SRichard Guy Briggs mutex_lock(&audit_cmd_mutex); 1303c6480207SPaul Moore if (sock == audit_sock) 1304c6480207SPaul Moore auditd_reset(); 1305*533c7b69SRichard Guy Briggs mutex_unlock(&audit_cmd_mutex); 130633faba7fSRichard Guy Briggs 1307e231d54cSMonam Agarwal RCU_INIT_POINTER(aunet->nlsk, NULL); 130833faba7fSRichard Guy Briggs synchronize_net(); 130933faba7fSRichard Guy Briggs netlink_kernel_release(sock); 131033faba7fSRichard Guy Briggs } 131133faba7fSRichard Guy Briggs 13128626877bSRichard Guy Briggs static struct pernet_operations audit_net_ops __net_initdata = { 131333faba7fSRichard Guy Briggs .init = audit_net_init, 131433faba7fSRichard Guy Briggs .exit = audit_net_exit, 131533faba7fSRichard Guy Briggs .id = &audit_net_id, 131633faba7fSRichard Guy Briggs .size = sizeof(struct audit_net), 131733faba7fSRichard Guy Briggs }; 131833faba7fSRichard Guy Briggs 131933faba7fSRichard Guy Briggs /* Initialize audit support at boot time. */ 132033faba7fSRichard Guy Briggs static int __init audit_init(void) 132133faba7fSRichard Guy Briggs { 132233faba7fSRichard Guy Briggs int i; 132333faba7fSRichard Guy Briggs 1324a3f07114SEric Paris if (audit_initialized == AUDIT_DISABLED) 1325a3f07114SEric Paris return 0; 1326a3f07114SEric Paris 1327d957f7b7SJoe Perches pr_info("initializing netlink subsys (%s)\n", 13281da177e4SLinus Torvalds audit_default ? "enabled" : "disabled"); 132933faba7fSRichard Guy Briggs register_pernet_subsys(&audit_net_ops); 133071e1c784SAmy Griffis 1331af8b824fSPaul Moore skb_queue_head_init(&audit_queue); 1332c6480207SPaul Moore skb_queue_head_init(&audit_retry_queue); 1333af8b824fSPaul Moore skb_queue_head_init(&audit_hold_queue); 1334a3f07114SEric Paris audit_initialized = AUDIT_INITIALIZED; 13351da177e4SLinus Torvalds audit_enabled = audit_default; 1336b593d384SEric Paris audit_ever_enabled |= !!audit_default; 13373dc7e315SDarrel Goeddel 1338f368c07dSAmy Griffis for (i = 0; i < AUDIT_INODE_BUCKETS; i++) 1339f368c07dSAmy Griffis INIT_LIST_HEAD(&audit_inode_hash[i]); 1340f368c07dSAmy Griffis 13416c925564SPaul Moore kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd"); 13426c925564SPaul Moore if (IS_ERR(kauditd_task)) { 13436c925564SPaul Moore int err = PTR_ERR(kauditd_task); 13446c925564SPaul Moore panic("audit: failed to start the kauditd thread (%d)\n", err); 13456c925564SPaul Moore } 13466c925564SPaul Moore 13476c925564SPaul Moore audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); 13486c925564SPaul Moore 13491da177e4SLinus Torvalds return 0; 13501da177e4SLinus Torvalds } 13511da177e4SLinus Torvalds __initcall(audit_init); 13521da177e4SLinus Torvalds 13531da177e4SLinus Torvalds /* Process kernel command-line parameter at boot time. audit=0 or audit=1. */ 13541da177e4SLinus Torvalds static int __init audit_enable(char *str) 13551da177e4SLinus Torvalds { 13561da177e4SLinus Torvalds audit_default = !!simple_strtol(str, NULL, 0); 1357a3f07114SEric Paris if (!audit_default) 1358a3f07114SEric Paris audit_initialized = AUDIT_DISABLED; 1359a3f07114SEric Paris 1360d957f7b7SJoe Perches pr_info("%s\n", audit_default ? 1361d3ca0344SGao feng "enabled (after initialization)" : "disabled (until reboot)"); 1362a3f07114SEric Paris 13639b41046cSOGAWA Hirofumi return 1; 13641da177e4SLinus Torvalds } 13651da177e4SLinus Torvalds __setup("audit=", audit_enable); 13661da177e4SLinus Torvalds 1367f910fde7SRichard Guy Briggs /* Process kernel command-line parameter at boot time. 1368f910fde7SRichard Guy Briggs * audit_backlog_limit=<n> */ 1369f910fde7SRichard Guy Briggs static int __init audit_backlog_limit_set(char *str) 1370f910fde7SRichard Guy Briggs { 13713e1d0bb6SJoe Perches u32 audit_backlog_limit_arg; 1372d957f7b7SJoe Perches 1373f910fde7SRichard Guy Briggs pr_info("audit_backlog_limit: "); 13743e1d0bb6SJoe Perches if (kstrtouint(str, 0, &audit_backlog_limit_arg)) { 13753e1d0bb6SJoe Perches pr_cont("using default of %u, unable to parse %s\n", 1376f910fde7SRichard Guy Briggs audit_backlog_limit, str); 1377f910fde7SRichard Guy Briggs return 1; 1378f910fde7SRichard Guy Briggs } 13793e1d0bb6SJoe Perches 13803e1d0bb6SJoe Perches audit_backlog_limit = audit_backlog_limit_arg; 1381d957f7b7SJoe Perches pr_cont("%d\n", audit_backlog_limit); 1382f910fde7SRichard Guy Briggs 1383f910fde7SRichard Guy Briggs return 1; 1384f910fde7SRichard Guy Briggs } 1385f910fde7SRichard Guy Briggs __setup("audit_backlog_limit=", audit_backlog_limit_set); 1386f910fde7SRichard Guy Briggs 138716e1904eSChris Wright static void audit_buffer_free(struct audit_buffer *ab) 138816e1904eSChris Wright { 138916e1904eSChris Wright unsigned long flags; 139016e1904eSChris Wright 13918fc6115cSChris Wright if (!ab) 13928fc6115cSChris Wright return; 13938fc6115cSChris Wright 13945ac52f33SChris Wright kfree_skb(ab->skb); 139516e1904eSChris Wright spin_lock_irqsave(&audit_freelist_lock, flags); 13965d136a01SSerge E. Hallyn if (audit_freelist_count > AUDIT_MAXFREE) 139716e1904eSChris Wright kfree(ab); 13985d136a01SSerge E. Hallyn else { 13995d136a01SSerge E. Hallyn audit_freelist_count++; 140016e1904eSChris Wright list_add(&ab->list, &audit_freelist); 14015d136a01SSerge E. Hallyn } 140216e1904eSChris Wright spin_unlock_irqrestore(&audit_freelist_lock, flags); 140316e1904eSChris Wright } 140416e1904eSChris Wright 1405c0404993SSteve Grubb static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, 1406dd0fc66fSAl Viro gfp_t gfp_mask, int type) 140716e1904eSChris Wright { 140816e1904eSChris Wright unsigned long flags; 140916e1904eSChris Wright struct audit_buffer *ab = NULL; 1410c0404993SSteve Grubb struct nlmsghdr *nlh; 141116e1904eSChris Wright 141216e1904eSChris Wright spin_lock_irqsave(&audit_freelist_lock, flags); 141316e1904eSChris Wright if (!list_empty(&audit_freelist)) { 141416e1904eSChris Wright ab = list_entry(audit_freelist.next, 141516e1904eSChris Wright struct audit_buffer, list); 141616e1904eSChris Wright list_del(&ab->list); 141716e1904eSChris Wright --audit_freelist_count; 141816e1904eSChris Wright } 141916e1904eSChris Wright spin_unlock_irqrestore(&audit_freelist_lock, flags); 142016e1904eSChris Wright 142116e1904eSChris Wright if (!ab) { 14224332bdd3SDavid Woodhouse ab = kmalloc(sizeof(*ab), gfp_mask); 142316e1904eSChris Wright if (!ab) 14248fc6115cSChris Wright goto err; 142516e1904eSChris Wright } 14268fc6115cSChris Wright 1427c0404993SSteve Grubb ab->ctx = ctx; 14289ad9ad38SDavid Woodhouse ab->gfp_mask = gfp_mask; 1429ee080e6cSEric Paris 1430ee080e6cSEric Paris ab->skb = nlmsg_new(AUDIT_BUFSIZ, gfp_mask); 1431ee080e6cSEric Paris if (!ab->skb) 1432c64e66c6SDavid S. Miller goto err; 1433ee080e6cSEric Paris 1434c64e66c6SDavid S. Miller nlh = nlmsg_put(ab->skb, 0, 0, type, 0, 0); 1435c64e66c6SDavid S. Miller if (!nlh) 1436c64e66c6SDavid S. Miller goto out_kfree_skb; 1437ee080e6cSEric Paris 143816e1904eSChris Wright return ab; 1439ee080e6cSEric Paris 1440c64e66c6SDavid S. Miller out_kfree_skb: 1441ee080e6cSEric Paris kfree_skb(ab->skb); 1442ee080e6cSEric Paris ab->skb = NULL; 14438fc6115cSChris Wright err: 14448fc6115cSChris Wright audit_buffer_free(ab); 14458fc6115cSChris Wright return NULL; 144616e1904eSChris Wright } 14471da177e4SLinus Torvalds 1448b0dd25a8SRandy Dunlap /** 1449b0dd25a8SRandy Dunlap * audit_serial - compute a serial number for the audit record 1450b0dd25a8SRandy Dunlap * 1451b0dd25a8SRandy Dunlap * Compute a serial number for the audit record. Audit records are 1452bfb4496eSDavid Woodhouse * written to user-space as soon as they are generated, so a complete 1453bfb4496eSDavid Woodhouse * audit record may be written in several pieces. The timestamp of the 1454bfb4496eSDavid Woodhouse * record and this serial number are used by the user-space tools to 1455bfb4496eSDavid Woodhouse * determine which pieces belong to the same audit record. The 1456bfb4496eSDavid Woodhouse * (timestamp,serial) tuple is unique for each syscall and is live from 1457bfb4496eSDavid Woodhouse * syscall entry to syscall exit. 1458bfb4496eSDavid Woodhouse * 1459bfb4496eSDavid Woodhouse * NOTE: Another possibility is to store the formatted records off the 1460bfb4496eSDavid Woodhouse * audit context (for those records that have a context), and emit them 1461bfb4496eSDavid Woodhouse * all at syscall exit. However, this could delay the reporting of 1462bfb4496eSDavid Woodhouse * significant errors until syscall exit (or never, if the system 1463b0dd25a8SRandy Dunlap * halts). 1464b0dd25a8SRandy Dunlap */ 1465bfb4496eSDavid Woodhouse unsigned int audit_serial(void) 1466bfb4496eSDavid Woodhouse { 146701478d7dSRichard Guy Briggs static atomic_t serial = ATOMIC_INIT(0); 1468bfb4496eSDavid Woodhouse 146901478d7dSRichard Guy Briggs return atomic_add_return(1, &serial); 1470bfb4496eSDavid Woodhouse } 1471bfb4496eSDavid Woodhouse 1472bfb4496eSDavid Woodhouse static inline void audit_get_stamp(struct audit_context *ctx, 1473bfb4496eSDavid Woodhouse struct timespec *t, unsigned int *serial) 1474bfb4496eSDavid Woodhouse { 147548887e63SAl Viro if (!ctx || !auditsc_get_stamp(ctx, t, serial)) { 1476bfb4496eSDavid Woodhouse *t = CURRENT_TIME; 1477bfb4496eSDavid Woodhouse *serial = audit_serial(); 1478bfb4496eSDavid Woodhouse } 1479bfb4496eSDavid Woodhouse } 1480bfb4496eSDavid Woodhouse 1481b0dd25a8SRandy Dunlap /** 1482b0dd25a8SRandy Dunlap * audit_log_start - obtain an audit buffer 1483b0dd25a8SRandy Dunlap * @ctx: audit_context (may be NULL) 1484b0dd25a8SRandy Dunlap * @gfp_mask: type of allocation 1485b0dd25a8SRandy Dunlap * @type: audit message type 1486b0dd25a8SRandy Dunlap * 1487b0dd25a8SRandy Dunlap * Returns audit_buffer pointer on success or NULL on error. 1488b0dd25a8SRandy Dunlap * 1489b0dd25a8SRandy Dunlap * Obtain an audit buffer. This routine does locking to obtain the 1490b0dd25a8SRandy Dunlap * audit buffer, but then no locking is required for calls to 1491b0dd25a8SRandy Dunlap * audit_log_*format. If the task (ctx) is a task that is currently in a 1492b0dd25a8SRandy Dunlap * syscall, then the syscall is marked as auditable and an audit record 1493b0dd25a8SRandy Dunlap * will be written at syscall exit. If there is no associated task, then 1494b0dd25a8SRandy Dunlap * task context (ctx) should be NULL. 1495b0dd25a8SRandy Dunlap */ 14969796fdd8SAl Viro struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, 14979ad9ad38SDavid Woodhouse int type) 14981da177e4SLinus Torvalds { 149931975424SPaul Moore struct audit_buffer *ab; 15001da177e4SLinus Torvalds struct timespec t; 1501ef00be05SAndrew Morton unsigned int uninitialized_var(serial); 15021da177e4SLinus Torvalds 1503a3f07114SEric Paris if (audit_initialized != AUDIT_INITIALIZED) 15041da177e4SLinus Torvalds return NULL; 15051da177e4SLinus Torvalds 150686b2efbeSRichard Guy Briggs if (unlikely(!audit_filter(type, AUDIT_FILTER_TYPE))) 1507c8edc80cSDustin Kirkland return NULL; 1508c8edc80cSDustin Kirkland 1509a09cfa47SPaul Moore /* don't ever fail/sleep on these two conditions: 1510a09cfa47SPaul Moore * 1. auditd generated record - since we need auditd to drain the 151131975424SPaul Moore * queue; also, when we are checking for auditd, compare PIDs using 1512a09cfa47SPaul Moore * task_tgid_vnr() since auditd_pid is set in audit_receive_msg() 1513a09cfa47SPaul Moore * using a PID anchored in the caller's namespace 1514a09cfa47SPaul Moore * 2. audit command message - record types 1000 through 1099 inclusive 1515a09cfa47SPaul Moore * are command messages/records used to manage the kernel subsystem 1516a09cfa47SPaul Moore * and the audit userspace, blocking on these messages could cause 1517a09cfa47SPaul Moore * problems under load so don't do it (note: not all of these 1518a09cfa47SPaul Moore * command types are valid as record types, but it is quicker to 1519a09cfa47SPaul Moore * just check two ints than a series of ints in a if/switch stmt) */ 1520a09cfa47SPaul Moore if (!((audit_pid && audit_pid == task_tgid_vnr(current)) || 1521a09cfa47SPaul Moore (type >= 1000 && type <= 1099))) { 152231975424SPaul Moore long sleep_time = audit_backlog_wait_time; 15239ad9ad38SDavid Woodhouse 152431975424SPaul Moore while (audit_backlog_limit && 152531975424SPaul Moore (skb_queue_len(&audit_queue) > audit_backlog_limit)) { 152631975424SPaul Moore /* wake kauditd to try and flush the queue */ 152731975424SPaul Moore wake_up_interruptible(&kauditd_wait); 1528ac4cec44SDavid Woodhouse 152931975424SPaul Moore /* sleep if we are allowed and we haven't exhausted our 153031975424SPaul Moore * backlog wait limit */ 153131975424SPaul Moore if ((gfp_mask & __GFP_DIRECT_RECLAIM) && 153231975424SPaul Moore (sleep_time > 0)) { 153331975424SPaul Moore DECLARE_WAITQUEUE(wait, current); 153431975424SPaul Moore 153531975424SPaul Moore add_wait_queue_exclusive(&audit_backlog_wait, 153631975424SPaul Moore &wait); 153731975424SPaul Moore set_current_state(TASK_UNINTERRUPTIBLE); 153831975424SPaul Moore sleep_time = schedule_timeout(sleep_time); 153931975424SPaul Moore remove_wait_queue(&audit_backlog_wait, &wait); 154031975424SPaul Moore } else { 1541320f1b1eSEric Paris if (audit_rate_check() && printk_ratelimit()) 1542d957f7b7SJoe Perches pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n", 1543af8b824fSPaul Moore skb_queue_len(&audit_queue), 1544fb19b4c6SDavid Woodhouse audit_backlog_limit); 1545fb19b4c6SDavid Woodhouse audit_log_lost("backlog limit exceeded"); 1546fb19b4c6SDavid Woodhouse return NULL; 1547fb19b4c6SDavid Woodhouse } 154831975424SPaul Moore } 154931975424SPaul Moore } 1550e789e561SRichard Guy Briggs 15519ad9ad38SDavid Woodhouse ab = audit_buffer_alloc(ctx, gfp_mask, type); 15521da177e4SLinus Torvalds if (!ab) { 15531da177e4SLinus Torvalds audit_log_lost("out of memory in audit_log_start"); 15541da177e4SLinus Torvalds return NULL; 15551da177e4SLinus Torvalds } 15561da177e4SLinus Torvalds 1557bfb4496eSDavid Woodhouse audit_get_stamp(ab->ctx, &t, &serial); 15581da177e4SLinus Torvalds audit_log_format(ab, "audit(%lu.%03lu:%u): ", 15591da177e4SLinus Torvalds t.tv_sec, t.tv_nsec/1000000, serial); 156031975424SPaul Moore 15611da177e4SLinus Torvalds return ab; 15621da177e4SLinus Torvalds } 15631da177e4SLinus Torvalds 15648fc6115cSChris Wright /** 15655ac52f33SChris Wright * audit_expand - expand skb in the audit buffer 15668fc6115cSChris Wright * @ab: audit_buffer 1567b0dd25a8SRandy Dunlap * @extra: space to add at tail of the skb 15688fc6115cSChris Wright * 15698fc6115cSChris Wright * Returns 0 (no space) on failed expansion, or available space if 15708fc6115cSChris Wright * successful. 15718fc6115cSChris Wright */ 1572e3b926b4SDavid Woodhouse static inline int audit_expand(struct audit_buffer *ab, int extra) 15738fc6115cSChris Wright { 15745ac52f33SChris Wright struct sk_buff *skb = ab->skb; 1575406a1d86SHerbert Xu int oldtail = skb_tailroom(skb); 1576406a1d86SHerbert Xu int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask); 1577406a1d86SHerbert Xu int newtail = skb_tailroom(skb); 1578406a1d86SHerbert Xu 15795ac52f33SChris Wright if (ret < 0) { 15805ac52f33SChris Wright audit_log_lost("out of memory in audit_expand"); 15818fc6115cSChris Wright return 0; 15825ac52f33SChris Wright } 1583406a1d86SHerbert Xu 1584406a1d86SHerbert Xu skb->truesize += newtail - oldtail; 1585406a1d86SHerbert Xu return newtail; 15868fc6115cSChris Wright } 15871da177e4SLinus Torvalds 1588b0dd25a8SRandy Dunlap /* 1589b0dd25a8SRandy Dunlap * Format an audit message into the audit buffer. If there isn't enough 15901da177e4SLinus Torvalds * room in the audit buffer, more room will be allocated and vsnprint 15911da177e4SLinus Torvalds * will be called a second time. Currently, we assume that a printk 1592b0dd25a8SRandy Dunlap * can't format message larger than 1024 bytes, so we don't either. 1593b0dd25a8SRandy Dunlap */ 15941da177e4SLinus Torvalds static void audit_log_vformat(struct audit_buffer *ab, const char *fmt, 15951da177e4SLinus Torvalds va_list args) 15961da177e4SLinus Torvalds { 15971da177e4SLinus Torvalds int len, avail; 15985ac52f33SChris Wright struct sk_buff *skb; 1599eecb0a73SDavid Woodhouse va_list args2; 16001da177e4SLinus Torvalds 16011da177e4SLinus Torvalds if (!ab) 16021da177e4SLinus Torvalds return; 16031da177e4SLinus Torvalds 16045ac52f33SChris Wright BUG_ON(!ab->skb); 16055ac52f33SChris Wright skb = ab->skb; 16065ac52f33SChris Wright avail = skb_tailroom(skb); 16075ac52f33SChris Wright if (avail == 0) { 1608e3b926b4SDavid Woodhouse avail = audit_expand(ab, AUDIT_BUFSIZ); 16098fc6115cSChris Wright if (!avail) 16108fc6115cSChris Wright goto out; 16111da177e4SLinus Torvalds } 1612eecb0a73SDavid Woodhouse va_copy(args2, args); 161327a884dcSArnaldo Carvalho de Melo len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args); 16141da177e4SLinus Torvalds if (len >= avail) { 16151da177e4SLinus Torvalds /* The printk buffer is 1024 bytes long, so if we get 16161da177e4SLinus Torvalds * here and AUDIT_BUFSIZ is at least 1024, then we can 16171da177e4SLinus Torvalds * log everything that printk could have logged. */ 1618b0dd25a8SRandy Dunlap avail = audit_expand(ab, 1619b0dd25a8SRandy Dunlap max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail)); 16208fc6115cSChris Wright if (!avail) 1621a0e86bd4SJesper Juhl goto out_va_end; 162227a884dcSArnaldo Carvalho de Melo len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args2); 16231da177e4SLinus Torvalds } 1624168b7173SSteve Grubb if (len > 0) 1625168b7173SSteve Grubb skb_put(skb, len); 1626a0e86bd4SJesper Juhl out_va_end: 1627a0e86bd4SJesper Juhl va_end(args2); 16288fc6115cSChris Wright out: 16298fc6115cSChris Wright return; 16301da177e4SLinus Torvalds } 16311da177e4SLinus Torvalds 1632b0dd25a8SRandy Dunlap /** 1633b0dd25a8SRandy Dunlap * audit_log_format - format a message into the audit buffer. 1634b0dd25a8SRandy Dunlap * @ab: audit_buffer 1635b0dd25a8SRandy Dunlap * @fmt: format string 1636b0dd25a8SRandy Dunlap * @...: optional parameters matching @fmt string 1637b0dd25a8SRandy Dunlap * 1638b0dd25a8SRandy Dunlap * All the work is done in audit_log_vformat. 1639b0dd25a8SRandy Dunlap */ 16401da177e4SLinus Torvalds void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) 16411da177e4SLinus Torvalds { 16421da177e4SLinus Torvalds va_list args; 16431da177e4SLinus Torvalds 16441da177e4SLinus Torvalds if (!ab) 16451da177e4SLinus Torvalds return; 16461da177e4SLinus Torvalds va_start(args, fmt); 16471da177e4SLinus Torvalds audit_log_vformat(ab, fmt, args); 16481da177e4SLinus Torvalds va_end(args); 16491da177e4SLinus Torvalds } 16501da177e4SLinus Torvalds 1651b0dd25a8SRandy Dunlap /** 1652b0dd25a8SRandy Dunlap * audit_log_hex - convert a buffer to hex and append it to the audit skb 1653b0dd25a8SRandy Dunlap * @ab: the audit_buffer 1654b0dd25a8SRandy Dunlap * @buf: buffer to convert to hex 1655b0dd25a8SRandy Dunlap * @len: length of @buf to be converted 1656b0dd25a8SRandy Dunlap * 1657b0dd25a8SRandy Dunlap * No return value; failure to expand is silently ignored. 1658b0dd25a8SRandy Dunlap * 1659b0dd25a8SRandy Dunlap * This function will take the passed buf and convert it into a string of 1660b0dd25a8SRandy Dunlap * ascii hex digits. The new string is placed onto the skb. 1661b0dd25a8SRandy Dunlap */ 1662b556f8adSEric Paris void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf, 1663168b7173SSteve Grubb size_t len) 166483c7d091S { 1665168b7173SSteve Grubb int i, avail, new_len; 1666168b7173SSteve Grubb unsigned char *ptr; 1667168b7173SSteve Grubb struct sk_buff *skb; 166883c7d091S 16698ef2d304SAmy Griffis if (!ab) 16708ef2d304SAmy Griffis return; 16718ef2d304SAmy Griffis 1672168b7173SSteve Grubb BUG_ON(!ab->skb); 1673168b7173SSteve Grubb skb = ab->skb; 1674168b7173SSteve Grubb avail = skb_tailroom(skb); 1675168b7173SSteve Grubb new_len = len<<1; 1676168b7173SSteve Grubb if (new_len >= avail) { 1677168b7173SSteve Grubb /* Round the buffer request up to the next multiple */ 1678168b7173SSteve Grubb new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1); 1679168b7173SSteve Grubb avail = audit_expand(ab, new_len); 1680168b7173SSteve Grubb if (!avail) 1681168b7173SSteve Grubb return; 168283c7d091S } 168383c7d091S 168427a884dcSArnaldo Carvalho de Melo ptr = skb_tail_pointer(skb); 1685b8dbc324SJoe Perches for (i = 0; i < len; i++) 1686b8dbc324SJoe Perches ptr = hex_byte_pack_upper(ptr, buf[i]); 1687168b7173SSteve Grubb *ptr = 0; 1688168b7173SSteve Grubb skb_put(skb, len << 1); /* new string is twice the old string */ 1689168b7173SSteve Grubb } 1690168b7173SSteve Grubb 16919c937dccSAmy Griffis /* 16929c937dccSAmy Griffis * Format a string of no more than slen characters into the audit buffer, 16939c937dccSAmy Griffis * enclosed in quote marks. 16949c937dccSAmy Griffis */ 1695b556f8adSEric Paris void audit_log_n_string(struct audit_buffer *ab, const char *string, 1696b556f8adSEric Paris size_t slen) 16979c937dccSAmy Griffis { 16989c937dccSAmy Griffis int avail, new_len; 16999c937dccSAmy Griffis unsigned char *ptr; 17009c937dccSAmy Griffis struct sk_buff *skb; 17019c937dccSAmy Griffis 17028ef2d304SAmy Griffis if (!ab) 17038ef2d304SAmy Griffis return; 17048ef2d304SAmy Griffis 17059c937dccSAmy Griffis BUG_ON(!ab->skb); 17069c937dccSAmy Griffis skb = ab->skb; 17079c937dccSAmy Griffis avail = skb_tailroom(skb); 17089c937dccSAmy Griffis new_len = slen + 3; /* enclosing quotes + null terminator */ 17099c937dccSAmy Griffis if (new_len > avail) { 17109c937dccSAmy Griffis avail = audit_expand(ab, new_len); 17119c937dccSAmy Griffis if (!avail) 17129c937dccSAmy Griffis return; 17139c937dccSAmy Griffis } 171427a884dcSArnaldo Carvalho de Melo ptr = skb_tail_pointer(skb); 17159c937dccSAmy Griffis *ptr++ = '"'; 17169c937dccSAmy Griffis memcpy(ptr, string, slen); 17179c937dccSAmy Griffis ptr += slen; 17189c937dccSAmy Griffis *ptr++ = '"'; 17199c937dccSAmy Griffis *ptr = 0; 17209c937dccSAmy Griffis skb_put(skb, slen + 2); /* don't include null terminator */ 17219c937dccSAmy Griffis } 17229c937dccSAmy Griffis 1723b0dd25a8SRandy Dunlap /** 1724de6bbd1dSEric Paris * audit_string_contains_control - does a string need to be logged in hex 1725f706d5d2SDave Jones * @string: string to be checked 1726f706d5d2SDave Jones * @len: max length of the string to check 1727de6bbd1dSEric Paris */ 17289fcf836bSYaowei Bai bool audit_string_contains_control(const char *string, size_t len) 1729de6bbd1dSEric Paris { 1730de6bbd1dSEric Paris const unsigned char *p; 1731b3897f56SMiloslav Trmac for (p = string; p < (const unsigned char *)string + len; p++) { 17321d6c9649SVesa-Matti J Kari if (*p == '"' || *p < 0x21 || *p > 0x7e) 17339fcf836bSYaowei Bai return true; 1734de6bbd1dSEric Paris } 17359fcf836bSYaowei Bai return false; 1736de6bbd1dSEric Paris } 1737de6bbd1dSEric Paris 1738de6bbd1dSEric Paris /** 1739522ed776SMiloslav Trmac * audit_log_n_untrustedstring - log a string that may contain random characters 1740b0dd25a8SRandy Dunlap * @ab: audit_buffer 1741f706d5d2SDave Jones * @len: length of string (not including trailing null) 1742b0dd25a8SRandy Dunlap * @string: string to be logged 1743b0dd25a8SRandy Dunlap * 1744b0dd25a8SRandy Dunlap * This code will escape a string that is passed to it if the string 1745168b7173SSteve Grubb * contains a control character, unprintable character, double quote mark, 1746168b7173SSteve Grubb * or a space. Unescaped strings will start and end with a double quote mark. 1747b0dd25a8SRandy Dunlap * Strings that are escaped are printed in hex (2 digits per char). 17489c937dccSAmy Griffis * 17499c937dccSAmy Griffis * The caller specifies the number of characters in the string to log, which may 17509c937dccSAmy Griffis * or may not be the entire string. 1751b0dd25a8SRandy Dunlap */ 1752b556f8adSEric Paris void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string, 1753b556f8adSEric Paris size_t len) 175483c7d091S { 1755de6bbd1dSEric Paris if (audit_string_contains_control(string, len)) 1756b556f8adSEric Paris audit_log_n_hex(ab, string, len); 1757de6bbd1dSEric Paris else 1758b556f8adSEric Paris audit_log_n_string(ab, string, len); 175983c7d091S } 176083c7d091S 17619c937dccSAmy Griffis /** 1762522ed776SMiloslav Trmac * audit_log_untrustedstring - log a string that may contain random characters 17639c937dccSAmy Griffis * @ab: audit_buffer 17649c937dccSAmy Griffis * @string: string to be logged 17659c937dccSAmy Griffis * 1766522ed776SMiloslav Trmac * Same as audit_log_n_untrustedstring(), except that strlen is used to 17679c937dccSAmy Griffis * determine string length. 17689c937dccSAmy Griffis */ 1769de6bbd1dSEric Paris void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) 17709c937dccSAmy Griffis { 1771b556f8adSEric Paris audit_log_n_untrustedstring(ab, string, strlen(string)); 17729c937dccSAmy Griffis } 17739c937dccSAmy Griffis 1774168b7173SSteve Grubb /* This is a helper-function to print the escaped d_path */ 17751da177e4SLinus Torvalds void audit_log_d_path(struct audit_buffer *ab, const char *prefix, 177666b3fad3SAl Viro const struct path *path) 17771da177e4SLinus Torvalds { 177844707fdfSJan Blunck char *p, *pathname; 17791da177e4SLinus Torvalds 17808fc6115cSChris Wright if (prefix) 17818fc6115cSChris Wright audit_log_format(ab, "%s", prefix); 17821da177e4SLinus Torvalds 1783168b7173SSteve Grubb /* We will allow 11 spaces for ' (deleted)' to be appended */ 178444707fdfSJan Blunck pathname = kmalloc(PATH_MAX+11, ab->gfp_mask); 178544707fdfSJan Blunck if (!pathname) { 1786def57543SEric Paris audit_log_string(ab, "<no_memory>"); 1787168b7173SSteve Grubb return; 1788168b7173SSteve Grubb } 1789cf28b486SJan Blunck p = d_path(path, pathname, PATH_MAX+11); 1790168b7173SSteve Grubb if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */ 17911da177e4SLinus Torvalds /* FIXME: can we save some information here? */ 1792def57543SEric Paris audit_log_string(ab, "<too_long>"); 1793168b7173SSteve Grubb } else 1794168b7173SSteve Grubb audit_log_untrustedstring(ab, p); 179544707fdfSJan Blunck kfree(pathname); 17961da177e4SLinus Torvalds } 17971da177e4SLinus Torvalds 17984d3fb709SEric Paris void audit_log_session_info(struct audit_buffer *ab) 17994d3fb709SEric Paris { 18004440e854SEric Paris unsigned int sessionid = audit_get_sessionid(current); 18014d3fb709SEric Paris uid_t auid = from_kuid(&init_user_ns, audit_get_loginuid(current)); 18024d3fb709SEric Paris 1803b8f89caaSRichard Guy Briggs audit_log_format(ab, " auid=%u ses=%u", auid, sessionid); 18044d3fb709SEric Paris } 18054d3fb709SEric Paris 18069d960985SEric Paris void audit_log_key(struct audit_buffer *ab, char *key) 18079d960985SEric Paris { 18089d960985SEric Paris audit_log_format(ab, " key="); 18099d960985SEric Paris if (key) 18109d960985SEric Paris audit_log_untrustedstring(ab, key); 18119d960985SEric Paris else 18129d960985SEric Paris audit_log_format(ab, "(null)"); 18139d960985SEric Paris } 18149d960985SEric Paris 1815b24a30a7SEric Paris void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap) 1816b24a30a7SEric Paris { 1817b24a30a7SEric Paris int i; 1818b24a30a7SEric Paris 1819b24a30a7SEric Paris audit_log_format(ab, " %s=", prefix); 1820b24a30a7SEric Paris CAP_FOR_EACH_U32(i) { 1821b24a30a7SEric Paris audit_log_format(ab, "%08x", 18227d8b6c63SEric Paris cap->cap[CAP_LAST_U32 - i]); 1823b24a30a7SEric Paris } 1824b24a30a7SEric Paris } 1825b24a30a7SEric Paris 1826691e6d59SRichard Guy Briggs static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) 1827b24a30a7SEric Paris { 1828b24a30a7SEric Paris kernel_cap_t *perm = &name->fcap.permitted; 1829b24a30a7SEric Paris kernel_cap_t *inh = &name->fcap.inheritable; 1830b24a30a7SEric Paris int log = 0; 1831b24a30a7SEric Paris 1832b24a30a7SEric Paris if (!cap_isclear(*perm)) { 1833b24a30a7SEric Paris audit_log_cap(ab, "cap_fp", perm); 1834b24a30a7SEric Paris log = 1; 1835b24a30a7SEric Paris } 1836b24a30a7SEric Paris if (!cap_isclear(*inh)) { 1837b24a30a7SEric Paris audit_log_cap(ab, "cap_fi", inh); 1838b24a30a7SEric Paris log = 1; 1839b24a30a7SEric Paris } 1840b24a30a7SEric Paris 1841b24a30a7SEric Paris if (log) 1842b24a30a7SEric Paris audit_log_format(ab, " cap_fe=%d cap_fver=%x", 1843b24a30a7SEric Paris name->fcap.fE, name->fcap_ver); 1844b24a30a7SEric Paris } 1845b24a30a7SEric Paris 1846b24a30a7SEric Paris static inline int audit_copy_fcaps(struct audit_names *name, 1847b24a30a7SEric Paris const struct dentry *dentry) 1848b24a30a7SEric Paris { 1849b24a30a7SEric Paris struct cpu_vfs_cap_data caps; 1850b24a30a7SEric Paris int rc; 1851b24a30a7SEric Paris 1852b24a30a7SEric Paris if (!dentry) 1853b24a30a7SEric Paris return 0; 1854b24a30a7SEric Paris 1855b24a30a7SEric Paris rc = get_vfs_caps_from_disk(dentry, &caps); 1856b24a30a7SEric Paris if (rc) 1857b24a30a7SEric Paris return rc; 1858b24a30a7SEric Paris 1859b24a30a7SEric Paris name->fcap.permitted = caps.permitted; 1860b24a30a7SEric Paris name->fcap.inheritable = caps.inheritable; 1861b24a30a7SEric Paris name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); 1862b24a30a7SEric Paris name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >> 1863b24a30a7SEric Paris VFS_CAP_REVISION_SHIFT; 1864b24a30a7SEric Paris 1865b24a30a7SEric Paris return 0; 1866b24a30a7SEric Paris } 1867b24a30a7SEric Paris 1868b24a30a7SEric Paris /* Copy inode data into an audit_names. */ 1869b24a30a7SEric Paris void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, 1870d6335d77SAndreas Gruenbacher struct inode *inode) 1871b24a30a7SEric Paris { 1872b24a30a7SEric Paris name->ino = inode->i_ino; 1873b24a30a7SEric Paris name->dev = inode->i_sb->s_dev; 1874b24a30a7SEric Paris name->mode = inode->i_mode; 1875b24a30a7SEric Paris name->uid = inode->i_uid; 1876b24a30a7SEric Paris name->gid = inode->i_gid; 1877b24a30a7SEric Paris name->rdev = inode->i_rdev; 1878b24a30a7SEric Paris security_inode_getsecid(inode, &name->osid); 1879b24a30a7SEric Paris audit_copy_fcaps(name, dentry); 1880b24a30a7SEric Paris } 1881b24a30a7SEric Paris 1882b24a30a7SEric Paris /** 1883b24a30a7SEric Paris * audit_log_name - produce AUDIT_PATH record from struct audit_names 1884b24a30a7SEric Paris * @context: audit_context for the task 1885b24a30a7SEric Paris * @n: audit_names structure with reportable details 1886b24a30a7SEric Paris * @path: optional path to report instead of audit_names->name 1887b24a30a7SEric Paris * @record_num: record number to report when handling a list of names 1888b24a30a7SEric Paris * @call_panic: optional pointer to int that will be updated if secid fails 1889b24a30a7SEric Paris */ 1890b24a30a7SEric Paris void audit_log_name(struct audit_context *context, struct audit_names *n, 1891b24a30a7SEric Paris struct path *path, int record_num, int *call_panic) 1892b24a30a7SEric Paris { 1893b24a30a7SEric Paris struct audit_buffer *ab; 1894b24a30a7SEric Paris ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); 1895b24a30a7SEric Paris if (!ab) 1896b24a30a7SEric Paris return; 1897b24a30a7SEric Paris 1898b24a30a7SEric Paris audit_log_format(ab, "item=%d", record_num); 1899b24a30a7SEric Paris 1900b24a30a7SEric Paris if (path) 1901b24a30a7SEric Paris audit_log_d_path(ab, " name=", path); 1902b24a30a7SEric Paris else if (n->name) { 1903b24a30a7SEric Paris switch (n->name_len) { 1904b24a30a7SEric Paris case AUDIT_NAME_FULL: 1905b24a30a7SEric Paris /* log the full path */ 1906b24a30a7SEric Paris audit_log_format(ab, " name="); 1907b24a30a7SEric Paris audit_log_untrustedstring(ab, n->name->name); 1908b24a30a7SEric Paris break; 1909b24a30a7SEric Paris case 0: 1910b24a30a7SEric Paris /* name was specified as a relative path and the 1911b24a30a7SEric Paris * directory component is the cwd */ 1912b24a30a7SEric Paris audit_log_d_path(ab, " name=", &context->pwd); 1913b24a30a7SEric Paris break; 1914b24a30a7SEric Paris default: 1915b24a30a7SEric Paris /* log the name's directory component */ 1916b24a30a7SEric Paris audit_log_format(ab, " name="); 1917b24a30a7SEric Paris audit_log_n_untrustedstring(ab, n->name->name, 1918b24a30a7SEric Paris n->name_len); 1919b24a30a7SEric Paris } 1920b24a30a7SEric Paris } else 1921b24a30a7SEric Paris audit_log_format(ab, " name=(null)"); 1922b24a30a7SEric Paris 1923425afcffSLinus Torvalds if (n->ino != AUDIT_INO_UNSET) 1924b24a30a7SEric Paris audit_log_format(ab, " inode=%lu" 1925b24a30a7SEric Paris " dev=%02x:%02x mode=%#ho" 1926b24a30a7SEric Paris " ouid=%u ogid=%u rdev=%02x:%02x", 1927b24a30a7SEric Paris n->ino, 1928b24a30a7SEric Paris MAJOR(n->dev), 1929b24a30a7SEric Paris MINOR(n->dev), 1930b24a30a7SEric Paris n->mode, 1931b24a30a7SEric Paris from_kuid(&init_user_ns, n->uid), 1932b24a30a7SEric Paris from_kgid(&init_user_ns, n->gid), 1933b24a30a7SEric Paris MAJOR(n->rdev), 1934b24a30a7SEric Paris MINOR(n->rdev)); 1935b24a30a7SEric Paris if (n->osid != 0) { 1936b24a30a7SEric Paris char *ctx = NULL; 1937b24a30a7SEric Paris u32 len; 1938b24a30a7SEric Paris if (security_secid_to_secctx( 1939b24a30a7SEric Paris n->osid, &ctx, &len)) { 1940b24a30a7SEric Paris audit_log_format(ab, " osid=%u", n->osid); 1941b24a30a7SEric Paris if (call_panic) 1942b24a30a7SEric Paris *call_panic = 2; 1943b24a30a7SEric Paris } else { 1944b24a30a7SEric Paris audit_log_format(ab, " obj=%s", ctx); 1945b24a30a7SEric Paris security_release_secctx(ctx, len); 1946b24a30a7SEric Paris } 1947b24a30a7SEric Paris } 1948b24a30a7SEric Paris 1949d3aea84aSJeff Layton /* log the audit_names record type */ 1950d3aea84aSJeff Layton audit_log_format(ab, " nametype="); 1951d3aea84aSJeff Layton switch(n->type) { 1952d3aea84aSJeff Layton case AUDIT_TYPE_NORMAL: 1953d3aea84aSJeff Layton audit_log_format(ab, "NORMAL"); 1954d3aea84aSJeff Layton break; 1955d3aea84aSJeff Layton case AUDIT_TYPE_PARENT: 1956d3aea84aSJeff Layton audit_log_format(ab, "PARENT"); 1957d3aea84aSJeff Layton break; 1958d3aea84aSJeff Layton case AUDIT_TYPE_CHILD_DELETE: 1959d3aea84aSJeff Layton audit_log_format(ab, "DELETE"); 1960d3aea84aSJeff Layton break; 1961d3aea84aSJeff Layton case AUDIT_TYPE_CHILD_CREATE: 1962d3aea84aSJeff Layton audit_log_format(ab, "CREATE"); 1963d3aea84aSJeff Layton break; 1964d3aea84aSJeff Layton default: 1965d3aea84aSJeff Layton audit_log_format(ab, "UNKNOWN"); 1966d3aea84aSJeff Layton break; 1967d3aea84aSJeff Layton } 1968d3aea84aSJeff Layton 1969b24a30a7SEric Paris audit_log_fcaps(ab, n); 1970b24a30a7SEric Paris audit_log_end(ab); 1971b24a30a7SEric Paris } 1972b24a30a7SEric Paris 1973b24a30a7SEric Paris int audit_log_task_context(struct audit_buffer *ab) 1974b24a30a7SEric Paris { 1975b24a30a7SEric Paris char *ctx = NULL; 1976b24a30a7SEric Paris unsigned len; 1977b24a30a7SEric Paris int error; 1978b24a30a7SEric Paris u32 sid; 1979b24a30a7SEric Paris 1980b24a30a7SEric Paris security_task_getsecid(current, &sid); 1981b24a30a7SEric Paris if (!sid) 1982b24a30a7SEric Paris return 0; 1983b24a30a7SEric Paris 1984b24a30a7SEric Paris error = security_secid_to_secctx(sid, &ctx, &len); 1985b24a30a7SEric Paris if (error) { 1986b24a30a7SEric Paris if (error != -EINVAL) 1987b24a30a7SEric Paris goto error_path; 1988b24a30a7SEric Paris return 0; 1989b24a30a7SEric Paris } 1990b24a30a7SEric Paris 1991b24a30a7SEric Paris audit_log_format(ab, " subj=%s", ctx); 1992b24a30a7SEric Paris security_release_secctx(ctx, len); 1993b24a30a7SEric Paris return 0; 1994b24a30a7SEric Paris 1995b24a30a7SEric Paris error_path: 1996b24a30a7SEric Paris audit_panic("error in audit_log_task_context"); 1997b24a30a7SEric Paris return error; 1998b24a30a7SEric Paris } 1999b24a30a7SEric Paris EXPORT_SYMBOL(audit_log_task_context); 2000b24a30a7SEric Paris 20014766b199SDavidlohr Bueso void audit_log_d_path_exe(struct audit_buffer *ab, 20024766b199SDavidlohr Bueso struct mm_struct *mm) 20034766b199SDavidlohr Bueso { 20045b282552SDavidlohr Bueso struct file *exe_file; 20054766b199SDavidlohr Bueso 20065b282552SDavidlohr Bueso if (!mm) 20075b282552SDavidlohr Bueso goto out_null; 20085b282552SDavidlohr Bueso 20095b282552SDavidlohr Bueso exe_file = get_mm_exe_file(mm); 20105b282552SDavidlohr Bueso if (!exe_file) 20115b282552SDavidlohr Bueso goto out_null; 20125b282552SDavidlohr Bueso 20135b282552SDavidlohr Bueso audit_log_d_path(ab, " exe=", &exe_file->f_path); 20145b282552SDavidlohr Bueso fput(exe_file); 20155b282552SDavidlohr Bueso return; 20165b282552SDavidlohr Bueso out_null: 20175b282552SDavidlohr Bueso audit_log_format(ab, " exe=(null)"); 20184766b199SDavidlohr Bueso } 20194766b199SDavidlohr Bueso 20203f5be2daSRichard Guy Briggs struct tty_struct *audit_get_tty(struct task_struct *tsk) 20213f5be2daSRichard Guy Briggs { 20223f5be2daSRichard Guy Briggs struct tty_struct *tty = NULL; 20233f5be2daSRichard Guy Briggs unsigned long flags; 20243f5be2daSRichard Guy Briggs 20253f5be2daSRichard Guy Briggs spin_lock_irqsave(&tsk->sighand->siglock, flags); 20263f5be2daSRichard Guy Briggs if (tsk->signal) 20273f5be2daSRichard Guy Briggs tty = tty_kref_get(tsk->signal->tty); 20283f5be2daSRichard Guy Briggs spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 20293f5be2daSRichard Guy Briggs return tty; 20303f5be2daSRichard Guy Briggs } 20313f5be2daSRichard Guy Briggs 20323f5be2daSRichard Guy Briggs void audit_put_tty(struct tty_struct *tty) 20333f5be2daSRichard Guy Briggs { 20343f5be2daSRichard Guy Briggs tty_kref_put(tty); 20353f5be2daSRichard Guy Briggs } 20363f5be2daSRichard Guy Briggs 2037b24a30a7SEric Paris void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) 2038b24a30a7SEric Paris { 2039b24a30a7SEric Paris const struct cred *cred; 20409eab339bSRichard Guy Briggs char comm[sizeof(tsk->comm)]; 2041db0a6fb5SRichard Guy Briggs struct tty_struct *tty; 2042b24a30a7SEric Paris 2043b24a30a7SEric Paris if (!ab) 2044b24a30a7SEric Paris return; 2045b24a30a7SEric Paris 2046b24a30a7SEric Paris /* tsk == current */ 2047b24a30a7SEric Paris cred = current_cred(); 2048db0a6fb5SRichard Guy Briggs tty = audit_get_tty(tsk); 2049b24a30a7SEric Paris audit_log_format(ab, 2050c92cdeb4SRichard Guy Briggs " ppid=%d pid=%d auid=%u uid=%u gid=%u" 2051b24a30a7SEric Paris " euid=%u suid=%u fsuid=%u" 20522f2ad101SRichard Guy Briggs " egid=%u sgid=%u fsgid=%u tty=%s ses=%u", 2053c92cdeb4SRichard Guy Briggs task_ppid_nr(tsk), 2054f1dc4867SRichard Guy Briggs task_pid_nr(tsk), 2055b24a30a7SEric Paris from_kuid(&init_user_ns, audit_get_loginuid(tsk)), 2056b24a30a7SEric Paris from_kuid(&init_user_ns, cred->uid), 2057b24a30a7SEric Paris from_kgid(&init_user_ns, cred->gid), 2058b24a30a7SEric Paris from_kuid(&init_user_ns, cred->euid), 2059b24a30a7SEric Paris from_kuid(&init_user_ns, cred->suid), 2060b24a30a7SEric Paris from_kuid(&init_user_ns, cred->fsuid), 2061b24a30a7SEric Paris from_kgid(&init_user_ns, cred->egid), 2062b24a30a7SEric Paris from_kgid(&init_user_ns, cred->sgid), 2063b24a30a7SEric Paris from_kgid(&init_user_ns, cred->fsgid), 2064db0a6fb5SRichard Guy Briggs tty ? tty_name(tty) : "(none)", 2065db0a6fb5SRichard Guy Briggs audit_get_sessionid(tsk)); 2066db0a6fb5SRichard Guy Briggs audit_put_tty(tty); 2067b24a30a7SEric Paris audit_log_format(ab, " comm="); 20689eab339bSRichard Guy Briggs audit_log_untrustedstring(ab, get_task_comm(comm, tsk)); 20694766b199SDavidlohr Bueso audit_log_d_path_exe(ab, tsk->mm); 2070b24a30a7SEric Paris audit_log_task_context(ab); 2071b24a30a7SEric Paris } 2072b24a30a7SEric Paris EXPORT_SYMBOL(audit_log_task_info); 2073b24a30a7SEric Paris 2074b0dd25a8SRandy Dunlap /** 2075a51d9eaaSKees Cook * audit_log_link_denied - report a link restriction denial 207622011964SShailendra Verma * @operation: specific link operation 2077a51d9eaaSKees Cook * @link: the path that triggered the restriction 2078a51d9eaaSKees Cook */ 2079a51d9eaaSKees Cook void audit_log_link_denied(const char *operation, struct path *link) 2080a51d9eaaSKees Cook { 2081a51d9eaaSKees Cook struct audit_buffer *ab; 2082b24a30a7SEric Paris struct audit_names *name; 2083a51d9eaaSKees Cook 2084b24a30a7SEric Paris name = kzalloc(sizeof(*name), GFP_NOFS); 2085b24a30a7SEric Paris if (!name) 2086b24a30a7SEric Paris return; 2087b24a30a7SEric Paris 2088b24a30a7SEric Paris /* Generate AUDIT_ANOM_LINK with subject, operation, outcome. */ 2089a51d9eaaSKees Cook ab = audit_log_start(current->audit_context, GFP_KERNEL, 2090a51d9eaaSKees Cook AUDIT_ANOM_LINK); 2091d1c7d97aSSasha Levin if (!ab) 2092b24a30a7SEric Paris goto out; 2093b24a30a7SEric Paris audit_log_format(ab, "op=%s", operation); 2094b24a30a7SEric Paris audit_log_task_info(ab, current); 2095b24a30a7SEric Paris audit_log_format(ab, " res=0"); 2096a51d9eaaSKees Cook audit_log_end(ab); 2097b24a30a7SEric Paris 2098b24a30a7SEric Paris /* Generate AUDIT_PATH record with object. */ 2099b24a30a7SEric Paris name->type = AUDIT_TYPE_NORMAL; 21003b362157SDavid Howells audit_copy_inode(name, link->dentry, d_backing_inode(link->dentry)); 2101b24a30a7SEric Paris audit_log_name(current->audit_context, name, link, 0, NULL); 2102b24a30a7SEric Paris out: 2103b24a30a7SEric Paris kfree(name); 2104a51d9eaaSKees Cook } 2105a51d9eaaSKees Cook 2106a51d9eaaSKees Cook /** 2107b0dd25a8SRandy Dunlap * audit_log_end - end one audit record 2108b0dd25a8SRandy Dunlap * @ab: the audit_buffer 2109b0dd25a8SRandy Dunlap * 21104aa83872SPaul Moore * We can not do a netlink send inside an irq context because it blocks (last 21114aa83872SPaul Moore * arg, flags, is not set to MSG_DONTWAIT), so the audit buffer is placed on a 21124aa83872SPaul Moore * queue and a tasklet is scheduled to remove them from the queue outside the 21134aa83872SPaul Moore * irq context. May be called in any context. 2114b0dd25a8SRandy Dunlap */ 2115b7d11258SDavid Woodhouse void audit_log_end(struct audit_buffer *ab) 21161da177e4SLinus Torvalds { 21171da177e4SLinus Torvalds if (!ab) 21181da177e4SLinus Torvalds return; 21191da177e4SLinus Torvalds if (!audit_rate_check()) { 21201da177e4SLinus Torvalds audit_log_lost("rate limit exceeded"); 21211da177e4SLinus Torvalds } else { 2122af8b824fSPaul Moore skb_queue_tail(&audit_queue, ab->skb); 2123b7d11258SDavid Woodhouse wake_up_interruptible(&kauditd_wait); 2124f3d357b0SEric Paris ab->skb = NULL; 21251da177e4SLinus Torvalds } 212616e1904eSChris Wright audit_buffer_free(ab); 21271da177e4SLinus Torvalds } 21281da177e4SLinus Torvalds 2129b0dd25a8SRandy Dunlap /** 2130b0dd25a8SRandy Dunlap * audit_log - Log an audit record 2131b0dd25a8SRandy Dunlap * @ctx: audit context 2132b0dd25a8SRandy Dunlap * @gfp_mask: type of allocation 2133b0dd25a8SRandy Dunlap * @type: audit message type 2134b0dd25a8SRandy Dunlap * @fmt: format string to use 2135b0dd25a8SRandy Dunlap * @...: variable parameters matching the format string 2136b0dd25a8SRandy Dunlap * 2137b0dd25a8SRandy Dunlap * This is a convenience function that calls audit_log_start, 2138b0dd25a8SRandy Dunlap * audit_log_vformat, and audit_log_end. It may be called 2139b0dd25a8SRandy Dunlap * in any context. 2140b0dd25a8SRandy Dunlap */ 21419796fdd8SAl Viro void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, 21429ad9ad38SDavid Woodhouse const char *fmt, ...) 21431da177e4SLinus Torvalds { 21441da177e4SLinus Torvalds struct audit_buffer *ab; 21451da177e4SLinus Torvalds va_list args; 21461da177e4SLinus Torvalds 21479ad9ad38SDavid Woodhouse ab = audit_log_start(ctx, gfp_mask, type); 21481da177e4SLinus Torvalds if (ab) { 21491da177e4SLinus Torvalds va_start(args, fmt); 21501da177e4SLinus Torvalds audit_log_vformat(ab, fmt, args); 21511da177e4SLinus Torvalds va_end(args); 21521da177e4SLinus Torvalds audit_log_end(ab); 21531da177e4SLinus Torvalds } 21541da177e4SLinus Torvalds } 2155bf45da97Slorenzo@gnu.org 2156131ad62dSMr Dash Four #ifdef CONFIG_SECURITY 2157131ad62dSMr Dash Four /** 2158131ad62dSMr Dash Four * audit_log_secctx - Converts and logs SELinux context 2159131ad62dSMr Dash Four * @ab: audit_buffer 2160131ad62dSMr Dash Four * @secid: security number 2161131ad62dSMr Dash Four * 2162131ad62dSMr Dash Four * This is a helper function that calls security_secid_to_secctx to convert 2163131ad62dSMr Dash Four * secid to secctx and then adds the (converted) SELinux context to the audit 2164131ad62dSMr Dash Four * log by calling audit_log_format, thus also preventing leak of internal secid 2165131ad62dSMr Dash Four * to userspace. If secid cannot be converted audit_panic is called. 2166131ad62dSMr Dash Four */ 2167131ad62dSMr Dash Four void audit_log_secctx(struct audit_buffer *ab, u32 secid) 2168131ad62dSMr Dash Four { 2169131ad62dSMr Dash Four u32 len; 2170131ad62dSMr Dash Four char *secctx; 2171131ad62dSMr Dash Four 2172131ad62dSMr Dash Four if (security_secid_to_secctx(secid, &secctx, &len)) { 2173131ad62dSMr Dash Four audit_panic("Cannot convert secid to context"); 2174131ad62dSMr Dash Four } else { 2175131ad62dSMr Dash Four audit_log_format(ab, " obj=%s", secctx); 2176131ad62dSMr Dash Four security_release_secctx(secctx, len); 2177131ad62dSMr Dash Four } 2178131ad62dSMr Dash Four } 2179131ad62dSMr Dash Four EXPORT_SYMBOL(audit_log_secctx); 2180131ad62dSMr Dash Four #endif 2181131ad62dSMr Dash Four 2182bf45da97Slorenzo@gnu.org EXPORT_SYMBOL(audit_log_start); 2183bf45da97Slorenzo@gnu.org EXPORT_SYMBOL(audit_log_end); 2184bf45da97Slorenzo@gnu.org EXPORT_SYMBOL(audit_log_format); 2185bf45da97Slorenzo@gnu.org EXPORT_SYMBOL(audit_log); 2186