aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/auditsc.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:19 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:19 -0500
commitc69e8d9c01db2adc503464993c358901c9af9de4 (patch)
treebed94aaa9aeb7a7834d1c880f72b62a11a752c78 /kernel/auditsc.c
parent86a264abe542cfececb4df129bc45a0338d8cdb9 (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.c33
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
1230static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) 1233static 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);