Boolean algebra error in 2.6.24?



On systems running 2.6.24, at will fail to send a SIGHUP to
atd after a job has been queued because of EPERM. The 'main' signal
permission check is in ../kernel/signal.c, subroutine 'bad_signal'

static int check_kill_permission(int sig, struct siginfo *info,
struct task_struct *t)
{
int error = -EINVAL;
if (!valid_signal(sig))
return error;

if (info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info))) {

[ 'check for permission according to uid' ]

return error;
}

return security_task_kill(t, info, sig, 0);
}

The routine being ultimatively called by security_task_kill is
cap_task_kill in ../security/ commoncap.c:

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;

['other checks']

if (capable(CAP_KILL))
return 0;

return -EPERM;
}

This routine (for the 'no fs capailities in use' case) will return
-EPERM if the initial condition is not true and the current doesn't
have CAP_KILL. 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 (if the complex condition in check_ was
true and cap_ was called, the check in check_ must have been
successful.

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)

<=>

!a || !(b || !c)

<=>

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

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

It is certain that at doesn't work with [2] and does work with [3].
Additionally, I have checked this with a truth table:

a b c !a || (!b && c) a && (b || !c) !(a && (b || !c))
0 0 0 1 0 1
0 0 1 1 0 1
0 1 0 1 0 1
0 1 1 1 0 1
1 0 0 0 1 0
1 0 1 1 0 1
1 1 0 0 1 0
1 1 1 0 1 0

Am I missing something here?

.



Relevant Pages

  • [patch 19/20] XEN-paravirt: Add the Xenbus sysfs and virtual device hotplug driver.
    ... int bind_evtchn_to_irqhandler(unsigned int evtchn, ... * modify it under the terms of the GNU General Public License version 2 ... * as published by the Free Software Foundation; ... * Permission is hereby granted, free of charge, to any person obtaining a copy ...
    (Linux-Kernel)
  • Re: increment and loop error!
    ... your int only hold 32767, and that when you print out the value, ... and print it out with a %ld format element. ... "It is important to remember that when it comes to law, computers ... Only people can be given permission." ...
    (comp.lang.c)
  • Re: increment and loop error!
    ... your int only hold 32767, and that when you print out the value, ... and print it out with a %ld format element. ... "It is important to remember that when it comes to law, computers ... Only people can be given permission." ...
    (comp.lang.c)
  • Re: Configure failing why?
    ... # gcc foo.cpp ... ./configure: line 1: ./a.out: Permission denied ... script is making is not getting execute permissions enable by the ... int main$ c++ foo.cpp ...
    (comp.lang.python)
  • Re: [PATCH -mm 5/7] add user namespace
    ... The one thing that just occurred to me is that the generic permission ... int generic_permission(struct inode *inode, int mask, ...
    (Linux-Kernel)