2009-11-10 17:24:01 |
John Johansen |
description |
The auditing code of capabilities, has a simple cache to reduce capability messages flooding the audit logs. Checking and updating the cache disables kernel preemption (via get_cpu_var). One potential exit path does not properly put the per cpu var, thus not reenabling preemption.
ent = &get_cpu_var(audit_cache);
if (sa->base.task == ent->task && cap_raised(ent->caps, sa->cap)) {
--------> needs put_cpu_var(audit_cache); <--------
if (PROFILE_COMPLAIN(profile))
return 0;
return sa->base.error;
} else {
ent->task = sa->base.task;
cap_raise(ent->caps, sa->cap);
}
put_cpu_var(audit_cache); |
SRU Justification: Failing to put_cpu_var means that kernel preemption is disabled for the task. This will affect all confined processes that try to audit a capability message (so an process that has capability violation or is in learning mode and would have a capability violation).
The auditing code of capabilities, has a simple cache to reduce capability messages flooding the audit logs. Checking and updating the cache disables kernel preemption (via get_cpu_var). One potential exit path does not properly put the per cpu var, thus not reenabling preemption.
ent = &get_cpu_var(audit_cache);
if (sa->base.task == ent->task && cap_raised(ent->caps, sa->cap)) {
--------> needs put_cpu_var(audit_cache); <--------
if (PROFILE_COMPLAIN(profile))
return 0;
return sa->base.error;
} else {
ent->task = sa->base.task;
cap_raise(ent->caps, sa->cap);
}
put_cpu_var(audit_cache);
|
|