Notes |
(0006514)
ncase
04-10-08 16:08
|
The patches are for the unstable tree and also the busybox_1_9_stable tree. |
|
(0006524)
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? |
|
(0006534)
ncase
04-10-08 16:41
|
The man pages do say int, but if I actually look in sys/ioctl.h on all of my systems here I see the following:
extern int ioctl (int __fd, unsigned long int __request, ...) __THROW;
You are correct that it's the ioctl_or_perror_and_die() call in getty.c which is failing. I suspected that something was getting mangled in the argument passing after seeing this strange strace of getty (I've included only the ioctl calls):
ioctl(0, TCGETS, {B115200 opost isig -icanon -echo ...}) = 0
ioctl(0, TIOCSPGRP, [-1905424]) = -1 ENOTTY (Inappropriate ioctl for device)
ioctl(0, TCFLSH, 0x2) = 0
ioctl(0, TCSETS, {B115200 opost -isig -icanon -echo ...}) = 0
ioctl(0, TCFLSH, 0) = 0
ioctl(1, TCGETS, {B115200 opost -isig -icanon -echo ...}) = 0
ioctl(0, TCSETS, 0xfffffe2eb90) = -1 EINVAL (Invalid argument)
The final ioctl() which fails happens right after I enter the login name, and it prints out the error message I mentioned before. The ioctls() before it which succeed are calling ioctl() directly rather than using the wrapper.
So what appears to be happening is that the incorrect size of 'request' is actually mangling the value of the argp that gets passed, since you can see that strace sees it as TCSETS properly. |
|
(0006544)
vda
04-10-08 16:47
|
Can you printf("%p", argp) before the call to ioctl_or_perror_and_die() and inside the call? |
|
(0007044)
vda
04-23-08 21:48
|
fixed in svn and will be in 1.10.2. |
|