• Eric W. Biederman's avatar
    signal: In sigqueueinfo prefer sig not si_signo · 601d5abf
    Eric W. Biederman authored
    Andrei Vagin <avagin@gmail.com> reported:
    
    > Accoding to the man page, the user should not set si_signo, it has to be set
    > by kernel.
    >
    > $ man 2 rt_sigqueueinfo
    >
    >     The uinfo argument specifies the data to accompany  the  signal.   This
    >        argument  is  a  pointer to a structure of type siginfo_t, described in
    >        sigaction(2) (and defined  by  including  <sigaction.h>).   The  caller
    >        should set the following fields in this structure:
    >
    >        si_code
    >               This  must  be  one of the SI_* codes in the Linux kernel source
    >               file include/asm-generic/siginfo.h, with  the  restriction  that
    >               the  code  must  be  negative (i.e., cannot be SI_USER, which is
    >               used by the kernel to indicate a signal  sent  by  kill(2))  and
    >               cannot  (since  Linux  2.6.39) be SI_TKILL (which is used by the
    >               kernel to indicate a signal sent using tgkill(2)).
    >
    >        si_pid This should be set to a process ID, typically the process ID  of
    >               the sender.
    >
    >        si_uid This  should  be set to a user ID, typically the real user ID of
    >               the sender.
    >
    >        si_value
    >               This field contains the user data to accompany the signal.   For
    >               more information, see the description of the last (union sigval)
    >               argument of sigqueue(3).
    >
    >        Internally, the kernel sets the si_signo field to the  value  specified
    >        in  sig,  so that the receiver of the signal can also obtain the signal
    >        number via that field.
    >
    > On Tue, Sep 25, 2018 at 07:19:02PM +0200, Eric W. Biederman wrote:
    >>
    >> If there is some application that calls sigqueueinfo directly that has
    >> a problem with this added sanity check we can revisit this when we see
    >> what kind of crazy that application is doing.
    >
    >
    > I already know two "applications" ;)
    >
    > https://github.com/torvalds/linux/blob/master/tools/testing/selftests/ptrace/peeksiginfo.c
    > https://github.com/checkpoint-restore/criu/blob/master/test/zdtm/static/sigpending.c
    >
    > Disclaimer: I'm the author of both of them.
    
    Looking at the kernel code the historical behavior has alwasy been to prefer
    the signal number passed in by the kernel.
    
    So sigh.  Implmenet __copy_siginfo_from_user and __copy_siginfo_from_user32 to
    take that signal number and prefer it.  The user of ptrace will still
    use copy_siginfo_from_user and copy_siginfo_from_user32 as they do not and
    never have had a signal number there.
    
    Luckily this change has never made it farther than linux-next.
    
    Fixes: e75dc036 ("signal: Fail sigqueueinfo if si_signo != sig")
    Reported-by: default avatarAndrei Vagin <avagin@gmail.com>
    Tested-by: default avatarAndrei Vagin <avagin@gmail.com>
    Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
    601d5abf
signal.c 106 KB