All of lore.kernel.org
 help / color / mirror / Atom feed
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 */

  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.