From: Dmitry V. Levin Date: Mon, 16 May 2016 21:01:43 +0000 (+0000) Subject: Fix decoding of fcntl/fcntl64 operation argument X-Git-Tag: v4.12~155 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=77086594ce4ff74a6afa5d4570d2a1dfbc5ae3c5;p=strace Fix decoding of fcntl/fcntl64 operation argument Consistently treat operation argument of fcntl/fcntl64 syscalls as int to match the kernel behaviour. * fcntl.c (print_fcntl, SYS_FUNC(fcntl), SYS_FUNC(fcntl64)): Assign 2nd argument of syscall to a variable of type unsigned int and use it in all subsequent checks and lookups. * tests/struct_flock.c (invoke_test_syscall): New function. (test_flock_einval, test_flock): Use it. * tests/fcntl.c (test_flock64_einval): Use it. * tests/fcntl64.c (test_flock64_einval, test_flock64): Use it. --- diff --git a/fcntl.c b/fcntl.c index e2a76f98..59eca9db 100644 --- a/fcntl.c +++ b/fcntl.c @@ -87,7 +87,9 @@ print_f_owner_ex(struct tcb *tcp, const long addr) static int print_fcntl(struct tcb *tcp) { - switch (tcp->u_arg[1]) { + const unsigned int cmd = tcp->u_arg[1]; + + switch (cmd) { case F_SETFD: tprints(", "); printflags(fdflags, tcp->u_arg[2], "FD_???"); @@ -194,8 +196,8 @@ SYS_FUNC(fcntl) if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); tprints(", "); - const char *str = - xlookup(fcntlcmds, (unsigned long) tcp->u_arg[1]); + const unsigned int cmd = tcp->u_arg[1]; + const char *str = xlookup(fcntlcmds, cmd); if (str) { tprints(str); } else { @@ -204,7 +206,7 @@ SYS_FUNC(fcntl) * constants, but we would like to show them * for better debugging experience. */ - printxval(fcntl64cmds, tcp->u_arg[1], "F_???"); + printxval(fcntl64cmds, cmd, "F_???"); } } return print_fcntl(tcp); @@ -212,18 +214,18 @@ SYS_FUNC(fcntl) SYS_FUNC(fcntl64) { + const unsigned int cmd = tcp->u_arg[1]; if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); tprints(", "); - const char *str = - xlookup(fcntl64cmds, (unsigned long) tcp->u_arg[1]); + const char *str = xlookup(fcntl64cmds, cmd); if (str) { tprints(str); } else { - printxval(fcntlcmds, tcp->u_arg[1], "F_???"); + printxval(fcntlcmds, cmd, "F_???"); } } - switch (tcp->u_arg[1]) { + switch (cmd) { case F_SETLK64: case F_SETLKW64: tprints(", "); diff --git a/tests/fcntl.c b/tests/fcntl.c index dfad530a..1ea83e14 100644 --- a/tests/fcntl.c +++ b/tests/fcntl.c @@ -44,7 +44,7 @@ test_flock64_einval(const int cmd, const char *name) .l_start = 0xdefaced1facefeed, .l_len = 0xdefaced2cafef00d }; - syscall(TEST_SYSCALL_NR, 0, cmd, &fl); + invoke_test_syscall(cmd, &fl); printf("%s(0, %s, %p) = %s\n", TEST_SYSCALL_STR, name, &fl, EINVAL_STR); } diff --git a/tests/fcntl64.c b/tests/fcntl64.c index 726576e6..b83a098d 100644 --- a/tests/fcntl64.c +++ b/tests/fcntl64.c @@ -44,7 +44,7 @@ test_flock64_einval(const int cmd, const char *name) .l_start = 0xdefaced1facefeed, .l_len = 0xdefaced2cafef00d }; - syscall(TEST_SYSCALL_NR, 0, cmd, &fl); + invoke_test_syscall(cmd, &fl); printf("%s(0, %s, {l_type=F_RDLCK, l_whence=SEEK_SET" ", l_start=%jd, l_len=%jd}) = %s\n", TEST_SYSCALL_STR, name, (intmax_t) fl.l_start, (intmax_t) fl.l_len, EINVAL_STR); @@ -64,7 +64,7 @@ test_flock64(void) .l_type = F_RDLCK, .l_len = FILE_LEN }; - int rc = syscall(TEST_SYSCALL_NR, 0, F_SETLK64, &fl); + long rc = invoke_test_syscall(F_SETLK64, &fl); printf("%s(0, F_SETLK64, {l_type=F_RDLCK, l_whence=SEEK_SET" ", l_start=0, l_len=%d}) = %s\n", TEST_SYSCALL_STR, FILE_LEN, rc ? EINVAL_STR : "0"); @@ -72,12 +72,12 @@ test_flock64(void) if (rc) return; - syscall(TEST_SYSCALL_NR, 0, F_GETLK64, &fl); + invoke_test_syscall(F_GETLK64, &fl); printf("%s(0, F_GETLK64, {l_type=F_UNLCK, l_whence=SEEK_SET" ", l_start=0, l_len=%d, l_pid=0}) = 0\n", TEST_SYSCALL_STR, FILE_LEN); - syscall(TEST_SYSCALL_NR, 0, F_SETLK64, &fl); + invoke_test_syscall(F_SETLK64, &fl); printf("%s(0, F_SETLK64, {l_type=F_UNLCK, l_whence=SEEK_SET" ", l_start=0, l_len=%d}) = 0\n", TEST_SYSCALL_STR, FILE_LEN); diff --git a/tests/struct_flock.c b/tests/struct_flock.c index fd427501..aae71a03 100644 --- a/tests/struct_flock.c +++ b/tests/struct_flock.c @@ -42,6 +42,14 @@ # define TYPEOF_FLOCK_OFF_T off_t #endif +static long +invoke_test_syscall(const unsigned int cmd, void *const p) +{ + const unsigned long op = (unsigned long) 0xffffffff00000000 | cmd; + + return syscall(TEST_SYSCALL_NR, 0, op, (unsigned long) p); +} + static void test_flock_einval(const int cmd, const char *name) { @@ -50,7 +58,7 @@ test_flock_einval(const int cmd, const char *name) .l_start = (TYPEOF_FLOCK_OFF_T) 0xdefaced1facefeed, .l_len = (TYPEOF_FLOCK_OFF_T) 0xdefaced2cafef00d }; - syscall(TEST_SYSCALL_NR, 0, cmd, &fl); + invoke_test_syscall(cmd, &fl); printf("%s(0, %s, {l_type=F_RDLCK, l_whence=SEEK_SET" ", l_start=%jd, l_len=%jd}) = %s\n", TEST_SYSCALL_STR, name, (intmax_t) fl.l_start, (intmax_t) fl.l_len, EINVAL_STR); @@ -66,19 +74,19 @@ test_flock(void) .l_type = F_RDLCK, .l_len = FILE_LEN }; - int rc = syscall(TEST_SYSCALL_NR, 0, F_SETLK, &fl); + long rc = invoke_test_syscall(F_SETLK, &fl); printf("%s(0, F_SETLK, {l_type=F_RDLCK, l_whence=SEEK_SET" ", l_start=0, l_len=%d}) = %s\n", TEST_SYSCALL_STR, FILE_LEN, rc ? EINVAL_STR : "0"); if (rc) return; - syscall(TEST_SYSCALL_NR, 0, F_GETLK, &fl); + invoke_test_syscall(F_GETLK, &fl); printf("%s(0, F_GETLK, {l_type=F_UNLCK, l_whence=SEEK_SET" ", l_start=0, l_len=%d, l_pid=0}) = 0\n", TEST_SYSCALL_STR, FILE_LEN); - syscall(TEST_SYSCALL_NR, 0, F_SETLK, &fl); + invoke_test_syscall(F_SETLK, &fl); printf("%s(0, F_SETLK, {l_type=F_UNLCK, l_whence=SEEK_SET" ", l_start=0, l_len=%d}) = 0\n", TEST_SYSCALL_STR, FILE_LEN);