From: David Howells <dhowells@redhat.com>
To: Chuck Ebbert <76306.1226@compuserve.com>
Cc: Andrew Morton <akpm@osdl.org>, Kasper Sandberg <lkml@metanurb.dk>,
linux-kernel <linux-kernel@vger.kernel.org>,
David Howells <dhowells@redhat.com>,
ak@muc.de, vojtech@suse.cz
Subject: Re: BUG? atleast >=2.6.19-rc5, x86 chroot on x86_64
Date: Tue, 05 Dec 2006 14:19:53 +0000 [thread overview]
Message-ID: <4701.1165328393@redhat.com> (raw)
In-Reply-To: <200612050436_MC3-1-D3F9-FB3D@compuserve.com>
[-- Attachment #1: Type: text/plain, Size: 2852 bytes --]
Chuck Ebbert <76306.1226@compuserve.com> wrote:
> Here is a patch to reverse that. Kasper, can you test it?
> (Your filesystem is on a FAT/VFAT volume, I assume.)
Please don't revert that patch. If you do, you'll break CONFIG_BLOCK=n.
Can you compile and run the attached program as both 32-bit and 64-bit?
On my x86_64 test box, I did:
[root@andromeda ~]# mkfs.vfat /dev/sda5
[root@andromeda ~]# mount /dev/sda5 /mnt
[root@andromeda ~]# mkdir /mnt/a
[root@andromeda ~]# /tmp/ioctl /mnt/a # 32-bit
268 : 82187201, 82187202
268 : 82187201, 82187202
Calling VFAT_IOCTL_READDIR_BOTH32
Calling VFAT_IOCTL_READDIR_BOTH
[root@andromeda ~]# /tmp/ioctl /mnt/a # 64-bit
280 : 82307201, 82307202
268 : 82187201, 82187202
Calling VFAT_IOCTL_READDIR_BOTH32
ioctl: Inappropriate ioctl for device
Calling VFAT_IOCTL_READDIR_BOTH
Which is what I'd expect (the 64-bit ioctl does not support the 32-bit
function). Tracing the 64-bit version shows that the right numbers are being
given to the syscall, though strace decodes them as the same symbol if not in
raw mode:
[root@andromeda ~]# strace -eioctl -eraw=ioctl /tmp/ioctl /mnt/a
280 : 82307201, 82307202
268 : 82187201, 82187202
Calling VFAT_IOCTL_READDIR_BOTH32
ioctl(0x3, 0x82187201, 0x7fff9cec36c0) = -1 (errno 25)
ioctl: Inappropriate ioctl for device
Calling VFAT_IOCTL_READDIR_BOTH
ioctl(0x3, 0x82307201, 0x7fff9cec3490) = 0x1
Process 3410 detached
Applying the attached patch to the kernel produces the following elements in
the log for the 32-bit compilation:
==> fat_compat_dir_ioctl(82187201,ffa803b8)
==> fat_dir_ioctl(82307201,ffff810036a97ca8)
<== fat_dir_ioctl() = 1
<== fat_compat_dir_ioctl() = 1
==> fat_compat_dir_ioctl(82187201,ffa801a0)
==> fat_dir_ioctl(82307201,ffff810036a97ca8)
<== fat_dir_ioctl() = 1
<== fat_compat_dir_ioctl() = 1
and this for the 64-bit compilation:
==> fat_dir_ioctl(82187201,7fff031f69f0)
call fat_generic_ioctl()
<== fat_dir_ioctl() = -25
==> fat_dir_ioctl(82307201,7fff031f67c0)
<== fat_dir_ioctl() = 1
Which is entirely what I'd expect.
However, it's possible that the 64-bit kernel interface used to allow the
32-bit calls. If that's the case could you be running a 64-bit program
somewhere in your 32-bit chroot?
| i have only tested with >=rc5, thw folling, as an example, appears in
| dmesg:
| ioctl32(regedit.exe:11801): Unknown cmd fd(9) cmd(82187201){02}
| arg(00221000) on /home/redeeman
| ioctl32(regedit.exe:11801): Unknown cmd fd(9) cmd(82187201){02}
| arg(00221000) on /home/redeeman/.wine/drive_c/windows/system32
| ioctl32(regedit.exe:11801): Unknown cmd fd(9) cmd(82187201){02}
| arg(00221000) on /home/redeeman/.wine/drive_c/windows/system
How do you get that? I don't see anything like that. I've tried:
echo 1 >/proc/sys/kernel/compat-log
But that doesn't seem to do anything.
David
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: ioctl.c --]
[-- Type: text/x-c, Size: 3054 bytes --]
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define _IOC_NRBITS 8
#define _IOC_TYPEBITS 8
#define _IOC_SIZEBITS 14
#define _IOC_DIRBITS 2
#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
#define _IOC_NRSHIFT 0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
#define _IOC_NONE 0U
#define _IOC_WRITE 1U
#define _IOC_READ 2U
#define _IOC(dir,type,nr,size) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
extern unsigned int __invalid_size_argument_for_IOC;
#define _IOC_TYPECHECK(t) \
((sizeof(t) == sizeof(t[1]) && \
sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
sizeof(t) : __invalid_size_argument_for_IOC)
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2])
#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef long __kernel_off_t;
typedef s32 compat_off_t;
struct compat_dirent {
u32 d_ino;
compat_off_t d_off;
u16 d_reclen;
char d_name[256];
};
struct dirent {
long d_ino;
__kernel_off_t d_off;
unsigned short d_reclen;
char d_name[256]; /* We must not include limits.h! */
};
#define O_DIRECTORY 00200000 /* must be a directory */
int main(int argc, char *argv[])
{
struct compat_dirent cdire[2];
struct dirent dire[2];
int fd;
printf("%zu : %lx, %lx\n",
sizeof(struct dirent),
(unsigned long) VFAT_IOCTL_READDIR_BOTH,
(unsigned long) VFAT_IOCTL_READDIR_SHORT);
printf("%zu : %lx, %lx\n",
sizeof(struct compat_dirent),
(unsigned long) VFAT_IOCTL_READDIR_BOTH32,
(unsigned long) VFAT_IOCTL_READDIR_SHORT32);
for (argv++; *argv; argv++) {
fd = open(*argv, O_DIRECTORY | O_RDONLY);
if (fd < 0) {
perror(*argv);
exit(1);
}
printf("Calling VFAT_IOCTL_READDIR_BOTH32\n");
if (ioctl(fd, VFAT_IOCTL_READDIR_BOTH32, cdire) < 0)
perror("ioctl");
printf("Calling VFAT_IOCTL_READDIR_BOTH\n");
if (ioctl(fd, VFAT_IOCTL_READDIR_BOTH, dire) < 0)
perror("ioctl");
close(fd);
}
return 0;
}
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: ioctl.diff --]
[-- Type: text/x-patch, Size: 1365 bytes --]
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 69c439f..eadaef1 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -704,6 +704,8 @@ static int fat_dir_ioctl(struct inode *
struct dirent __user *d1;
int ret, short_only, both;
+ printk("==> fat_dir_ioctl(%x,%lx)\n", cmd, arg);
+
switch (cmd) {
case VFAT_IOCTL_READDIR_SHORT:
short_only = 1;
@@ -714,7 +716,9 @@ static int fat_dir_ioctl(struct inode *
both = 1;
break;
default:
- return fat_generic_ioctl(inode, filp, cmd, arg);
+ printk("call fat_generic_ioctl()\n");
+ ret = fat_generic_ioctl(inode, filp, cmd, arg);
+ goto out;
}
d1 = (struct dirent __user *)arg;
@@ -739,6 +743,8 @@ static int fat_dir_ioctl(struct inode *
mutex_unlock(&inode->i_mutex);
if (ret >= 0)
ret = buf.result;
+out:
+ printk("<== fat_dir_ioctl() = %d\n", ret);
return ret;
}
@@ -769,6 +775,8 @@ static long fat_compat_dir_ioctl(struct
mm_segment_t oldfs = get_fs();
struct dirent d[2];
+ printk("==> fat_compat_dir_ioctl(%x,%lx)\n", cmd, arg);
+
switch (cmd) {
case VFAT_IOCTL_READDIR_BOTH32:
cmd = VFAT_IOCTL_READDIR_BOTH;
@@ -790,6 +798,7 @@ static long fat_compat_dir_ioctl(struct
ret |= fat_compat_put_dirent32(&d[0], p);
ret |= fat_compat_put_dirent32(&d[1], p + 1);
}
+ printk("<== fat_compat_dir_ioctl() = %d\n", ret);
return ret;
}
#endif /* CONFIG_COMPAT */
next prev parent reply other threads:[~2006-12-05 14:20 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-05 9:33 BUG? atleast >=2.6.19-rc5, x86 chroot on x86_64 Chuck Ebbert
2006-12-05 14:19 ` David Howells [this message]
2006-12-06 0:11 ` Kasper Sandberg
-- strict thread matches above, loose matches on Subject: below --
2006-12-13 7:50 Chuck Ebbert
2006-12-13 8:05 ` Kasper Sandberg
2006-12-13 11:08 ` Alan
2006-12-11 8:27 Chuck Ebbert
2006-12-13 4:39 ` Kasper Sandberg
2006-12-06 2:31 Chuck Ebbert
2006-12-06 12:58 ` Kasper Sandberg
2006-12-06 13:08 ` David Howells
2006-12-06 16:06 ` Kasper Sandberg
2006-12-06 16:48 ` David Howells
2006-12-06 20:05 ` Kasper Sandberg
2006-12-06 21:29 ` Andi Kleen
2006-12-06 22:19 ` Kasper Sandberg
2006-12-05 20:32 Chuck Ebbert
2006-12-05 22:11 ` David Howells
2006-11-22 14:29 Kasper Sandberg
2006-11-22 23:25 ` Andrew Morton
2006-11-26 13:47 ` Kasper Sandberg
2006-12-05 2:36 ` Kasper Sandberg
2006-12-05 2:59 ` Kasper Sandberg
2006-12-05 3:20 ` Andrew Morton
2006-12-05 14:17 ` David Howells
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4701.1165328393@redhat.com \
--to=dhowells@redhat.com \
--cc=76306.1226@compuserve.com \
--cc=ak@muc.de \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lkml@metanurb.dk \
--cc=vojtech@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox