]> granicus.if.org Git - strace/commitdiff
ioctl: fix ioctl command number decoding in case of conflicts
authorGabriel Laskar <gabriel@lse.epita.fr>
Wed, 23 Sep 2015 08:11:55 +0000 (10:11 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 23 Sep 2015 23:29:30 +0000 (23:29 +0000)
When a command number was decoded through ioctl_decode_command_number(),
there was no check for conflicts with other potential ioctls numbers.

For example:
ioctl(fd, MCE_GET_RECORD_LEN, &i);
output:
ioctl(3, MIXER_READ(1), 0x7ffddce74a58) = 0
instead of:
ioctl(3, MIXER_READ(1) or MCE_GET_RECORD_LEN, 0x7ffee435ce08) = 0

* ioctl.c (SYS_FUNC(ioctl)): Fix ioctl command number decoding
in case of conflicts.
* tests/ioctl.c (main): Add a case for command number conflicts.

Signed-off-by: Gabriel Laskar <gabriel@lse.epita.fr>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
ioctl.c
tests/ioctl.c

diff --git a/ioctl.c b/ioctl.c
index 284828a5a468db2e042a19957e8adc28e190c5ee..adce9867fd87901eeee46c25a1d7e6132f70666c 100644 (file)
--- a/ioctl.c
+++ b/ioctl.c
@@ -277,15 +277,16 @@ SYS_FUNC(ioctl)
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
                tprints(", ");
-               if (!ioctl_decode_command_number(tcp)) {
-                       iop = ioctl_lookup(tcp->u_arg[1]);
-                       if (iop) {
-                               tprints(iop->symbol);
-                               while ((iop = ioctl_next_match(iop)))
-                                       tprintf(" or %s", iop->symbol);
-                       } else {
-                               ioctl_print_code(tcp->u_arg[1]);
-                       }
+               ret = ioctl_decode_command_number(tcp);
+               iop = ioctl_lookup(tcp->u_arg[1]);
+               if (iop) {
+                       if (ret)
+                               tprints(" or ");
+                       tprints(iop->symbol);
+                       while ((iop = ioctl_next_match(iop)))
+                               tprintf(" or %s", iop->symbol);
+               } else if (!ret) {
+                       ioctl_print_code(tcp->u_arg[1]);
                }
                ret = ioctl_decode(tcp);
        } else {
index 7f9b84ce2c94420da1b7fea56733d3ab797af2be..7882140f8443cb6c8c350e427c11adaffd56bb7b 100644 (file)
@@ -58,6 +58,10 @@ main(void )
        printf("ioctl(-1, EVIOCGBIT(EV_KEY, 8), %p)"
               " = -1 EBADF (Bad file descriptor)\n", &data);
 
+       (void) ioctl(-1, _IOR('M', 13, int), &data);
+       printf("ioctl(-1, MIXER_READ(13) or OTPSELECT, [MTD_OTP_OFF])"
+              " = -1 EBADF (Bad file descriptor)\n");
+
        (void) ioctl(-1, _IOR(0xde, 0xad, data), &data);
        printf("ioctl(-1, _IOC(_IOC_READ, 0xde, 0xad, 0x08), %p)"
               " = -1 EBADF (Bad file descriptor)\n", &data);