diff options
author | Eric Paris <eparis@redhat.com> | 2013-04-30 15:30:32 -0400 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2013-04-30 15:31:28 -0400 |
commit | b24a30a7305418ff138ff51776fc555ec57c011a (patch) | |
tree | 2c64cff75b758c3fb407118ab473167fb5bec3fa /kernel/audit.h | |
parent | 7173c54e3a9deb491a586e7e107375109ee48bcb (diff) |
audit: fix event coverage of AUDIT_ANOM_LINK
The userspace audit tools didn't like the existing formatting of the
AUDIT_ANOM_LINK event. It needed to be expanded to emit an AUDIT_PATH
event as well, so this implements the change. The bulk of the patch is
moving code out of auditsc.c into audit.c and audit.h for general use.
It expands audit_log_name to include an optional "struct path" argument
for the simple case of just needing to report a pathname. This also
makes
audit_log_task_info available when syscall auditing is not enabled,
since
it is needed in either case for process details.
Signed-off-by: Kees Cook <keescook@chromium.org>
Reported-by: Steve Grubb <sgrubb@redhat.com>
Diffstat (limited to 'kernel/audit.h')
-rw-r--r-- | kernel/audit.h | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/kernel/audit.h b/kernel/audit.h index d06ffc144f81..45c8325de5bb 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
23 | #include <linux/audit.h> | 23 | #include <linux/audit.h> |
24 | #include <linux/skbuff.h> | 24 | #include <linux/skbuff.h> |
25 | #include <uapi/linux/mqueue.h> | ||
25 | 26 | ||
26 | /* 0 = no checking | 27 | /* 0 = no checking |
27 | 1 = put_count checking | 28 | 1 = put_count checking |
@@ -29,6 +30,11 @@ | |||
29 | */ | 30 | */ |
30 | #define AUDIT_DEBUG 0 | 31 | #define AUDIT_DEBUG 0 |
31 | 32 | ||
33 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context | ||
34 | * for saving names from getname(). If we get more names we will allocate | ||
35 | * a name dynamically and also add those to the list anchored by names_list. */ | ||
36 | #define AUDIT_NAMES 5 | ||
37 | |||
32 | /* At task start time, the audit_state is set in the audit_context using | 38 | /* At task start time, the audit_state is set in the audit_context using |
33 | a per-task filter. At syscall entry, the audit_state is augmented by | 39 | a per-task filter. At syscall entry, the audit_state is augmented by |
34 | the syscall filter. */ | 40 | the syscall filter. */ |
@@ -59,8 +65,159 @@ struct audit_entry { | |||
59 | struct audit_krule rule; | 65 | struct audit_krule rule; |
60 | }; | 66 | }; |
61 | 67 | ||
68 | struct audit_cap_data { | ||
69 | kernel_cap_t permitted; | ||
70 | kernel_cap_t inheritable; | ||
71 | union { | ||
72 | unsigned int fE; /* effective bit of file cap */ | ||
73 | kernel_cap_t effective; /* effective set of process */ | ||
74 | }; | ||
75 | }; | ||
76 | |||
77 | /* When fs/namei.c:getname() is called, we store the pointer in name and | ||
78 | * we don't let putname() free it (instead we free all of the saved | ||
79 | * pointers at syscall exit time). | ||
80 | * | ||
81 | * Further, in fs/namei.c:path_lookup() we store the inode and device. | ||
82 | */ | ||
83 | struct audit_names { | ||
84 | struct list_head list; /* audit_context->names_list */ | ||
85 | |||
86 | struct filename *name; | ||
87 | int name_len; /* number of chars to log */ | ||
88 | bool name_put; /* call __putname()? */ | ||
89 | |||
90 | unsigned long ino; | ||
91 | dev_t dev; | ||
92 | umode_t mode; | ||
93 | kuid_t uid; | ||
94 | kgid_t gid; | ||
95 | dev_t rdev; | ||
96 | u32 osid; | ||
97 | struct audit_cap_data fcap; | ||
98 | unsigned int fcap_ver; | ||
99 | unsigned char type; /* record type */ | ||
100 | /* | ||
101 | * This was an allocated audit_names and not from the array of | ||
102 | * names allocated in the task audit context. Thus this name | ||
103 | * should be freed on syscall exit. | ||
104 | */ | ||
105 | bool should_free; | ||
106 | }; | ||
107 | |||
108 | /* The per-task audit context. */ | ||
109 | struct audit_context { | ||
110 | int dummy; /* must be the first element */ | ||
111 | int in_syscall; /* 1 if task is in a syscall */ | ||
112 | enum audit_state state, current_state; | ||
113 | unsigned int serial; /* serial number for record */ | ||
114 | int major; /* syscall number */ | ||
115 | struct timespec ctime; /* time of syscall entry */ | ||
116 | unsigned long argv[4]; /* syscall arguments */ | ||
117 | long return_code;/* syscall return code */ | ||
118 | u64 prio; | ||
119 | int return_valid; /* return code is valid */ | ||
120 | /* | ||
121 | * The names_list is the list of all audit_names collected during this | ||
122 | * syscall. The first AUDIT_NAMES entries in the names_list will | ||
123 | * actually be from the preallocated_names array for performance | ||
124 | * reasons. Except during allocation they should never be referenced | ||
125 | * through the preallocated_names array and should only be found/used | ||
126 | * by running the names_list. | ||
127 | */ | ||
128 | struct audit_names preallocated_names[AUDIT_NAMES]; | ||
129 | int name_count; /* total records in names_list */ | ||
130 | struct list_head names_list; /* struct audit_names->list anchor */ | ||
131 | char *filterkey; /* key for rule that triggered record */ | ||
132 | struct path pwd; | ||
133 | struct audit_aux_data *aux; | ||
134 | struct audit_aux_data *aux_pids; | ||
135 | struct sockaddr_storage *sockaddr; | ||
136 | size_t sockaddr_len; | ||
137 | /* Save things to print about task_struct */ | ||
138 | pid_t pid, ppid; | ||
139 | kuid_t uid, euid, suid, fsuid; | ||
140 | kgid_t gid, egid, sgid, fsgid; | ||
141 | unsigned long personality; | ||
142 | int arch; | ||
143 | |||
144 | pid_t target_pid; | ||
145 | kuid_t target_auid; | ||
146 | kuid_t target_uid; | ||
147 | unsigned int target_sessionid; | ||
148 | u32 target_sid; | ||
149 | char target_comm[TASK_COMM_LEN]; | ||
150 | |||
151 | struct audit_tree_refs *trees, *first_trees; | ||
152 | struct list_head killed_trees; | ||
153 | int tree_count; | ||
154 | |||
155 | int type; | ||
156 | union { | ||
157 | struct { | ||
158 | int nargs; | ||
159 | long args[6]; | ||
160 | } socketcall; | ||
161 | struct { | ||
162 | kuid_t uid; | ||
163 | kgid_t gid; | ||
164 | umode_t mode; | ||
165 | u32 osid; | ||
166 | int has_perm; | ||
167 | uid_t perm_uid; | ||
168 | gid_t perm_gid; | ||
169 | umode_t perm_mode; | ||
170 | unsigned long qbytes; | ||
171 | } ipc; | ||
172 | struct { | ||
173 | mqd_t mqdes; | ||
174 | struct mq_attr mqstat; | ||
175 | } mq_getsetattr; | ||
176 | struct { | ||
177 | mqd_t mqdes; | ||
178 | int sigev_signo; | ||
179 | } mq_notify; | ||
180 | struct { | ||
181 | mqd_t mqdes; | ||
182 | size_t msg_len; | ||
183 | unsigned int msg_prio; | ||
184 | struct timespec abs_timeout; | ||
185 | } mq_sendrecv; | ||
186 | struct { | ||
187 | int oflag; | ||
188 | umode_t mode; | ||
189 | struct mq_attr attr; | ||
190 | } mq_open; | ||
191 | struct { | ||
192 | pid_t pid; | ||
193 | struct audit_cap_data cap; | ||
194 | } capset; | ||
195 | struct { | ||
196 | int fd; | ||
197 | int flags; | ||
198 | } mmap; | ||
199 | }; | ||
200 | int fds[2]; | ||
201 | |||
202 | #if AUDIT_DEBUG | ||
203 | int put_count; | ||
204 | int ino_count; | ||
205 | #endif | ||
206 | }; | ||
207 | |||
62 | #ifdef CONFIG_AUDIT | 208 | #ifdef CONFIG_AUDIT |
209 | extern int audit_enabled; | ||
63 | extern int audit_ever_enabled; | 210 | extern int audit_ever_enabled; |
211 | |||
212 | extern void audit_copy_inode(struct audit_names *name, | ||
213 | const struct dentry *dentry, | ||
214 | const struct inode *inode); | ||
215 | extern void audit_log_cap(struct audit_buffer *ab, char *prefix, | ||
216 | kernel_cap_t *cap); | ||
217 | extern void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name); | ||
218 | extern void audit_log_name(struct audit_context *context, | ||
219 | struct audit_names *n, struct path *path, | ||
220 | int record_num, int *call_panic); | ||
64 | #endif | 221 | #endif |
65 | 222 | ||
66 | extern int audit_pid; | 223 | extern int audit_pid; |