]> granicus.if.org Git - strace/commitdiff
Fix decoding of fcntl/fcntl64 operation argument
authorDmitry V. Levin <ldv@altlinux.org>
Mon, 16 May 2016 21:01:43 +0000 (21:01 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 16 May 2016 21:46:48 +0000 (21:46 +0000)
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.

fcntl.c
tests/fcntl.c
tests/fcntl64.c
tests/struct_flock.c

diff --git a/fcntl.c b/fcntl.c
index e2a76f980870a6f9db5f9525edd43ea5b1ce556b..59eca9db403b33bceb045fa59d0f6d657af1e401 100644 (file)
--- 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(", ");
index dfad530ac0d86ff8948cf36fdddfeafaf76e5cde..1ea83e148bc0e1fe10045146d202c9b08e29e4d1 100644 (file)
@@ -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);
 }
index 726576e62aef8779258438eb3da17956c9cc05c0..b83a098d4281315fdfc5b1931127e3836c9b4558 100644 (file)
@@ -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);
index fd42750111d4b309107fc89068a92122aa2d2fc0..aae71a03441041b349ca1fb922d1e3f65cc40197 100644 (file)
 # 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);