printuid: fix uid_t decoding on 64-bit architectures

It was not a good idea to treat uid_t as a long int type because
the latter is twice larger than uid_t on 64-bit architectures.

* defs.h (printuid): Change uid argument type from "unsigned long"
to "unsigned int".
* util.c (printuid): Likewise.  When uid equals to -1, print "-1".
* tests/uid.awk: New file.
* tests/uid.c: New file.
* tests/uid32.c: Likewise.
* tests/uid.test: New test.
* tests/uid32.test: Likewise.
* tests/Makefile.am (CHECK_PROGRAMS): Add uid and uid32.
(TESTS): Add uid.test and uid32.test.
(EXTRA_DIST): Add uid.awk.
* tests/.gitignore: Add uid and uid32.
This commit is contained in:
Дмитрий Левин 2014-12-13 18:24:13 +00:00
parent 79fb4d6a9a
commit 1da7c95b62
9 changed files with 197 additions and 3 deletions

2
defs.h
View File

@ -706,7 +706,7 @@ extern void printrusage(struct tcb *, long);
#ifdef ALPHA
extern void printrusage32(struct tcb *, long);
#endif
extern void printuid(const char *, unsigned long);
extern void printuid(const char *, const unsigned int);
extern void print_sigset_addr_len(struct tcb *, long, long);
extern void printsignal(int);
extern void tprint_iov(struct tcb *, unsigned long, unsigned long, int decode_iov);

3
tests/.gitignore vendored
View File

@ -1,3 +1,4 @@
caps
inet-accept-connect-send-recv
mmsg
net-accept-connect
@ -7,6 +8,8 @@ set_ptracer_any
sigaction
stack-fcall
statfs
uid
uid32
uio
*.log
*.log.*

View File

@ -13,6 +13,8 @@ check_PROGRAMS = \
sigaction \
stack-fcall \
statfs \
uid \
uid32 \
uio
statfs_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64
@ -34,6 +36,8 @@ TESTS = \
net.test \
net-fd.test \
net-yy.test \
uid.test \
uid32.test \
uio.test \
count.test \
detach-sleeping.test \
@ -52,6 +56,7 @@ EXTRA_DIST = init.sh run.sh \
net-yy-accept.awk \
net-yy-connect.awk \
sigaction.awk \
uid.awk \
$(TESTS)
CLEANFILES = $(TESTS:=.tmp)

86
tests/uid.awk Normal file
View File

@ -0,0 +1,86 @@
BEGIN {
ok = 0
fail = 0
r_uid = "(0|[1-9][0-9]*)"
r_getuid = "^getuid" suffix "\\(\\)[[:space:]]+= " r_uid "$"
r_setuid = "^/$"
r_getresuid = "^/$"
r_setreuid = "^/$"
r_setresuid = "^/$"
r_chown = "^/$"
s_last = "/"
}
ok == 1 {
fail = 1
next
}
$0 == s_last {
ok = 1
next
}
{
if (match($0, r_getuid, a)) {
r_uid = a[1]
r_setuid = "^setuid" suffix "\\(" r_uid "\\)[[:space:]]+= 0$"
next
}
if (match($0, r_setuid)) {
r_getresuid = "^getresuid" suffix "\\(\\[" r_uid "\\], \\[" r_uid "\\], \\[" r_uid "\\]\\)[[:space:]]+= 0$"
next
}
if (match($0, r_getresuid)) {
r_setreuid = "^setreuid" suffix "\\(-1, -1\\)[[:space:]]+= 0$"
next
}
if (match($0, r_setreuid)) {
r_setresuid = "^setresuid" suffix "\\(-1, " r_uid ", -1\\)[[:space:]]+= 0$"
next
}
if (match($0, r_setresuid)) {
r_chown = "^chown" suffix "\\(\".\", -1, -1\\)[[:space:]]+= 0$"
next
}
if (match($0, r_chown)) {
s_last = "+++ exited with 0 +++"
next
}
next
}
END {
if (fail) {
print "Unexpected output after exit"
exit 1
}
if (ok)
exit 0
if (r_setuid == "^/$") {
print "getuid doesn't match"
exit 1
}
if (r_getresuid == "^/$") {
print "setuid doesn't match"
exit 1
}
if (r_setreuid == "^/$") {
print "getresuid doesn't match"
exit 1
}
if (r_setresuid == "^/$") {
print "setreuid doesn't match"
exit 1
}
if (r_chown == "^/$") {
print "setresuid doesn't match"
exit 1
}
if (s_last == "/") {
print "chown doesn't match"
exit 1
}
print "The last line doesn't match"
exit 1
}

