[BusyBox 0002884]: ioctl() wrappers broken on 64-bit systems

bugs at busybox.net bugs at busybox.net
Thu Apr 10 23:25:02 UTC 2008


A NOTE has been added to this issue. 
====================================================================== 
http://busybox.net/bugs/view.php?id=2884 
====================================================================== 
Reported By:                ncase
Assigned To:                BusyBox
====================================================================== 
Project:                    BusyBox
Issue ID:                   2884
Category:                   Other
Reproducibility:            always
Severity:                   major
Priority:                   normal
Status:                     assigned
====================================================================== 
Date Submitted:             04-10-2008 16:06 PDT
Last Modified:              04-10-2008 16:25 PDT
====================================================================== 
Summary:                    ioctl() wrappers broken on 64-bit systems
Description: 
The ioctl_*() and bb_xioctl*() functions declare the second argument as
"int request" rather than "unsigned long int request" which break the
ioctl() calls on 64-bit systems.

This bug presented itself in the form of login failing during the termios
TCSETS call:

    getty: /dev/ttyS0: TCSETS: Invalid argument

I verified that changing the "request" argument to "unsigned long int"
fixes the problem.  It should leave 32-bit systems unaffected.  See
attached patch.
====================================================================== 

---------------------------------------------------------------------- 
 ncase - 04-10-08 16:08  
---------------------------------------------------------------------- 
The patches are for the unstable tree and also the busybox_1_9_stable tree. 

---------------------------------------------------------------------- 
 vda - 04-10-08 16:25  
---------------------------------------------------------------------- 
This is strange, since both Linux and POSIX man pages say that that
parameter is int, not long:

#include <sys/ioctl.h>
int ioctl(int d, int request, ...);


I assume you are talking about this call in getty.c:

ioctl_or_perror_and_die(0, TCSETS, tp, "%s: TCSETS", op->tty);

TCSETS is defined as follows (in glibc, probaly the same in all other
lics):

#define TCSETS          0x5402

I don't understand how this code doesn't work:

int ioctl_or_perror_and_die(int fd, int request, void *argp, const char
*fmt,...)
{
        int ret;
        va_list p;

        ret = ioctl(fd, request, argp);
        if (ret < 0) {
                va_start(p, fmt);
                bb_verror_msg(fmt, p, strerror(errno));
                /* xfunc_die can actually longjmp, so be nice */
                va_end(p);
                xfunc_die();
        }
        return ret;
}

but replacing "int request" with "unsigned long request" makes it work?
It should work the same since 0x5402 comfortably fits into both 32-bit
int
and 64-bit long.

Can you describe failure scenario in more details? Why exactly it is
failing? 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
04-10-08 16:06  ncase          New Issue                                    
04-10-08 16:06  ncase          Status                   new => assigned     
04-10-08 16:06  ncase          Assigned To               => BusyBox         
04-10-08 16:06  ncase          File Added:
busybox-unstable-ioctl-64bit-fix.patch                    
04-10-08 16:08  ncase          File Added: busybox-stable-ioctl-64bit-fix.patch 
                  
04-10-08 16:08  ncase          Note Added: 0006514                          
04-10-08 16:25  vda            Note Added: 0006524                          
======================================================================




More information about the busybox-cvs mailing list