11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 2fe7752baSDavid Woodhouse /* audit -- definition of audit_context structure and supporting types 3fe7752baSDavid Woodhouse * 4fe7752baSDavid Woodhouse * Copyright 2003-2004 Red Hat, Inc. 5fe7752baSDavid Woodhouse * Copyright 2005 Hewlett-Packard Development Company, L.P. 6fe7752baSDavid Woodhouse * Copyright 2005 IBM Corporation 7fe7752baSDavid Woodhouse */ 8fe7752baSDavid Woodhouse 9*d97e9938SMaYuming #ifndef _KERNEL_AUDIT_H_ 10*d97e9938SMaYuming #define _KERNEL_AUDIT_H_ 11*d97e9938SMaYuming 12fe7752baSDavid Woodhouse #include <linux/fs.h> 13fe7752baSDavid Woodhouse #include <linux/audit.h> 149044e6bcSAl Viro #include <linux/skbuff.h> 15b24a30a7SEric Paris #include <uapi/linux/mqueue.h> 163f5be2daSRichard Guy Briggs #include <linux/tty.h> 17fe7752baSDavid Woodhouse 18b24a30a7SEric Paris /* AUDIT_NAMES is the number of slots we reserve in the audit_context 19b24a30a7SEric Paris * for saving names from getname(). If we get more names we will allocate 20b24a30a7SEric Paris * a name dynamically and also add those to the list anchored by names_list. */ 21b24a30a7SEric Paris #define AUDIT_NAMES 5 22b24a30a7SEric Paris 23fe7752baSDavid Woodhouse /* At task start time, the audit_state is set in the audit_context using 24fe7752baSDavid Woodhouse a per-task filter. At syscall entry, the audit_state is augmented by 25fe7752baSDavid Woodhouse the syscall filter. */ 26fe7752baSDavid Woodhouse enum audit_state { 27619ed58aSSergey Nazarov AUDIT_STATE_DISABLED, /* Do not create per-task audit_context. 28fe7752baSDavid Woodhouse * No syscall-specific audit records can 29fe7752baSDavid Woodhouse * be generated. */ 30619ed58aSSergey Nazarov AUDIT_STATE_BUILD, /* Create the per-task audit_context, 31997f5b64SEric Paris * and fill it in at syscall 32fe7752baSDavid Woodhouse * entry time. This makes a full 33fe7752baSDavid Woodhouse * syscall record available if some 34fe7752baSDavid Woodhouse * other part of the kernel decides it 35fe7752baSDavid Woodhouse * should be recorded. */ 36619ed58aSSergey Nazarov AUDIT_STATE_RECORD /* Create the per-task audit_context, 37fe7752baSDavid Woodhouse * always fill it in at syscall entry 38fe7752baSDavid Woodhouse * time, and always write out the audit 39fe7752baSDavid Woodhouse * record at syscall exit time. */ 40fe7752baSDavid Woodhouse }; 41fe7752baSDavid Woodhouse 42fe7752baSDavid Woodhouse /* Rule lists */ 43cfcad62cSEric Paris struct audit_watch; 447f492942SRichard Guy Briggs struct audit_fsnotify_mark; 4574c3cbe3SAl Viro struct audit_tree; 4674c3cbe3SAl Viro struct audit_chunk; 4774c3cbe3SAl Viro 48fe7752baSDavid Woodhouse struct audit_entry { 49fe7752baSDavid Woodhouse struct list_head list; 50fe7752baSDavid Woodhouse struct rcu_head rcu; 5193315ed6SAmy Griffis struct audit_krule rule; 52fe7752baSDavid Woodhouse }; 53fe7752baSDavid Woodhouse 54b24a30a7SEric Paris struct audit_cap_data { 55b24a30a7SEric Paris kernel_cap_t permitted; 56b24a30a7SEric Paris kernel_cap_t inheritable; 57b24a30a7SEric Paris union { 58b24a30a7SEric Paris unsigned int fE; /* effective bit of file cap */ 59b24a30a7SEric Paris kernel_cap_t effective; /* effective set of process */ 60b24a30a7SEric Paris }; 617786f6b6SRichard Guy Briggs kernel_cap_t ambient; 622fec30e2SRichard Guy Briggs kuid_t rootid; 63b24a30a7SEric Paris }; 64b24a30a7SEric Paris 6555422d0bSPaul Moore /* When fs/namei.c:getname() is called, we store the pointer in name and bump 6655422d0bSPaul Moore * the refcnt in the associated filename struct. 67b24a30a7SEric Paris * 68b24a30a7SEric Paris * Further, in fs/namei.c:path_lookup() we store the inode and device. 69b24a30a7SEric Paris */ 70b24a30a7SEric Paris struct audit_names { 71b24a30a7SEric Paris struct list_head list; /* audit_context->names_list */ 72b24a30a7SEric Paris 73b24a30a7SEric Paris struct filename *name; 74b24a30a7SEric Paris int name_len; /* number of chars to log */ 7579f6530cSJeff Layton bool hidden; /* don't log this record */ 76b24a30a7SEric Paris 77b24a30a7SEric Paris unsigned long ino; 78b24a30a7SEric Paris dev_t dev; 79b24a30a7SEric Paris umode_t mode; 80b24a30a7SEric Paris kuid_t uid; 81b24a30a7SEric Paris kgid_t gid; 82b24a30a7SEric Paris dev_t rdev; 83b24a30a7SEric Paris u32 osid; 84b24a30a7SEric Paris struct audit_cap_data fcap; 85b24a30a7SEric Paris unsigned int fcap_ver; 86b24a30a7SEric Paris unsigned char type; /* record type */ 87b24a30a7SEric Paris /* 88b24a30a7SEric Paris * This was an allocated audit_names and not from the array of 89b24a30a7SEric Paris * names allocated in the task audit context. Thus this name 90b24a30a7SEric Paris * should be freed on syscall exit. 91b24a30a7SEric Paris */ 92b24a30a7SEric Paris bool should_free; 93b24a30a7SEric Paris }; 94b24a30a7SEric Paris 953f1c8250SWilliam Roberts struct audit_proctitle { 963f1c8250SWilliam Roberts int len; /* length of the cmdline field. */ 973f1c8250SWilliam Roberts char *value; /* the cmdline field */ 983f1c8250SWilliam Roberts }; 993f1c8250SWilliam Roberts 100b24a30a7SEric Paris /* The per-task audit context. */ 101b24a30a7SEric Paris struct audit_context { 102b24a30a7SEric Paris int dummy; /* must be the first element */ 103b24a30a7SEric Paris int in_syscall; /* 1 if task is in a syscall */ 104b24a30a7SEric Paris enum audit_state state, current_state; 105b24a30a7SEric Paris unsigned int serial; /* serial number for record */ 106b24a30a7SEric Paris int major; /* syscall number */ 1072115bb25SDeepa Dinamani struct timespec64 ctime; /* time of syscall entry */ 108b24a30a7SEric Paris unsigned long argv[4]; /* syscall arguments */ 109b24a30a7SEric Paris long return_code;/* syscall return code */ 110b24a30a7SEric Paris u64 prio; 111b24a30a7SEric Paris int return_valid; /* return code is valid */ 112b24a30a7SEric Paris /* 113b24a30a7SEric Paris * The names_list is the list of all audit_names collected during this 114b24a30a7SEric Paris * syscall. The first AUDIT_NAMES entries in the names_list will 115b24a30a7SEric Paris * actually be from the preallocated_names array for performance 116b24a30a7SEric Paris * reasons. Except during allocation they should never be referenced 117b24a30a7SEric Paris * through the preallocated_names array and should only be found/used 118b24a30a7SEric Paris * by running the names_list. 119b24a30a7SEric Paris */ 120b24a30a7SEric Paris struct audit_names preallocated_names[AUDIT_NAMES]; 121b24a30a7SEric Paris int name_count; /* total records in names_list */ 122b24a30a7SEric Paris struct list_head names_list; /* struct audit_names->list anchor */ 123b24a30a7SEric Paris char *filterkey; /* key for rule that triggered record */ 124b24a30a7SEric Paris struct path pwd; 125b24a30a7SEric Paris struct audit_aux_data *aux; 126b24a30a7SEric Paris struct audit_aux_data *aux_pids; 127b24a30a7SEric Paris struct sockaddr_storage *sockaddr; 128b24a30a7SEric Paris size_t sockaddr_len; 129b24a30a7SEric Paris /* Save things to print about task_struct */ 130b24a30a7SEric Paris pid_t pid, ppid; 131b24a30a7SEric Paris kuid_t uid, euid, suid, fsuid; 132b24a30a7SEric Paris kgid_t gid, egid, sgid, fsgid; 133b24a30a7SEric Paris unsigned long personality; 134b24a30a7SEric Paris int arch; 135b24a30a7SEric Paris 136b24a30a7SEric Paris pid_t target_pid; 137b24a30a7SEric Paris kuid_t target_auid; 138b24a30a7SEric Paris kuid_t target_uid; 139b24a30a7SEric Paris unsigned int target_sessionid; 140b24a30a7SEric Paris u32 target_sid; 141b24a30a7SEric Paris char target_comm[TASK_COMM_LEN]; 142b24a30a7SEric Paris 143b24a30a7SEric Paris struct audit_tree_refs *trees, *first_trees; 144b24a30a7SEric Paris struct list_head killed_trees; 145b24a30a7SEric Paris int tree_count; 146b24a30a7SEric Paris 147b24a30a7SEric Paris int type; 148b24a30a7SEric Paris union { 149b24a30a7SEric Paris struct { 150b24a30a7SEric Paris int nargs; 151b24a30a7SEric Paris long args[6]; 152b24a30a7SEric Paris } socketcall; 153b24a30a7SEric Paris struct { 154b24a30a7SEric Paris kuid_t uid; 155b24a30a7SEric Paris kgid_t gid; 156b24a30a7SEric Paris umode_t mode; 157b24a30a7SEric Paris u32 osid; 158b24a30a7SEric Paris int has_perm; 159b24a30a7SEric Paris uid_t perm_uid; 160b24a30a7SEric Paris gid_t perm_gid; 161b24a30a7SEric Paris umode_t perm_mode; 162b24a30a7SEric Paris unsigned long qbytes; 163b24a30a7SEric Paris } ipc; 164b24a30a7SEric Paris struct { 165b24a30a7SEric Paris mqd_t mqdes; 166b24a30a7SEric Paris struct mq_attr mqstat; 167b24a30a7SEric Paris } mq_getsetattr; 168b24a30a7SEric Paris struct { 169b24a30a7SEric Paris mqd_t mqdes; 170b24a30a7SEric Paris int sigev_signo; 171b24a30a7SEric Paris } mq_notify; 172b24a30a7SEric Paris struct { 173b24a30a7SEric Paris mqd_t mqdes; 174b24a30a7SEric Paris size_t msg_len; 175b24a30a7SEric Paris unsigned int msg_prio; 176b9047726SDeepa Dinamani struct timespec64 abs_timeout; 177b24a30a7SEric Paris } mq_sendrecv; 178b24a30a7SEric Paris struct { 179b24a30a7SEric Paris int oflag; 180b24a30a7SEric Paris umode_t mode; 181b24a30a7SEric Paris struct mq_attr attr; 182b24a30a7SEric Paris } mq_open; 183b24a30a7SEric Paris struct { 184b24a30a7SEric Paris pid_t pid; 185b24a30a7SEric Paris struct audit_cap_data cap; 186b24a30a7SEric Paris } capset; 187b24a30a7SEric Paris struct { 188b24a30a7SEric Paris int fd; 189b24a30a7SEric Paris int flags; 190b24a30a7SEric Paris } mmap; 191d9cfea91SRichard Guy Briggs struct { 192d9cfea91SRichard Guy Briggs int argc; 193d9cfea91SRichard Guy Briggs } execve; 194ca86cad7SRichard Guy Briggs struct { 195ca86cad7SRichard Guy Briggs char *name; 196ca86cad7SRichard Guy Briggs } module; 197b24a30a7SEric Paris }; 198b24a30a7SEric Paris int fds[2]; 1993f1c8250SWilliam Roberts struct audit_proctitle proctitle; 200b24a30a7SEric Paris }; 201b24a30a7SEric Paris 202b3b4fdf6SPaul Moore extern bool audit_ever_enabled; 203c782f242SHarvey Harrison 2040fe3c7fcSRichard Guy Briggs extern void audit_log_session_info(struct audit_buffer *ab); 2050fe3c7fcSRichard Guy Briggs 206b6c7c115SPaul Moore extern int auditd_test_task(struct task_struct *task); 207fe7752baSDavid Woodhouse 208f368c07dSAmy Griffis #define AUDIT_INODE_BUCKETS 32 209f368c07dSAmy Griffis extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; 210f368c07dSAmy Griffis 211f368c07dSAmy Griffis static inline int audit_hash_ino(u32 ino) 212f368c07dSAmy Griffis { 213f368c07dSAmy Griffis return (ino & (AUDIT_INODE_BUCKETS-1)); 214f368c07dSAmy Griffis } 215f368c07dSAmy Griffis 216e3d6b07bSJeff Layton /* Indicates that audit should log the full pathname. */ 217e3d6b07bSJeff Layton #define AUDIT_NAME_FULL -1 218e3d6b07bSJeff Layton 21955669bfaSAl Viro extern int audit_match_class(int class, unsigned syscall); 220f368c07dSAmy Griffis extern int audit_comparator(const u32 left, const u32 op, const u32 right); 221ca57ec0fSEric W. Biederman extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right); 222ca57ec0fSEric W. Biederman extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right); 223bfcec708SJeff Layton extern int parent_len(const char *path); 224795d673aSAl Viro extern int audit_compare_dname_path(const struct qstr *dname, const char *path, int plen); 22545a0642bSPaul Moore extern struct sk_buff *audit_make_reply(int seq, int type, int done, int multi, 226b8800aa5SStephen Hemminger const void *payload, int size); 227fe7752baSDavid Woodhouse extern void audit_panic(const char *message); 2283dc7e315SDarrel Goeddel 2299044e6bcSAl Viro struct audit_netlink_list { 230f9441639SRichard Guy Briggs __u32 portid; 231638a0fd2SEric W. Biederman struct net *net; 2329044e6bcSAl Viro struct sk_buff_head q; 2339044e6bcSAl Viro }; 2349044e6bcSAl Viro 2353054d067SPaul Moore int audit_send_list_thread(void *_dest); 2369044e6bcSAl Viro 2373dc7e315SDarrel Goeddel extern int selinux_audit_rule_update(void); 238e1396065SAl Viro 23974c3cbe3SAl Viro extern struct mutex audit_filter_mutex; 240e4c1a0d1SDerek Robson extern int audit_del_rule(struct audit_entry *entry); 241e4c1a0d1SDerek Robson extern void audit_free_rule_rcu(struct rcu_head *head); 242c782f242SHarvey Harrison extern struct list_head audit_filter_list[]; 24374c3cbe3SAl Viro 244939a67fcSEric Paris extern struct audit_entry *audit_dupe_rule(struct audit_krule *old); 245939a67fcSEric Paris 2464766b199SDavidlohr Bueso extern void audit_log_d_path_exe(struct audit_buffer *ab, 2474766b199SDavidlohr Bueso struct mm_struct *mm); 2484766b199SDavidlohr Bueso 2492a1fe215SPaul Moore extern struct tty_struct *audit_get_tty(void); 2503f5be2daSRichard Guy Briggs extern void audit_put_tty(struct tty_struct *tty); 2513f5be2daSRichard Guy Briggs 25205c7a9cbSRichard Guy Briggs /* audit watch/mark/tree functions */ 253c8fc5d49SRichard Guy Briggs #ifdef CONFIG_AUDITSYSCALL 254cd108b5cSRichard Guy Briggs extern unsigned int audit_serial(void); 255cd108b5cSRichard Guy Briggs extern int auditsc_get_stamp(struct audit_context *ctx, 256cd108b5cSRichard Guy Briggs struct timespec64 *t, unsigned int *serial); 257cd108b5cSRichard Guy Briggs 258cfcad62cSEric Paris extern void audit_put_watch(struct audit_watch *watch); 259cfcad62cSEric Paris extern void audit_get_watch(struct audit_watch *watch); 26005c7a9cbSRichard Guy Briggs extern int audit_to_watch(struct audit_krule *krule, char *path, int len, 26105c7a9cbSRichard Guy Briggs u32 op); 262ae7b8f41SEric Paris extern int audit_add_watch(struct audit_krule *krule, struct list_head **list); 263a05fb6ccSEric Paris extern void audit_remove_watch_rule(struct audit_krule *krule); 264cfcad62cSEric Paris extern char *audit_watch_path(struct audit_watch *watch); 26505c7a9cbSRichard Guy Briggs extern int audit_watch_compare(struct audit_watch *watch, unsigned long ino, 26605c7a9cbSRichard Guy Briggs dev_t dev); 2677f492942SRichard Guy Briggs 26805c7a9cbSRichard Guy Briggs extern struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, 26905c7a9cbSRichard Guy Briggs char *pathname, int len); 2707f492942SRichard Guy Briggs extern char *audit_mark_path(struct audit_fsnotify_mark *mark); 2717f492942SRichard Guy Briggs extern void audit_remove_mark(struct audit_fsnotify_mark *audit_mark); 2727f492942SRichard Guy Briggs extern void audit_remove_mark_rule(struct audit_krule *krule); 27305c7a9cbSRichard Guy Briggs extern int audit_mark_compare(struct audit_fsnotify_mark *mark, 27405c7a9cbSRichard Guy Briggs unsigned long ino, dev_t dev); 27534d99af5SRichard Guy Briggs extern int audit_dupe_exe(struct audit_krule *new, struct audit_krule *old); 27605c7a9cbSRichard Guy Briggs extern int audit_exe_compare(struct task_struct *tsk, 27705c7a9cbSRichard Guy Briggs struct audit_fsnotify_mark *mark); 2787f492942SRichard Guy Briggs 27905c7a9cbSRichard Guy Briggs extern struct audit_chunk *audit_tree_lookup(const struct inode *inode); 28005c7a9cbSRichard Guy Briggs extern void audit_put_chunk(struct audit_chunk *chunk); 28105c7a9cbSRichard Guy Briggs extern bool audit_tree_match(struct audit_chunk *chunk, 28205c7a9cbSRichard Guy Briggs struct audit_tree *tree); 28305c7a9cbSRichard Guy Briggs extern int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op); 28405c7a9cbSRichard Guy Briggs extern int audit_add_tree_rule(struct audit_krule *rule); 28505c7a9cbSRichard Guy Briggs extern int audit_remove_tree_rule(struct audit_krule *rule); 28605c7a9cbSRichard Guy Briggs extern void audit_trim_trees(void); 28705c7a9cbSRichard Guy Briggs extern int audit_tag_tree(char *old, char *new); 28805c7a9cbSRichard Guy Briggs extern const char *audit_tree_path(struct audit_tree *tree); 28905c7a9cbSRichard Guy Briggs extern void audit_put_tree(struct audit_tree *tree); 29005c7a9cbSRichard Guy Briggs extern void audit_kill_trees(struct audit_context *context); 29105c7a9cbSRichard Guy Briggs 292b48345aaSRichard Guy Briggs extern int audit_signal_info_syscall(struct task_struct *t); 29305c7a9cbSRichard Guy Briggs extern void audit_filter_inodes(struct task_struct *tsk, 29405c7a9cbSRichard Guy Briggs struct audit_context *ctx); 29505c7a9cbSRichard Guy Briggs extern struct list_head *audit_killed_trees(void); 29605c7a9cbSRichard Guy Briggs #else /* CONFIG_AUDITSYSCALL */ 297cd108b5cSRichard Guy Briggs #define auditsc_get_stamp(c, t, s) 0 298d4ceb1d6SArnd Bergmann #define audit_put_watch(w) do { } while (0) 299d4ceb1d6SArnd Bergmann #define audit_get_watch(w) do { } while (0) 300939a67fcSEric Paris #define audit_to_watch(k, p, l, o) (-EINVAL) 301939a67fcSEric Paris #define audit_add_watch(k, l) (-EINVAL) 302939a67fcSEric Paris #define audit_remove_watch_rule(k) BUG() 303939a67fcSEric Paris #define audit_watch_path(w) "" 304939a67fcSEric Paris #define audit_watch_compare(w, i, d) 0 305939a67fcSEric Paris 3067f492942SRichard Guy Briggs #define audit_alloc_mark(k, p, l) (ERR_PTR(-EINVAL)) 3077f492942SRichard Guy Briggs #define audit_mark_path(m) "" 308d4ceb1d6SArnd Bergmann #define audit_remove_mark(m) do { } while (0) 309d4ceb1d6SArnd Bergmann #define audit_remove_mark_rule(k) do { } while (0) 3107f492942SRichard Guy Briggs #define audit_mark_compare(m, i, d) 0 31134d99af5SRichard Guy Briggs #define audit_exe_compare(t, m) (-EINVAL) 31234d99af5SRichard Guy Briggs #define audit_dupe_exe(n, o) (-EINVAL) 313cfcad62cSEric Paris 31474c3cbe3SAl Viro #define audit_remove_tree_rule(rule) BUG() 31574c3cbe3SAl Viro #define audit_add_tree_rule(rule) -EINVAL 31674c3cbe3SAl Viro #define audit_make_tree(rule, str, op) -EINVAL 317d4ceb1d6SArnd Bergmann #define audit_trim_trees() do { } while (0) 318d4ceb1d6SArnd Bergmann #define audit_put_tree(tree) do { } while (0) 31974c3cbe3SAl Viro #define audit_tag_tree(old, new) -EINVAL 32074c3cbe3SAl Viro #define audit_tree_path(rule) "" /* never called */ 3219e36a5d4SRichard Guy Briggs #define audit_kill_trees(context) BUG() 32205c7a9cbSRichard Guy Briggs 323b48345aaSRichard Guy Briggs static inline int audit_signal_info_syscall(struct task_struct *t) 324b48345aaSRichard Guy Briggs { 325b48345aaSRichard Guy Briggs return 0; 326b48345aaSRichard Guy Briggs } 327b48345aaSRichard Guy Briggs 328619ed58aSSergey Nazarov #define audit_filter_inodes(t, c) AUDIT_STATE_DISABLED 32905c7a9cbSRichard Guy Briggs #endif /* CONFIG_AUDITSYSCALL */ 33074c3cbe3SAl Viro 331e4c1a0d1SDerek Robson extern char *audit_unpack_string(void **bufp, size_t *remain, size_t len); 33274c3cbe3SAl Viro 33386b2efbeSRichard Guy Briggs extern int audit_filter(int msgtype, unsigned int listtype); 33486b2efbeSRichard Guy Briggs 335ce423631SPaul Moore extern void audit_ctl_lock(void); 336ce423631SPaul Moore extern void audit_ctl_unlock(void); 337*d97e9938SMaYuming 338*d97e9938SMaYuming #endif 339