29
tests/uid.c Normal file
View File

@ -0,0 +1,29 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <unistd.h>
#include <sys/syscall.h>
int
main(void)
{
#if defined(__NR_getuid) \
&& defined(__NR_setuid) \
&& defined(__NR_getresuid) \
&& defined(__NR_setreuid) \
&& defined(__NR_setresuid) \
&& defined(__NR_chown)
uid_t r, e, s;
e = syscall(__NR_getuid);
assert(syscall(__NR_setuid, e) == 0);
assert(syscall(__NR_getresuid, &r, &e, &s) == 0);
assert(syscall(__NR_setreuid, -1, -1L) == 0);
assert(syscall(__NR_setresuid, -1, e, -1L) == 0);
assert(syscall(__NR_chown, ".", -1, -1L) == 0);
return 0;
#else
return 77;
#endif
}

32
tests/uid.test Executable file
View File

@ -0,0 +1,32 @@
#!/bin/sh
# Check uid decoding.
. "${srcdir=.}/init.sh"
check_prog awk
s="${uid_syscall_suffix-}"
w="${uid_t_size-}"
uid="uid$s$w"
./"$uid" || {
if [ $? -eq 77 ]; then
framework_skip_ "some uid$s or uid${w}_t syscalls are not available"
else
fail_ "$uid failed"
fi
}
syscalls="getuid$s,setuid$s,getresuid$s,setreuid$s,setresuid$s,chown$s"
args="-e trace=$syscalls"
$STRACE -o "$LOG" $args ./"$uid"|| {
cat "$LOG"
fail_ "$STRACE $args ./$uid failed"
}
awk -f "$srcdir"/uid.awk -v suffix="$s" "$LOG" || {
cat "$LOG"
fail_ 'unexpected output'
}
exit 0

29
tests/uid32.c Normal file
View File

@ -0,0 +1,29 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <unistd.h>
#include <sys/syscall.h>
int
main(void)
{
#if defined(__NR_getuid32) \
&& defined(__NR_setuid32) \
&& defined(__NR_getresuid32) \
&& defined(__NR_setreuid32) \
&& defined(__NR_setresuid32) \
&& defined(__NR_chown32)
uid_t r, e, s;
e = syscall(__NR_getuid32);
assert(syscall(__NR_setuid32, e) == 0);
assert(syscall(__NR_getresuid32, &r, &e, &s) == 0);
assert(syscall(__NR_setreuid32, -1, -1L) == 0);
assert(syscall(__NR_setresuid32, -1, e, -1L) == 0);
assert(syscall(__NR_chown32, ".", -1, -1L) == 0);
return 0;
#else
return 77;
#endif
}

7
tests/uid32.test Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
# Check uid32 decoding.
uid_syscall_suffix=32
. "${srcdir=.}/uid.test"

7
util.c
View File

@ -504,9 +504,12 @@ printfd(struct tcb *tcp, int fd)
}
void
printuid(const char *text, unsigned long uid)
printuid(const char *text, const unsigned int uid)
{
tprintf(((long) uid == -1) ? "%s%ld" : "%s%lu", text, uid);
if ((unsigned int) -1 == uid)
tprintf("%s-1", text);
else
tprintf("%s%u", text, uid);
}
/*