1fe7752baSDavid Woodhouse /* audit -- definition of audit_context structure and supporting types 2fe7752baSDavid Woodhouse * 3fe7752baSDavid Woodhouse * Copyright 2003-2004 Red Hat, Inc. 4fe7752baSDavid Woodhouse * Copyright 2005 Hewlett-Packard Development Company, L.P. 5fe7752baSDavid Woodhouse * Copyright 2005 IBM Corporation 6fe7752baSDavid Woodhouse * 7fe7752baSDavid Woodhouse * This program is free software; you can redistribute it and/or modify 8fe7752baSDavid Woodhouse * it under the terms of the GNU General Public License as published by 9fe7752baSDavid Woodhouse * the Free Software Foundation; either version 2 of the License, or 10fe7752baSDavid Woodhouse * (at your option) any later version. 11fe7752baSDavid Woodhouse * 12fe7752baSDavid Woodhouse * This program is distributed in the hope that it will be useful, 13fe7752baSDavid Woodhouse * but WITHOUT ANY WARRANTY; without even the implied warranty of 14fe7752baSDavid Woodhouse * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15fe7752baSDavid Woodhouse * GNU General Public License for more details. 16fe7752baSDavid Woodhouse * 17fe7752baSDavid Woodhouse * You should have received a copy of the GNU General Public License 18fe7752baSDavid Woodhouse * along with this program; if not, write to the Free Software 19fe7752baSDavid Woodhouse * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20fe7752baSDavid Woodhouse */ 21fe7752baSDavid Woodhouse 22fe7752baSDavid Woodhouse #include <linux/fs.h> 23fe7752baSDavid Woodhouse #include <linux/audit.h> 249044e6bcSAl Viro #include <linux/skbuff.h> 25*b24a30a7SEric Paris #include <uapi/linux/mqueue.h> 26fe7752baSDavid Woodhouse 27fe7752baSDavid Woodhouse /* 0 = no checking 28fe7752baSDavid Woodhouse 1 = put_count checking 29fe7752baSDavid Woodhouse 2 = verbose put_count checking 30fe7752baSDavid Woodhouse */ 31fe7752baSDavid Woodhouse #define AUDIT_DEBUG 0 32fe7752baSDavid Woodhouse 33*b24a30a7SEric Paris /* AUDIT_NAMES is the number of slots we reserve in the audit_context 34*b24a30a7SEric Paris * for saving names from getname(). If we get more names we will allocate 35*b24a30a7SEric Paris * a name dynamically and also add those to the list anchored by names_list. */ 36*b24a30a7SEric Paris #define AUDIT_NAMES 5 37*b24a30a7SEric Paris 38fe7752baSDavid Woodhouse /* At task start time, the audit_state is set in the audit_context using 39fe7752baSDavid Woodhouse a per-task filter. At syscall entry, the audit_state is augmented by 40fe7752baSDavid Woodhouse the syscall filter. */ 41fe7752baSDavid Woodhouse enum audit_state { 42fe7752baSDavid Woodhouse AUDIT_DISABLED, /* Do not create per-task audit_context. 43fe7752baSDavid Woodhouse * No syscall-specific audit records can 44fe7752baSDavid Woodhouse * be generated. */ 45fe7752baSDavid Woodhouse AUDIT_BUILD_CONTEXT, /* Create the per-task audit_context, 46997f5b64SEric Paris * and fill it in at syscall 47fe7752baSDavid Woodhouse * entry time. This makes a full 48fe7752baSDavid Woodhouse * syscall record available if some 49fe7752baSDavid Woodhouse * other part of the kernel decides it 50fe7752baSDavid Woodhouse * should be recorded. */ 51fe7752baSDavid Woodhouse AUDIT_RECORD_CONTEXT /* Create the per-task audit_context, 52fe7752baSDavid Woodhouse * always fill it in at syscall entry 53fe7752baSDavid Woodhouse * time, and always write out the audit 54fe7752baSDavid Woodhouse * record at syscall exit time. */ 55fe7752baSDavid Woodhouse }; 56fe7752baSDavid Woodhouse 57fe7752baSDavid Woodhouse /* Rule lists */ 58cfcad62cSEric Paris struct audit_watch; 5974c3cbe3SAl Viro struct audit_tree; 6074c3cbe3SAl Viro struct audit_chunk; 6174c3cbe3SAl Viro 62fe7752baSDavid Woodhouse struct audit_entry { 63fe7752baSDavid Woodhouse struct list_head list; 64fe7752baSDavid Woodhouse struct rcu_head rcu; 6593315ed6SAmy Griffis struct audit_krule rule; 66fe7752baSDavid Woodhouse }; 67fe7752baSDavid Woodhouse 68*b24a30a7SEric Paris struct audit_cap_data { 69*b24a30a7SEric Paris kernel_cap_t permitted; 70*b24a30a7SEric Paris kernel_cap_t inheritable; 71*b24a30a7SEric Paris union { 72*b24a30a7SEric Paris unsigned int fE; /* effective bit of file cap */ 73*b24a30a7SEric Paris kernel_cap_t effective; /* effective set of process */ 74*b24a30a7SEric Paris }; 75*b24a30a7SEric Paris }; 76*b24a30a7SEric Paris 77*b24a30a7SEric Paris /* When fs/namei.c:getname() is called, we store the pointer in name and 78*b24a30a7SEric Paris * we don't let putname() free it (instead we free all of the saved 79*b24a30a7SEric Paris * pointers at syscall exit time). 80*b24a30a7SEric Paris * 81*b24a30a7SEric Paris * Further, in fs/namei.c:path_lookup() we store the inode and device. 82*b24a30a7SEric Paris */ 83*b24a30a7SEric Paris struct audit_names { 84*b24a30a7SEric Paris struct list_head list; /* audit_context->names_list */ 85*b24a30a7SEric Paris 86*b24a30a7SEric Paris struct filename *name; 87*b24a30a7SEric Paris int name_len; /* number of chars to log */ 88*b24a30a7SEric Paris bool name_put; /* call __putname()? */ 89*b24a30a7SEric Paris 90*b24a30a7SEric Paris unsigned long ino; 91*b24a30a7SEric Paris dev_t dev; 92*b24a30a7SEric Paris umode_t mode; 93*b24a30a7SEric Paris kuid_t uid; 94*b24a30a7SEric Paris kgid_t gid; 95*b24a30a7SEric Paris dev_t rdev; 96*b24a30a7SEric Paris u32 osid; 97*b24a30a7SEric Paris struct audit_cap_data fcap; 98*b24a30a7SEric Paris unsigned int fcap_ver; 99*b24a30a7SEric Paris unsigned char type; /* record type */ 100*b24a30a7SEric Paris /* 101*b24a30a7SEric Paris * This was an allocated audit_names and not from the array of 102*b24a30a7SEric Paris * names allocated in the task audit context. Thus this name 103*b24a30a7SEric Paris * should be freed on syscall exit. 104*b24a30a7SEric Paris */ 105*b24a30a7SEric Paris bool should_free; 106*b24a30a7SEric Paris }; 107*b24a30a7SEric Paris 108*b24a30a7SEric Paris /* The per-task audit context. */ 109*b24a30a7SEric Paris struct audit_context { 110*b24a30a7SEric Paris int dummy; /* must be the first element */ 111*b24a30a7SEric Paris int in_syscall; /* 1 if task is in a syscall */ 112*b24a30a7SEric Paris enum audit_state state, current_state; 113*b24a30a7SEric Paris unsigned int serial; /* serial number for record */ 114*b24a30a7SEric Paris int major; /* syscall number */ 115*b24a30a7SEric Paris struct timespec ctime; /* time of syscall entry */ 116*b24a30a7SEric Paris unsigned long argv[4]; /* syscall arguments */ 117*b24a30a7SEric Paris long return_code;/* syscall return code */ 118*b24a30a7SEric Paris u64 prio; 119*b24a30a7SEric Paris int return_valid; /* return code is valid */ 120*b24a30a7SEric Paris /* 121*b24a30a7SEric Paris * The names_list is the list of all audit_names collected during this 122*b24a30a7SEric Paris * syscall. The first AUDIT_NAMES entries in the names_list will 123*b24a30a7SEric Paris * actually be from the preallocated_names array for performance 124*b24a30a7SEric Paris * reasons. Except during allocation they should never be referenced 125*b24a30a7SEric Paris * through the preallocated_names array and should only be found/used 126*b24a30a7SEric Paris * by running the names_list. 127*b24a30a7SEric Paris */ 128*b24a30a7SEric Paris struct audit_names preallocated_names[AUDIT_NAMES]; 129*b24a30a7SEric Paris int name_count; /* total records in names_list */ 130*b24a30a7SEric Paris struct list_head names_list; /* struct audit_names->list anchor */ 131*b24a30a7SEric Paris char *filterkey; /* key for rule that triggered record */ 132*b24a30a7SEric Paris struct path pwd; 133*b24a30a7SEric Paris struct audit_aux_data *aux; 134*b24a30a7SEric Paris struct audit_aux_data *aux_pids; 135*b24a30a7SEric Paris struct sockaddr_storage *sockaddr; 136*b24a30a7SEric Paris size_t sockaddr_len; 137*b24a30a7SEric Paris /* Save things to print about task_struct */ 138*b24a30a7SEric Paris pid_t pid, ppid; 139*b24a30a7SEric Paris kuid_t uid, euid, suid, fsuid; 140*b24a30a7SEric Paris kgid_t gid, egid, sgid, fsgid; 141*b24a30a7SEric Paris unsigned long personality; 142*b24a30a7SEric Paris int arch; 143*b24a30a7SEric Paris 144*b24a30a7SEric Paris pid_t target_pid; 145*b24a30a7SEric Paris kuid_t target_auid; 146*b24a30a7SEric Paris kuid_t target_uid; 147*b24a30a7SEric Paris unsigned int target_sessionid; 148*b24a30a7SEric Paris u32 target_sid; 149*b24a30a7SEric Paris char target_comm[TASK_COMM_LEN]; 150*b24a30a7SEric Paris 151*b24a30a7SEric Paris struct audit_tree_refs *trees, *first_trees; 152*b24a30a7SEric Paris struct list_head killed_trees; 153*b24a30a7SEric Paris int tree_count; 154*b24a30a7SEric Paris 155*b24a30a7SEric Paris int type; 156*b24a30a7SEric Paris union { 157*b24a30a7SEric Paris struct { 158*b24a30a7SEric Paris int nargs; 159*b24a30a7SEric Paris long args[6]; 160*b24a30a7SEric Paris } socketcall; 161*b24a30a7SEric Paris struct { 162*b24a30a7SEric Paris kuid_t uid; 163*b24a30a7SEric Paris kgid_t gid; 164*b24a30a7SEric Paris umode_t mode; 165*b24a30a7SEric Paris u32 osid; 166*b24a30a7SEric Paris int has_perm; 167*b24a30a7SEric Paris uid_t perm_uid; 168*b24a30a7SEric Paris gid_t perm_gid; 169*b24a30a7SEric Paris umode_t perm_mode; 170*b24a30a7SEric Paris unsigned long qbytes; 171*b24a30a7SEric Paris } ipc; 172*b24a30a7SEric Paris struct { 173*b24a30a7SEric Paris mqd_t mqdes; 174*b24a30a7SEric Paris struct mq_attr mqstat; 175*b24a30a7SEric Paris } mq_getsetattr; 176*b24a30a7SEric Paris struct { 177*b24a30a7SEric Paris mqd_t mqdes; 178*b24a30a7SEric Paris int sigev_signo; 179*b24a30a7SEric Paris } mq_notify; 180*b24a30a7SEric Paris struct { 181*b24a30a7SEric Paris mqd_t mqdes; 182*b24a30a7SEric Paris size_t msg_len; 183*b24a30a7SEric Paris unsigned int msg_prio; 184*b24a30a7SEric Paris struct timespec abs_timeout; 185*b24a30a7SEric Paris } mq_sendrecv; 186*b24a30a7SEric Paris struct { 187*b24a30a7SEric Paris int oflag; 188*b24a30a7SEric Paris umode_t mode; 189*b24a30a7SEric Paris struct mq_attr attr; 190*b24a30a7SEric Paris } mq_open; 191*b24a30a7SEric Paris struct { 192*b24a30a7SEric Paris pid_t pid; 193*b24a30a7SEric Paris struct audit_cap_data cap; 194*b24a30a7SEric Paris } capset; 195*b24a30a7SEric Paris struct { 196*b24a30a7SEric Paris int fd; 197*b24a30a7SEric Paris int flags; 198*b24a30a7SEric Paris } mmap; 199*b24a30a7SEric Paris }; 200*b24a30a7SEric Paris int fds[2]; 201*b24a30a7SEric Paris 202*b24a30a7SEric Paris #if AUDIT_DEBUG 203*b24a30a7SEric Paris int put_count; 204*b24a30a7SEric Paris int ino_count; 205*b24a30a7SEric Paris #endif 206*b24a30a7SEric Paris }; 207*b24a30a7SEric Paris 208c782f242SHarvey Harrison #ifdef CONFIG_AUDIT 209*b24a30a7SEric Paris extern int audit_enabled; 210c782f242SHarvey Harrison extern int audit_ever_enabled; 211*b24a30a7SEric Paris 212*b24a30a7SEric Paris extern void audit_copy_inode(struct audit_names *name, 213*b24a30a7SEric Paris const struct dentry *dentry, 214*b24a30a7SEric Paris const struct inode *inode); 215*b24a30a7SEric Paris extern void audit_log_cap(struct audit_buffer *ab, char *prefix, 216*b24a30a7SEric Paris kernel_cap_t *cap); 217*b24a30a7SEric Paris extern void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name); 218*b24a30a7SEric Paris extern void audit_log_name(struct audit_context *context, 219*b24a30a7SEric Paris struct audit_names *n, struct path *path, 220*b24a30a7SEric Paris int record_num, int *call_panic); 221c782f242SHarvey Harrison #endif 222c782f242SHarvey Harrison 223fe7752baSDavid Woodhouse extern int audit_pid; 224fe7752baSDavid Woodhouse 225f368c07dSAmy Griffis #define AUDIT_INODE_BUCKETS 32 226f368c07dSAmy Griffis extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; 227f368c07dSAmy Griffis 228f368c07dSAmy Griffis static inline int audit_hash_ino(u32 ino) 229f368c07dSAmy Griffis { 230f368c07dSAmy Griffis return (ino & (AUDIT_INODE_BUCKETS-1)); 231f368c07dSAmy Griffis } 232f368c07dSAmy Griffis 233e3d6b07bSJeff Layton /* Indicates that audit should log the full pathname. */ 234e3d6b07bSJeff Layton #define AUDIT_NAME_FULL -1 235e3d6b07bSJeff Layton 23655669bfaSAl Viro extern int audit_match_class(int class, unsigned syscall); 237f368c07dSAmy Griffis extern int audit_comparator(const u32 left, const u32 op, const u32 right); 238ca57ec0fSEric W. Biederman extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right); 239ca57ec0fSEric W. Biederman extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right); 240bfcec708SJeff Layton extern int parent_len(const char *path); 241e3d6b07bSJeff Layton extern int audit_compare_dname_path(const char *dname, const char *path, int plen); 2429044e6bcSAl Viro extern struct sk_buff * audit_make_reply(int pid, int seq, int type, 2439044e6bcSAl Viro int done, int multi, 244b8800aa5SStephen Hemminger const void *payload, int size); 245fe7752baSDavid Woodhouse extern void audit_panic(const char *message); 2463dc7e315SDarrel Goeddel 2479044e6bcSAl Viro struct audit_netlink_list { 2489044e6bcSAl Viro int pid; 2499044e6bcSAl Viro struct sk_buff_head q; 2509044e6bcSAl Viro }; 2519044e6bcSAl Viro 2529044e6bcSAl Viro int audit_send_list(void *); 2539044e6bcSAl Viro 2543dc7e315SDarrel Goeddel extern int selinux_audit_rule_update(void); 255e1396065SAl Viro 25674c3cbe3SAl Viro extern struct mutex audit_filter_mutex; 25774c3cbe3SAl Viro extern void audit_free_rule_rcu(struct rcu_head *); 258c782f242SHarvey Harrison extern struct list_head audit_filter_list[]; 25974c3cbe3SAl Viro 260939a67fcSEric Paris extern struct audit_entry *audit_dupe_rule(struct audit_krule *old); 261939a67fcSEric Paris 262cfcad62cSEric Paris /* audit watch functions */ 263939a67fcSEric Paris #ifdef CONFIG_AUDIT_WATCH 264cfcad62cSEric Paris extern void audit_put_watch(struct audit_watch *watch); 265cfcad62cSEric Paris extern void audit_get_watch(struct audit_watch *watch); 266cfcad62cSEric Paris extern int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 op); 267ae7b8f41SEric Paris extern int audit_add_watch(struct audit_krule *krule, struct list_head **list); 268a05fb6ccSEric Paris extern void audit_remove_watch_rule(struct audit_krule *krule); 269cfcad62cSEric Paris extern char *audit_watch_path(struct audit_watch *watch); 270ae7b8f41SEric Paris extern int audit_watch_compare(struct audit_watch *watch, unsigned long ino, dev_t dev); 271939a67fcSEric Paris #else 272939a67fcSEric Paris #define audit_put_watch(w) {} 273939a67fcSEric Paris #define audit_get_watch(w) {} 274939a67fcSEric Paris #define audit_to_watch(k, p, l, o) (-EINVAL) 275939a67fcSEric Paris #define audit_add_watch(k, l) (-EINVAL) 276939a67fcSEric Paris #define audit_remove_watch_rule(k) BUG() 277939a67fcSEric Paris #define audit_watch_path(w) "" 278939a67fcSEric Paris #define audit_watch_compare(w, i, d) 0 279939a67fcSEric Paris 280939a67fcSEric Paris #endif /* CONFIG_AUDIT_WATCH */ 281cfcad62cSEric Paris 28274c3cbe3SAl Viro #ifdef CONFIG_AUDIT_TREE 28374c3cbe3SAl Viro extern struct audit_chunk *audit_tree_lookup(const struct inode *); 28474c3cbe3SAl Viro extern void audit_put_chunk(struct audit_chunk *); 28574c3cbe3SAl Viro extern int audit_tree_match(struct audit_chunk *, struct audit_tree *); 28674c3cbe3SAl Viro extern int audit_make_tree(struct audit_krule *, char *, u32); 28774c3cbe3SAl Viro extern int audit_add_tree_rule(struct audit_krule *); 28874c3cbe3SAl Viro extern int audit_remove_tree_rule(struct audit_krule *); 28974c3cbe3SAl Viro extern void audit_trim_trees(void); 29074c3cbe3SAl Viro extern int audit_tag_tree(char *old, char *new); 29174c3cbe3SAl Viro extern const char *audit_tree_path(struct audit_tree *); 29274c3cbe3SAl Viro extern void audit_put_tree(struct audit_tree *); 293916d7576SAl Viro extern void audit_kill_trees(struct list_head *); 29474c3cbe3SAl Viro #else 29574c3cbe3SAl Viro #define audit_remove_tree_rule(rule) BUG() 29674c3cbe3SAl Viro #define audit_add_tree_rule(rule) -EINVAL 29774c3cbe3SAl Viro #define audit_make_tree(rule, str, op) -EINVAL 29874c3cbe3SAl Viro #define audit_trim_trees() (void)0 29974c3cbe3SAl Viro #define audit_put_tree(tree) (void)0 30074c3cbe3SAl Viro #define audit_tag_tree(old, new) -EINVAL 30174c3cbe3SAl Viro #define audit_tree_path(rule) "" /* never called */ 302916d7576SAl Viro #define audit_kill_trees(list) BUG() 30374c3cbe3SAl Viro #endif 30474c3cbe3SAl Viro 30574c3cbe3SAl Viro extern char *audit_unpack_string(void **, size_t *, size_t); 30674c3cbe3SAl Viro 307c782f242SHarvey Harrison extern pid_t audit_sig_pid; 308cca080d9SEric W. Biederman extern kuid_t audit_sig_uid; 309c782f242SHarvey Harrison extern u32 audit_sig_sid; 310c782f242SHarvey Harrison 311e1396065SAl Viro #ifdef CONFIG_AUDITSYSCALL 312e54dc243SAmy Griffis extern int __audit_signal_info(int sig, struct task_struct *t); 313e54dc243SAmy Griffis static inline int audit_signal_info(int sig, struct task_struct *t) 314e1396065SAl Viro { 315e54dc243SAmy Griffis if (unlikely((audit_pid && t->tgid == audit_pid) || 316e54dc243SAmy Griffis (audit_signals && !audit_dummy_context()))) 317e54dc243SAmy Griffis return __audit_signal_info(sig, t); 318e54dc243SAmy Griffis return 0; 319e1396065SAl Viro } 3200590b933SAl Viro extern void audit_filter_inodes(struct task_struct *, struct audit_context *); 321916d7576SAl Viro extern struct list_head *audit_killed_trees(void); 322e1396065SAl Viro #else 323e54dc243SAmy Griffis #define audit_signal_info(s,t) AUDIT_DISABLED 324f368c07dSAmy Griffis #define audit_filter_inodes(t,c) AUDIT_DISABLED 325e1396065SAl Viro #endif 326916d7576SAl Viro 327916d7576SAl Viro extern struct mutex audit_cmd_mutex; 328