Re: Boolean algebra error in 2.6.24?



Gil Hamilton <gil_hamilton@xxxxxxxxxxx> writes:
Rainer Weikusat <rweikusat@xxxxxxxxxxx> wrote in
news:87skyc83u4.fsf@xxxxxxxxxxxxxxxxx:

static int check_kill_permission(int sig, struct siginfo *info,
struct task_struct *t)
if (info == SEND_SIG_NOINFO || (!is_si_special(info) &&
SI_FROMUSER(info))) {
[snip]
return error;

int cap_task_kill(struct task_struct *p, struct siginfo *info,
int sig, u32 secid)
{
if (info != SEND_SIG_NOINFO && (is_si_special(info) ||
SI_FROMKERNEL(info)))
return 0;

Defining a ::= 'signal has info', b ::= 'info is special' and
c ::= 'sent from user', the first condition can be written as

!a || (!b && c) [1]

and the second as

a && (b || !c) [2]

[1] can be transformed as follows:

!(a && (b || !c)) [3, !!]

meaning [2] is actually the opposite of [1], IOW when check_ oks the
signal, cap_ will deny it.

Am I missing something here?

I think I agree that the two conditions being checked are exactly
opposite as you say. However, it appears to me that the resulting
action is also opposite. Defining your "(a && (b || !c))" [2] condition
as X, the first case (check_kill_permission) is doing essentially
"if (!X) deny"
while the second case (cap_task_kill) is doing
"if (X) allow"

That seems consistent to me.

Except that the code doesn't work like this. As I already wrote:

Presumably, the purpose of the initial check is to
determine if the permission was already checked based on the uid and
to ok the kill if it was. This would imply that the two quoted complex
conditions must be equivalent

To put this into your terms, the complete sequence (as pseudo-code,
omitting non-relevant parts) would be:

if (!X) {
if (!permitted) deny;
}

if (X) allow;
deny;

BTW, the question was regarding an error in the transformations I had
done.
.