[PATCH] Fix ioctl() wrappers for 64-bit systems

Denys Vlasenko vda.linux at googlemail.com
Fri Apr 11 17:17:28 PDT 2008


On Friday 11 April 2008 19:41, Nate Case wrote:
> From this output, everything looks fine.  It's the actual system call
> that gets the bogus argument.  I made a simple standalone test case that
> demonstrates this same weird behavior:
> 
> ---[snip]---
> #include <stdio.h>
> #include <stdlib.h>                                                             
> #include <stdarg.h>                                                             
> #include <termios.h>                                                            
> #include <errno.h>                                                              
> #include <asm/ioctls.h>                                                         
>                                                                                 
> void ioctl_wrapper(int fd, int request, void *argp)               
> {                                                                               
>         printf("ioctl_wrapper: req = %x, argp = %p\n", request, argp);        
>         if (ioctl(fd, request, argp) < 0) {                                     
>                 printf("ioctl_wrapper() failed!\n");                          
>                 exit(-2);                                                       
>         }                                                                       
>         printf("ioctl_wrapper() success!\n");                                 
> }                            
> 
> int main(void)                                                                  
> {                                                                               
>         int res;                                                                
>         struct termios termios;                                                 
>                                                                                 
>         printf("main TCGETS: req = %x, argp = %p\n", TCGETS, &termios);       
>         ioctl_wrapper(0, TCGETS, &termios);                                     
>         printf("main TCSETS: req = %x, argp = %p\n", TCSETS, &termios);       
>         ioctl_wrapper(0, TCSETS, &termios);                                     
> }         
> ---[snip]---
> 
> Running on i386:
> 
>     $ ./ioctl-bug 
>     main TCGETS: req = 5401, argp = 0xbff9da84
>     ioctl_wrapper: req = 5401, argp = 0xbff9da84
>     ioctl_wrapper() success!
>     main TCSETS: req = 5402, argp = 0xbff9da84
>     ioctl_wrapper: req = 5402, argp = 0xbff9da84
>     ioctl_wrapper() success!
> 
> Running on ppc64:
> 
>     $ ./ioctl-bug 
>     main TCGETS: req = 403c7413, argp = 0xfffffebf640                               
>     ioctl_wrapper: req = 403c7413, argp = 0xfffffebf640                             
>     ioctl_wrapper() success!                                                        
>     main TCSETS: req = 803c7414, argp = 0xfffffebf640                               
>     ioctl_wrapper: req = 803c7414, argp = 0xfffffebf640                             
>     ioctl_wrapper() failed!     
> 
> Running on AMD64:
> 
>     $ ./ioctl-bug.amd64 
>     main TCGETS: req = 5401, argp = 0x7fff956cd5d0
>     ioctl_wrapper: req = 5401, argp = 0x7fff956cd5d0
>     ioctl_wrapper() success!
>     main TCSETS: req = 5402, argp = 0x7fff956cd5d0
>     ioctl_wrapper: req = 5402, argp = 0x7fff956cd5d0
>     ioctl_wrapper() success!
> 
> So it doesn't appear to really affect all 64-bit systems since it worked
> on x86-64.  It's also interesting that it seems to specifically affect
> TCSETS and not TCGETS.

I'd hazard to guess that ppc64's libc has ioctl
declared as

int ioctl(int d, ...); /* request is a vararg too!!! */

and you need to explicitly cast 2nd parameter to long
for correct operation. In your testcase:

         printf("ioctl_wrapper: req = %x, argp = %p\n", request, argp);        
-        if (ioctl(fd, request, argp) < 0) {
+        if (ioctl(fd, (long)request, argp) < 0) {

If this indeed is true, you need to fix ppc64 libc headers!

Can you send preprocessed output of your testcase in ppc64?
--
vda


More information about the busybox mailing list