[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