diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-12-14 03:46:48 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-01-04 15:14:40 -0500 |
commit | c32c8af43b9adde8d6f938d8e6328c13b8de79ac (patch) | |
tree | 6377079bba7530d2aa8a688ebf9ba3e09ae085a7 /kernel/auditsc.c | |
parent | 20114f71b27cafeb7c7e41d2b0f0b68c3fbb022b (diff) |
sanitize AUDIT_MQ_SENDRECV
* logging the original value of *msg_prio in mq_timedreceive(2)
is insane - the argument is write-only (i.e. syscall always
ignores the original value and only overwrites it).
* merge __audit_mq_timed{send,receive}
* don't do copy_from_user() twice
* don't mess with allocations in auditsc part
* ... and don't bother checking !audit_enabled and !context in there -
we'd already checked for audit_dummy_context().
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 127 |
1 files changed, 29 insertions, 98 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 3ece960de894..140c47453470 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -131,14 +131,6 @@ struct audit_aux_data_mq_open { | |||
131 | struct mq_attr attr; | 131 | struct mq_attr attr; |
132 | }; | 132 | }; |
133 | 133 | ||
134 | struct audit_aux_data_mq_sendrecv { | ||
135 | struct audit_aux_data d; | ||
136 | mqd_t mqdes; | ||
137 | size_t msg_len; | ||
138 | unsigned int msg_prio; | ||
139 | struct timespec abs_timeout; | ||
140 | }; | ||
141 | |||
142 | struct audit_aux_data_execve { | 134 | struct audit_aux_data_execve { |
143 | struct audit_aux_data d; | 135 | struct audit_aux_data d; |
144 | int argc; | 136 | int argc; |
@@ -244,6 +236,12 @@ struct audit_context { | |||
244 | mqd_t mqdes; | 236 | mqd_t mqdes; |
245 | int sigev_signo; | 237 | int sigev_signo; |
246 | } mq_notify; | 238 | } mq_notify; |
239 | struct { | ||
240 | mqd_t mqdes; | ||
241 | size_t msg_len; | ||
242 | unsigned int msg_prio; | ||
243 | struct timespec abs_timeout; | ||
244 | } mq_sendrecv; | ||
247 | }; | 245 | }; |
248 | 246 | ||
249 | #if AUDIT_DEBUG | 247 | #if AUDIT_DEBUG |
@@ -1265,6 +1263,16 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
1265 | return; | 1263 | return; |
1266 | } | 1264 | } |
1267 | break; } | 1265 | break; } |
1266 | case AUDIT_MQ_SENDRECV: { | ||
1267 | audit_log_format(ab, | ||
1268 | "mqdes=%d msg_len=%zd msg_prio=%u " | ||
1269 | "abs_timeout_sec=%ld abs_timeout_nsec=%ld", | ||
1270 | context->mq_sendrecv.mqdes, | ||
1271 | context->mq_sendrecv.msg_len, | ||
1272 | context->mq_sendrecv.msg_prio, | ||
1273 | context->mq_sendrecv.abs_timeout.tv_sec, | ||
1274 | context->mq_sendrecv.abs_timeout.tv_nsec); | ||
1275 | break; } | ||
1268 | case AUDIT_MQ_NOTIFY: { | 1276 | case AUDIT_MQ_NOTIFY: { |
1269 | audit_log_format(ab, "mqdes=%d sigev_signo=%d", | 1277 | audit_log_format(ab, "mqdes=%d sigev_signo=%d", |
1270 | context->mq_notify.mqdes, | 1278 | context->mq_notify.mqdes, |
@@ -1370,15 +1378,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1370 | axi->attr.mq_curmsgs); | 1378 | axi->attr.mq_curmsgs); |
1371 | break; } | 1379 | break; } |
1372 | 1380 | ||
1373 | case AUDIT_MQ_SENDRECV: { | ||
1374 | struct audit_aux_data_mq_sendrecv *axi = (void *)aux; | ||
1375 | audit_log_format(ab, | ||
1376 | "mqdes=%d msg_len=%zd msg_prio=%u " | ||
1377 | "abs_timeout_sec=%ld abs_timeout_nsec=%ld", | ||
1378 | axi->mqdes, axi->msg_len, axi->msg_prio, | ||
1379 | axi->abs_timeout.tv_sec, axi->abs_timeout.tv_nsec); | ||
1380 | break; } | ||
1381 | |||
1382 | case AUDIT_EXECVE: { | 1381 | case AUDIT_EXECVE: { |
1383 | struct audit_aux_data_execve *axi = (void *)aux; | 1382 | struct audit_aux_data_execve *axi = (void *)aux; |
1384 | audit_log_execve_info(context, &ab, axi); | 1383 | audit_log_execve_info(context, &ab, axi); |
@@ -2171,97 +2170,29 @@ int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr) | |||
2171 | } | 2170 | } |
2172 | 2171 | ||
2173 | /** | 2172 | /** |
2174 | * __audit_mq_timedsend - record audit data for a POSIX MQ timed send | 2173 | * __audit_mq_sendrecv - record audit data for a POSIX MQ timed send/receive |
2175 | * @mqdes: MQ descriptor | 2174 | * @mqdes: MQ descriptor |
2176 | * @msg_len: Message length | 2175 | * @msg_len: Message length |
2177 | * @msg_prio: Message priority | 2176 | * @msg_prio: Message priority |
2178 | * @u_abs_timeout: Message timeout in absolute time | 2177 | * @abs_timeout: Message timeout in absolute time |
2179 | * | ||
2180 | * Returns 0 for success or NULL context or < 0 on error. | ||
2181 | */ | ||
2182 | int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, | ||
2183 | const struct timespec __user *u_abs_timeout) | ||
2184 | { | ||
2185 | struct audit_aux_data_mq_sendrecv *ax; | ||
2186 | struct audit_context *context = current->audit_context; | ||
2187 | |||
2188 | if (!audit_enabled) | ||
2189 | return 0; | ||
2190 | |||
2191 | if (likely(!context)) | ||
2192 | return 0; | ||
2193 | |||
2194 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | ||
2195 | if (!ax) | ||
2196 | return -ENOMEM; | ||
2197 | |||
2198 | if (u_abs_timeout != NULL) { | ||
2199 | if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) { | ||
2200 | kfree(ax); | ||
2201 | return -EFAULT; | ||
2202 | } | ||
2203 | } else | ||
2204 | memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout)); | ||
2205 | |||
2206 | ax->mqdes = mqdes; | ||
2207 | ax->msg_len = msg_len; | ||
2208 | ax->msg_prio = msg_prio; | ||
2209 | |||
2210 | ax->d.type = AUDIT_MQ_SENDRECV; | ||
2211 | ax->d.next = context->aux; | ||
2212 | context->aux = (void *)ax; | ||
2213 | return 0; | ||
2214 | } | ||
2215 | |||
2216 | /** | ||
2217 | * __audit_mq_timedreceive - record audit data for a POSIX MQ timed receive | ||
2218 | * @mqdes: MQ descriptor | ||
2219 | * @msg_len: Message length | ||
2220 | * @u_msg_prio: Message priority | ||
2221 | * @u_abs_timeout: Message timeout in absolute time | ||
2222 | * | 2178 | * |
2223 | * Returns 0 for success or NULL context or < 0 on error. | ||
2224 | */ | 2179 | */ |
2225 | int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, | 2180 | void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, |
2226 | unsigned int __user *u_msg_prio, | 2181 | const struct timespec *abs_timeout) |
2227 | const struct timespec __user *u_abs_timeout) | ||
2228 | { | 2182 | { |
2229 | struct audit_aux_data_mq_sendrecv *ax; | ||
2230 | struct audit_context *context = current->audit_context; | 2183 | struct audit_context *context = current->audit_context; |
2184 | struct timespec *p = &context->mq_sendrecv.abs_timeout; | ||
2231 | 2185 | ||
2232 | if (!audit_enabled) | 2186 | if (abs_timeout) |
2233 | return 0; | 2187 | memcpy(p, abs_timeout, sizeof(struct timespec)); |
2234 | 2188 | else | |
2235 | if (likely(!context)) | 2189 | memset(p, 0, sizeof(struct timespec)); |
2236 | return 0; | ||
2237 | |||
2238 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | ||
2239 | if (!ax) | ||
2240 | return -ENOMEM; | ||
2241 | |||
2242 | if (u_msg_prio != NULL) { | ||
2243 | if (get_user(ax->msg_prio, u_msg_prio)) { | ||
2244 | kfree(ax); | ||
2245 | return -EFAULT; | ||
2246 | } | ||
2247 | } else | ||
2248 | ax->msg_prio = 0; | ||
2249 | |||
2250 | if (u_abs_timeout != NULL) { | ||
2251 | if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) { | ||
2252 | kfree(ax); | ||
2253 | return -EFAULT; | ||
2254 | } | ||
2255 | } else | ||
2256 | memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout)); | ||
2257 | 2190 | ||
2258 | ax->mqdes = mqdes; | 2191 | context->mq_sendrecv.mqdes = mqdes; |
2259 | ax->msg_len = msg_len; | 2192 | context->mq_sendrecv.msg_len = msg_len; |
2193 | context->mq_sendrecv.msg_prio = msg_prio; | ||
2260 | 2194 | ||
2261 | ax->d.type = AUDIT_MQ_SENDRECV; | 2195 | context->type = AUDIT_MQ_SENDRECV; |
2262 | ax->d.next = context->aux; | ||
2263 | context->aux = (void *)ax; | ||
2264 | return 0; | ||
2265 | } | 2196 | } |
2266 | 2197 | ||
2267 | /** | 2198 | /** |