diff options
author | David Howells <dhowells@redhat.com> | 2008-11-13 18:39:19 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-11-13 18:39:19 -0500 |
commit | c69e8d9c01db2adc503464993c358901c9af9de4 (patch) | |
tree | bed94aaa9aeb7a7834d1c880f72b62a11a752c78 /kernel/auditsc.c | |
parent | 86a264abe542cfececb4df129bc45a0338d8cdb9 (diff) |
CRED: Use RCU to access another task's creds and to release a task's own creds
Use RCU to access another task's creds and to release a task's own creds.
This means that it will be possible for the credentials of a task to be
replaced without another task (a) requiring a full lock to read them, and (b)
seeing deallocated memory.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: James Morris <jmorris@namei.org>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 2febf5165fad..ae8ef88ade3f 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -447,7 +447,7 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
447 | struct audit_names *name, | 447 | struct audit_names *name, |
448 | enum audit_state *state) | 448 | enum audit_state *state) |
449 | { | 449 | { |
450 | struct cred *cred = tsk->cred; | 450 | const struct cred *cred = get_task_cred(tsk); |
451 | int i, j, need_sid = 1; | 451 | int i, j, need_sid = 1; |
452 | u32 sid; | 452 | u32 sid; |
453 | 453 | ||
@@ -642,8 +642,10 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
642 | break; | 642 | break; |
643 | } | 643 | } |
644 | 644 | ||
645 | if (!result) | 645 | if (!result) { |
646 | put_cred(cred); | ||
646 | return 0; | 647 | return 0; |
648 | } | ||
647 | } | 649 | } |
648 | if (rule->filterkey && ctx) | 650 | if (rule->filterkey && ctx) |
649 | ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC); | 651 | ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC); |
@@ -651,6 +653,7 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
651 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; | 653 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; |
652 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; | 654 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; |
653 | } | 655 | } |
656 | put_cred(cred); | ||
654 | return 1; | 657 | return 1; |
655 | } | 658 | } |
656 | 659 | ||
@@ -1229,7 +1232,7 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) | |||
1229 | 1232 | ||
1230 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) | 1233 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) |
1231 | { | 1234 | { |
1232 | struct cred *cred = tsk->cred; | 1235 | const struct cred *cred; |
1233 | int i, call_panic = 0; | 1236 | int i, call_panic = 0; |
1234 | struct audit_buffer *ab; | 1237 | struct audit_buffer *ab; |
1235 | struct audit_aux_data *aux; | 1238 | struct audit_aux_data *aux; |
@@ -1239,13 +1242,14 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1239 | context->pid = tsk->pid; | 1242 | context->pid = tsk->pid; |
1240 | if (!context->ppid) | 1243 | if (!context->ppid) |
1241 | context->ppid = sys_getppid(); | 1244 | context->ppid = sys_getppid(); |
1242 | context->uid = cred->uid; | 1245 | cred = current_cred(); |
1243 | context->gid = cred->gid; | 1246 | context->uid = cred->uid; |
1244 | context->euid = cred->euid; | 1247 | context->gid = cred->gid; |
1245 | context->suid = cred->suid; | 1248 | context->euid = cred->euid; |
1249 | context->suid = cred->suid; | ||
1246 | context->fsuid = cred->fsuid; | 1250 | context->fsuid = cred->fsuid; |
1247 | context->egid = cred->egid; | 1251 | context->egid = cred->egid; |
1248 | context->sgid = cred->sgid; | 1252 | context->sgid = cred->sgid; |
1249 | context->fsgid = cred->fsgid; | 1253 | context->fsgid = cred->fsgid; |
1250 | context->personality = tsk->personality; | 1254 | context->personality = tsk->personality; |
1251 | 1255 | ||
@@ -2088,7 +2092,7 @@ int audit_set_loginuid(struct task_struct *task, uid_t loginuid) | |||
2088 | audit_log_format(ab, "login pid=%d uid=%u " | 2092 | audit_log_format(ab, "login pid=%d uid=%u " |
2089 | "old auid=%u new auid=%u" | 2093 | "old auid=%u new auid=%u" |
2090 | " old ses=%u new ses=%u", | 2094 | " old ses=%u new ses=%u", |
2091 | task->pid, task->cred->uid, | 2095 | task->pid, task_uid(task), |
2092 | task->loginuid, loginuid, | 2096 | task->loginuid, loginuid, |
2093 | task->sessionid, sessionid); | 2097 | task->sessionid, sessionid); |
2094 | audit_log_end(ab); | 2098 | audit_log_end(ab); |
@@ -2471,7 +2475,7 @@ void __audit_ptrace(struct task_struct *t) | |||
2471 | 2475 | ||
2472 | context->target_pid = t->pid; | 2476 | context->target_pid = t->pid; |
2473 | context->target_auid = audit_get_loginuid(t); | 2477 | context->target_auid = audit_get_loginuid(t); |
2474 | context->target_uid = t->cred->uid; | 2478 | context->target_uid = task_uid(t); |
2475 | context->target_sessionid = audit_get_sessionid(t); | 2479 | context->target_sessionid = audit_get_sessionid(t); |
2476 | security_task_getsecid(t, &context->target_sid); | 2480 | security_task_getsecid(t, &context->target_sid); |
2477 | memcpy(context->target_comm, t->comm, TASK_COMM_LEN); | 2481 | memcpy(context->target_comm, t->comm, TASK_COMM_LEN); |
@@ -2490,6 +2494,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2490 | struct audit_aux_data_pids *axp; | 2494 | struct audit_aux_data_pids *axp; |
2491 | struct task_struct *tsk = current; | 2495 | struct task_struct *tsk = current; |
2492 | struct audit_context *ctx = tsk->audit_context; | 2496 | struct audit_context *ctx = tsk->audit_context; |
2497 | uid_t uid = current_uid(), t_uid = task_uid(t); | ||
2493 | 2498 | ||
2494 | if (audit_pid && t->tgid == audit_pid) { | 2499 | if (audit_pid && t->tgid == audit_pid) { |
2495 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) { | 2500 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) { |
@@ -2497,7 +2502,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2497 | if (tsk->loginuid != -1) | 2502 | if (tsk->loginuid != -1) |
2498 | audit_sig_uid = tsk->loginuid; | 2503 | audit_sig_uid = tsk->loginuid; |
2499 | else | 2504 | else |
2500 | audit_sig_uid = tsk->cred->uid; | 2505 | audit_sig_uid = uid; |
2501 | security_task_getsecid(tsk, &audit_sig_sid); | 2506 | security_task_getsecid(tsk, &audit_sig_sid); |
2502 | } | 2507 | } |
2503 | if (!audit_signals || audit_dummy_context()) | 2508 | if (!audit_signals || audit_dummy_context()) |
@@ -2509,7 +2514,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2509 | if (!ctx->target_pid) { | 2514 | if (!ctx->target_pid) { |
2510 | ctx->target_pid = t->tgid; | 2515 | ctx->target_pid = t->tgid; |
2511 | ctx->target_auid = audit_get_loginuid(t); | 2516 | ctx->target_auid = audit_get_loginuid(t); |
2512 | ctx->target_uid = t->cred->uid; | 2517 | ctx->target_uid = t_uid; |
2513 | ctx->target_sessionid = audit_get_sessionid(t); | 2518 | ctx->target_sessionid = audit_get_sessionid(t); |
2514 | security_task_getsecid(t, &ctx->target_sid); | 2519 | security_task_getsecid(t, &ctx->target_sid); |
2515 | memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); | 2520 | memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); |
@@ -2530,7 +2535,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2530 | 2535 | ||
2531 | axp->target_pid[axp->pid_count] = t->tgid; | 2536 | axp->target_pid[axp->pid_count] = t->tgid; |
2532 | axp->target_auid[axp->pid_count] = audit_get_loginuid(t); | 2537 | axp->target_auid[axp->pid_count] = audit_get_loginuid(t); |
2533 | axp->target_uid[axp->pid_count] = t->cred->uid; | 2538 | axp->target_uid[axp->pid_count] = t_uid; |
2534 | axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); | 2539 | axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); |
2535 | security_task_getsecid(t, &axp->target_sid[axp->pid_count]); | 2540 | security_task_getsecid(t, &axp->target_sid[axp->pid_count]); |
2536 | memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); | 2541 | memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); |