Fix decoding of sgetmask and ssetmask syscalls
Old ssetmask syscall takes an argument and returns a value of type int. Old sgetmask syscall may return an error. * signal.c (SYS_FUNC(ssetmask)): Explicitly convert the argument and return value to unsigned int, print it using sprint_old_sigmask_val. (SYS_FUNC(sgetmask)): Do not print the mask in case of syserror. * tests/sxetmask.c: New file. * tests/gen_tests.in (sxetmask): New entry. * tests/pure_executables.list: Add sxetmask. * tests/.gitignore: Likewise. * NEWS: Mention this fix.
This commit is contained in:
parent
9d095c7860
commit
ba0bd3f1ec
1
NEWS
1
NEWS
@ -46,6 +46,7 @@ Noteworthy changes in release ?.?? (????-??-??)
|
||||
* Fixed the number of arguments and tracing flags of alpha specific syscalls.
|
||||
* Fixed decoding of old sigsuspend syscall on alpha, cris, mips, powerpc,
|
||||
powerpc64, sh, sh64, sparc, and sparc64.
|
||||
* Fixed decoding of sgetmask and ssetmask syscalls on 64-bit architectures.
|
||||
* Fixed decoding of netlink messages received within struct msghdr.
|
||||
* Worked around a bug in miscompiled aarch64 kernels leading to the 3rd
|
||||
argument of sched_getattr syscall being not quite 32-bit.
|
||||
|
10
signal.c
10
signal.c
@ -288,10 +288,11 @@ print_sigset_addr(struct tcb *const tcp, const kernel_ulong_t addr)
|
||||
SYS_FUNC(ssetmask)
|
||||
{
|
||||
if (entering(tcp)) {
|
||||
tprintsigmask_val("", tcp->u_arg[0]);
|
||||
tprint_old_sigmask_val("", (unsigned) tcp->u_arg[0]);
|
||||
}
|
||||
else if (!syserror(tcp)) {
|
||||
tcp->auxstr = sprintsigmask_val("old mask ", tcp->u_rval);
|
||||
tcp->auxstr = sprint_old_sigmask_val("old mask ",
|
||||
(unsigned) tcp->u_rval);
|
||||
return RVAL_HEX | RVAL_STR;
|
||||
}
|
||||
return 0;
|
||||
@ -395,10 +396,11 @@ SYS_FUNC(signal)
|
||||
|
||||
SYS_FUNC(sgetmask)
|
||||
{
|
||||
if (exiting(tcp)) {
|
||||
if (exiting(tcp) && !syserror(tcp)) {
|
||||
tcp->auxstr = sprintsigmask_val("mask ", tcp->u_rval);
|
||||
return RVAL_HEX | RVAL_STR;
|
||||
}
|
||||
return RVAL_HEX | RVAL_STR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_FUNC(sigsuspend)
|
||||
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -340,6 +340,7 @@ statfs
|
||||
statfs64
|
||||
statx
|
||||
swap
|
||||
sxetmask
|
||||
symlink
|
||||
symlinkat
|
||||
sync
|
||||
|
@ -293,6 +293,7 @@ statfs -a17
|
||||
statfs64 -a23
|
||||
statx -a32 -v -P stat.sample -P /dev/full
|
||||
swap -a23 -e trace=swapon,swapoff
|
||||
sxetmask -a11 -e trace=sgetmask,ssetmask
|
||||
symlink -a34
|
||||
symlinkat
|
||||
sync -a7
|
||||
|
@ -280,6 +280,7 @@ statfs
|
||||
statfs64
|
||||
statx
|
||||
swap
|
||||
sxetmask
|
||||
symlink
|
||||
symlinkat
|
||||
sync
|
||||
|
112
tests/sxetmask.c
Normal file
112
tests/sxetmask.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Check decoding of sgetmask and ssetmask syscalls.
|
||||
*
|
||||
* Copyright (c) 2017 Dmitry V. Levin <ldv@altlinux.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "tests.h"
|
||||
#include <asm/unistd.h>
|
||||
|
||||
#if defined __NR_sgetmask && defined __NR_ssetmask
|
||||
|
||||
# include <errno.h>
|
||||
# include <signal.h>
|
||||
# include <stdio.h>
|
||||
# include <stdint.h>
|
||||
# include <string.h>
|
||||
# include <unistd.h>
|
||||
|
||||
static long
|
||||
k_sgetmask(void)
|
||||
{
|
||||
return syscall(__NR_sgetmask);
|
||||
}
|
||||
|
||||
static long
|
||||
k_ssetmask(const kernel_ulong_t arg)
|
||||
{
|
||||
return syscall(__NR_ssetmask, arg);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
union {
|
||||
sigset_t libc_mask;
|
||||
unsigned long old_mask;
|
||||
} uset, uget;
|
||||
long rc;
|
||||
|
||||
/*
|
||||
* Block, reset, and raise SIGUSR1.
|
||||
* If a subsequent ssetmask call fails to set the proper mask,
|
||||
* the process will be terminated by SIGUSR1.
|
||||
*/
|
||||
sigemptyset(&uset.libc_mask);
|
||||
sigaddset(&uset.libc_mask, SIGUSR1);
|
||||
if (sigprocmask(SIG_SETMASK, &uset.libc_mask, NULL))
|
||||
perror_msg_and_fail("sigprocmask");
|
||||
if (signal(SIGUSR1, SIG_DFL) == SIG_ERR)
|
||||
perror_msg_and_fail("signal");
|
||||
raise(SIGUSR1);
|
||||
|
||||
sigaddset(&uset.libc_mask, SIGUSR2);
|
||||
rc = k_ssetmask((kernel_ulong_t) 0xfacefeed00000000ULL | uset.old_mask);
|
||||
if (rc == -1L) {
|
||||
printf("ssetmask([USR1 USR2]) = %s\n", sprintrc(rc));
|
||||
} else {
|
||||
printf("ssetmask([USR1 USR2]) = %#lx (old mask [USR1])\n", rc);
|
||||
/*
|
||||
* Use a regular sigprocmask call to check the value
|
||||
* returned by the ssetmask call being tested.
|
||||
*/
|
||||
if (sigprocmask(SIG_SETMASK, NULL, &uget.libc_mask))
|
||||
perror_msg_and_fail("sigprocmask");
|
||||
if (uset.old_mask != uget.old_mask)
|
||||
error_msg_and_fail("sigprocmask returned %#lx"
|
||||
" instead of %#lx",
|
||||
uget.old_mask, uset.old_mask);
|
||||
}
|
||||
|
||||
rc = k_sgetmask();
|
||||
if (rc == -1L) {
|
||||
printf("sgetmask() = %s\n", sprintrc(rc));
|
||||
} else {
|
||||
printf("sgetmask() = %#lx (mask [USR1 USR2])\n", rc);
|
||||
if (uget.old_mask != (unsigned long) rc)
|
||||
error_msg_and_fail("sigprocmask returned %#lx",
|
||||
uget.old_mask);
|
||||
}
|
||||
|
||||
puts("+++ exited with 0 +++");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SKIP_MAIN_UNDEFINED("__NR_sgetmask && __NR_ssetmask")
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user