Skip to contentSkip to conversation

sanitize building of fs/compat_ioctl.c

PATCH In review Christoph Hellwig 4 participants 8 messages Dec 13, 2005 – Dec 14, 2005

Subsystems (6)
VFS PowerPC MIPS s390 +2 more subsystems
lore
Share & tools
lore
#0 lore raw

PATCH 3/3 sanitize building of fs/compat_ioctl.c

Now that all these entries in the arch ioctl32.c files are gone [1], we can build fs/compat_ioctl.c as a normal object and kill tons of cruft. We need a special do_ioctl32_pointer handler for s390 so the compat_ptr call is done. This is not needed but harmless on all other architectures. Also remove some superflous includes in fs/compat_ioctl.c

Tested on ppc64.

[1] parisc still had it's PPP handler left, which is not fully correct for ppp and besides that ppp uses the generic SIOCPRIV ioctl so it'd kick in for all netdevice users. We can introduce a proper handler in one of the next patch series by adding a compat_ioctl method to struct net_device but for now let's just kill it - parisc doesn't compile in mainline anyway and I don't want this to block this patchset.

arch/ia64/ia32/ia32_ioctl.c deleted +0 -45
Index: linux-2.6.15-rc5/arch/ia64/ia32/ia32_ioctl.c
===================================================================
@@ -1,45 +0,0 @@
-/*
- * IA32 Architecture-specific ioctl shim code
- *
- * Copyright (C) 2000 VA Linux Co
- * Copyright (C) 2000 Don Dugger <[email protected]>
- * Copyright (C) 2001-2003 Hewlett-Packard Co
- *	David Mosberger-Tang <[email protected]>
- */
-
-#include <linux/signal.h>	/* argh, msdos_fs.h isn't self-contained... */
-#include <linux/syscalls.h>
-#include "ia32priv.h"
-  
-#define	INCLUDES
-#include "compat_ioctl.c"
-
-#define IOCTL_NR(a)	((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
-
-#define DO_IOCTL(fd, cmd, arg) ({			\
-	int _ret;					\
-	mm_segment_t _old_fs = get_fs();		\
-							\
-	set_fs(KERNEL_DS);				\
-	_ret = sys_ioctl(fd, cmd, (unsigned long)arg);	\
-	set_fs(_old_fs);				\
-	_ret;						\
-})
-
-#define CODE
-#include "compat_ioctl.c"
-
-#define COMPATIBLE_IOCTL(cmd)		HANDLE_IOCTL((cmd),sys_ioctl)
-#define HANDLE_IOCTL(cmd,handler)	{ (cmd), (ioctl_trans_handler_t)(handler), NULL },
-#define IOCTL_TABLE_START \
-	struct ioctl_trans ioctl_start[] = {
-#define IOCTL_TABLE_END \
-	};
-
-IOCTL_TABLE_START
-#define DECLARES
-#include "compat_ioctl.c"
-#include <linux/compat_ioctl.h>
-IOCTL_TABLE_END
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
arch/mips/kernel/ioctl32.c deleted +0 -50

50 lines not on this page · raw message

arch/parisc/kernel/ioctl32.c deleted +0 -41

41 lines not on this page · raw message

arch/powerpc/kernel/ioctl32.c deleted +0 -45

45 lines not on this page · raw message

arch/sparc64/kernel/ioctl32.c deleted +0 -39
Index: linux-2.6.15-rc5/arch/sparc64/kernel/ioctl32.c
===================================================================
@@ -1,39 +0,0 @@
-/* $Id: ioctl32.c,v 1.136 2002/01/14 09:49:52 davem Exp $
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- *
- * Copyright (C) 1997-2000  Jakub Jelinek  ([email protected])
- * Copyright (C) 1998  Eddie C. Dost  ([email protected])
- * Copyright (C) 2003  Pavel Machek ([email protected])
- *
- * These routines maintain argument size conversion between 32bit and 64bit
- * ioctls.
- */
-
-#define INCLUDES
-#include "compat_ioctl.c"
-#include <linux/syscalls.h>
-
-#define CODE
-#include "compat_ioctl.c"
-
-#define COMPATIBLE_IOCTL(cmd)		HANDLE_IOCTL((cmd),sys_ioctl)
-#define HANDLE_IOCTL(cmd,handler)	{ (cmd), (ioctl_trans_handler_t)(handler), NULL },
-#define IOCTL_TABLE_START \
-	struct ioctl_trans ioctl_start[] = {
-#define IOCTL_TABLE_END \
-	};
-
-IOCTL_TABLE_START
-#include <linux/compat_ioctl.h>
-#define DECLARES
-#include "compat_ioctl.c"
-#if 0
-HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl)
-HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl)
-HANDLE_IOCTL(RTC32_EPOCH_READ, do_rtc_ioctl)
-HANDLE_IOCTL(RTC32_EPOCH_SET, do_rtc_ioctl)
-#endif
-/* take care of sizeof(sizeof()) breakage */
-IOCTL_TABLE_END
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
arch/x86_64/ia32/ia32_ioctl.c deleted +0 -32
Index: linux-2.6.15-rc5/arch/x86_64/ia32/ia32_ioctl.c
===================================================================
@@ -1,32 +0,0 @@
-/* $Id: ia32_ioctl.c,v 1.25 2002/10/11 07:17:06 ak Exp $
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- *
- * Copyright (C) 1997-2000  Jakub Jelinek  ([email protected])
- * Copyright (C) 1998  Eddie C. Dost  ([email protected])
- * Copyright (C) 2001,2002  Andi Kleen, SuSE Labs 
- *
- * These routines maintain argument size conversion between 32bit and 64bit
- * ioctls.
- */
-
-#define INCLUDES
-#include <linux/syscalls.h>
-#include "compat_ioctl.c"
-#include <asm/ia32.h>
-
-#define CODE
-#include "compat_ioctl.c"
-
-
-#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler) }, 
-#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
-
-struct ioctl_trans ioctl_start[] = { 
-#include <linux/compat_ioctl.h>
-#define DECLARES
-#include "compat_ioctl.c"
-/* take care of sizeof(sizeof()) breakage */
-}; 
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
-
arch/s390/kernel/compat_ioctl.c deleted +0 -47

47 lines not on this page · raw message

include/linux/compat_ioctl.h +0 -8
Index: linux-2.6.15-rc5/include/linux/compat_ioctl.h
===================================================================
@@ -2,14 +2,6 @@
  * compatible types passed or none at all... Please include
  * only stuff that is compatible on *all architectures*.
  */
-#ifndef COMPATIBLE_IOCTL /* pointer to compatible structure or no argument */
-#define COMPATIBLE_IOCTL(cmd)  HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl)
-#endif
-
-#ifndef ULONG_IOCTL /* argument is an unsigned long integer, not a pointer */
-#define ULONG_IOCTL(cmd)  HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl)
-#endif
-
 
 COMPATIBLE_IOCTL(0x4B50)   /* KDGHWCLK - not in the kernel, but don't complain */
 COMPATIBLE_IOCTL(0x4B51)   /* KDSHWCLK - not in the kernel, but don't complain */
fs/Makefile +1 -1
Index: linux-2.6.15-rc5/fs/Makefile
===================================================================
@@ -14,7 +14,7 @@
 
 obj-$(CONFIG_INOTIFY)		+= inotify.o
 obj-$(CONFIG_EPOLL)		+= eventpoll.o
-obj-$(CONFIG_COMPAT)		+= compat.o
+obj-$(CONFIG_COMPAT)		+= compat.o compat_ioctl.o
 
 nfsd-$(CONFIG_NFSD)		:= nfsctl.o
 obj-y				+= $(nfsd-y) $(nfsd-m)
fs/compat_ioctl.c +21 -16
Index: linux-2.6.15-rc5/fs/compat_ioctl.c
===================================================================
@@ -10,7 +10,6 @@
  * ioctls.
  */
 
-#ifdef INCLUDES
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/compat.h>
@@ -82,13 +81,9 @@
 #include <linux/capi.h>
 
 #include <scsi/scsi.h>
-/* Ugly hack. */
-#undef __KERNEL__
 #include <scsi/scsi_ioctl.h>
-#define __KERNEL__
 #include <scsi/sg.h>
 
-#include <asm/types.h>
 #include <asm/uaccess.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
@@ -96,7 +91,6 @@
 #include <linux/watchdog.h>
 #include <linux/dm-ioctl.h>
 
-#include <asm/module.h>
 #include <linux/soundcard.h>
 #include <linux/lp.h>
 #include <linux/ppdev.h>
@@ -129,11 +123,6 @@
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/video.h>
 
-#undef INCLUDES
-#endif
-
-#ifdef CODE
-
 /* Aiee. Someone does not find a difference between int and long */
 #define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
 #define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
@@ -149,6 +138,12 @@
 #define EXT2_IOC32_GETVERSION             _IOR('v', 1, int)
 #define EXT2_IOC32_SETVERSION             _IOW('v', 2, int)
 
+static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
+			      unsigned long arg, struct file *f)
+{
+	return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
+}
+
 static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	mm_segment_t old_fs = get_fs();
@@ -2706,10 +2701,20 @@
 }
 #endif
 
-#undef CODE
-#endif
+#define HANDLE_IOCTL(cmd,handler) \
+	{ (cmd), (ioctl_trans_handler_t)(handler) },
+
+/* pointer to compatible structure or no argument */
+#define COMPATIBLE_IOCTL(cmd) \
+	{ (cmd), do_ioctl32_pointer },
+
+/* argument is an unsigned long integer, not a pointer */
+#define ULONG_IOCTL(cmd) \
+	{ (cmd), (ioctl_trans_handler_t)sys_ioctl },
 
-#ifdef DECLARES
+
+struct ioctl_trans ioctl_start[] = {
+#include <linux/compat_ioctl.h>
 HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
 HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
 #ifdef CONFIG_NET
@@ -2922,6 +2927,6 @@
 HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event)
 HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture)
 HANDLE_IOCTL(VIDEO_SET_SPU_PALETTE, do_video_set_spu_palette)
+};
 
-#undef DECLARES
-#endif
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);
arch/ia64/ia32/Makefile +1 -3
Index: linux-2.6.15-rc5/arch/ia64/ia32/Makefile
===================================================================
@@ -2,11 +2,9 @@
 # Makefile for the ia32 kernel emulation subsystem.
 #
 
-obj-y := ia32_entry.o sys_ia32.o ia32_ioctl.o ia32_signal.o \
+obj-y := ia32_entry.o sys_ia32.o ia32_signal.o \
 	 ia32_support.o ia32_traps.o binfmt_elf32.o ia32_ldt.o
 
-CFLAGS_ia32_ioctl.o += -Ifs/
-
 # Don't let GCC uses f16-f31 so that save_ia32_fpstate_live() and
 # restore_ia32_fpstate_live() can be sure the live register contain user-level state.
 CFLAGS_ia32_signal.o += -mfixed-range=f16-f31
arch/mips/kernel/Makefile +1 -2
Index: linux-2.6.15-rc5/arch/mips/kernel/Makefile
===================================================================
@@ -50,7 +50,7 @@
 obj-$(CONFIG_32BIT)		+= scall32-o32.o
 obj-$(CONFIG_64BIT)		+= scall64-64.o
 obj-$(CONFIG_BINFMT_IRIX)	+= binfmt_irix.o
-obj-$(CONFIG_MIPS32_COMPAT)	+= ioctl32.o linux32.o signal32.o
+obj-$(CONFIG_MIPS32_COMPAT)	+= linux32.o signal32.o
 obj-$(CONFIG_MIPS32_N32)	+= binfmt_elfn32.o scall64-n32.o signal_n32.o
 obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o ptrace32.o
 
@@ -60,6 +60,5 @@
 obj-$(CONFIG_64BIT)		+= cpu-bugs64.o
 
 CFLAGS_cpu-bugs64.o	= $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
-CFLAGS_ioctl32.o	+= -Ifs/
 
 EXTRA_AFLAGS := $(CFLAGS)
arch/parisc/kernel/Makefile +1 -2
Index: linux-2.6.15-rc5/arch/parisc/kernel/Makefile
===================================================================
@@ -6,7 +6,6 @@
 
 AFLAGS_entry.o	:= -traditional
 AFLAGS_pacache.o := -traditional
-CFLAGS_ioctl32.o := -Ifs/
 
 obj-y	     	:= cache.o pacache.o setup.o traps.o time.o irq.o \
 		   pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
@@ -19,6 +18,6 @@
 obj-$(CONFIG_PA11)	+= pci-dma.o
 obj-$(CONFIG_PCI)	+= pci.o
 obj-$(CONFIG_MODULES)	+= module.o
-obj-$(CONFIG_64BIT)	+= binfmt_elf32.o sys_parisc32.o ioctl32.o signal32.o
+obj-$(CONFIG_64BIT)	+= binfmt_elf32.o sys_parisc32.o signal32.o
 # only supported for PCX-W/U in 64-bit mode at the moment
 obj-$(CONFIG_64BIT)	+= perf.o perf_asm.o
arch/powerpc/kernel/Makefile +1 -2
Index: linux-2.6.15-rc5/arch/powerpc/kernel/Makefile
===================================================================
@@ -4,7 +4,6 @@
 
 ifeq ($(CONFIG_PPC64),y)
 EXTRA_CFLAGS	+= -mno-minimal-toc
-CFLAGS_ioctl32.o += -Ifs/
 endif
 ifeq ($(CONFIG_PPC32),y)
 CFLAGS_prom_init.o      += -fPIC
@@ -17,7 +16,7 @@
 obj-y				+= vdso32/
 obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
 				   signal_64.o ptrace32.o systbl.o \
-				   paca.o ioctl32.o cpu_setup_power4.o \
+				   paca.o cpu_setup_power4.o \
 				   firmware.o sysfs.o idle_64.o
 obj-$(CONFIG_PPC64)		+= vdso64/
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
arch/s390/kernel/Makefile +1 -2
Index: linux-2.6.15-rc5/arch/s390/kernel/Makefile
===================================================================
@@ -15,8 +15,7 @@
 obj-$(CONFIG_SMP)		+= smp.o
 
 obj-$(CONFIG_S390_SUPPORT)	+= compat_linux.o compat_signal.o \
-					compat_ioctl.o compat_wrapper.o \
-					compat_exec_domain.o
+					compat_wrapper.o compat_exec_domain.o
 obj-$(CONFIG_BINFMT_ELF32)	+= binfmt_elf32.o
 
 obj-$(CONFIG_ARCH_S390_31)	+= entry.o reipl.o
arch/sparc64/kernel/Makefile +1 -3
Index: linux-2.6.15-rc5/arch/sparc64/kernel/Makefile
===================================================================
@@ -16,7 +16,7 @@
 obj-$(CONFIG_PCI)	 += ebus.o isa.o pci_common.o pci_iommu.o \
 			    pci_psycho.o pci_sabre.o pci_schizo.o
 obj-$(CONFIG_SMP)	 += smp.o trampoline.o
-obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o ioctl32.o
+obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o
 obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
 obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
 obj-$(CONFIG_MODULES) += module.o
@@ -40,5 +40,3 @@
 
 head.o: head.S ttable.S itlb_base.S dtlb_base.S dtlb_backend.S dtlb_prot.S \
 	etrap.S rtrap.S winfixup.S entry.S
-
-CFLAGS_ioctl32.o += -Ifs/
arch/x86_64/ia32/Makefile +1 -3
Index: linux-2.6.15-rc5/arch/x86_64/ia32/Makefile
===================================================================
@@ -2,8 +2,7 @@
 # Makefile for the ia32 kernel emulation subsystem.
 #
 
-obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \
-	ia32_signal.o tls32.o \
+obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o tls32.o \
 	ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o
 
 sysv-$(CONFIG_SYSVIPC) := ipc32.o
@@ -29,4 +28,3 @@
 
 AFLAGS_vsyscall-sysenter.o = -m32
 AFLAGS_vsyscall-syscall.o = -m32
-CFLAGS_ia32_ioctl.o += -Ifs/
#1 lore raw
Quoted 7 lines · Christoph Hellwig

[1] parisc still had it's PPP handler left, which is not fully correct for ppp and besides that ppp uses the generic SIOCPRIV ioctl so it'd kick in for all netdevice users. We can introduce a proper handler in one of the next patch series by adding a compat_ioctl method to struct net_device but for now let's just kill it - parisc doesn't compile in mainline anyway and I don't want this to block this patchset.

parisc probably does compile in mainline these days. It's certainly much closer than it ever was before. The 64-bit code doesn't compile because Andi keeps blocking the is_compat_task() stuff. Why not do the netdevice compat_ioctl patch before killing this? I'd hate to have to back out this patch in the PA tree.

#2 lore raw

From: Matthew Wilcox <[email protected]>
Date: Tue, 13 Dec 2005 10:34:34 -0700

Quoted 2 lines

The 64-bit code doesn't compile because Andi keeps blocking the is_compat_task() stuff.

The one place where I ever thought that was necessary, the USB async userspace I/O operation stuff, was solved much more cleanly with ->compat_ioctl() file_operations handlers.

What do you really still need it for at this point?

I also would like to avoid it if possible.

#3 lore raw
Quoted 11 lines · David S. Miller

From: Matthew Wilcox <[email protected]>
Date: Tue, 13 Dec 2005 10:34:34 -0700

Quoted 2 lines

The 64-bit code doesn't compile because Andi keeps blocking the is_compat_task() stuff.

The one place where I ever thought that was necessary, the USB async userspace I/O operation stuff, was solved much more cleanly with ->compat_ioctl() file_operations handlers.

What do you really still need it for at this point?

PPP.

#4 lore raw

From: Matthew Wilcox <[email protected]>
Date: Tue, 13 Dec 2005 15:53:47 -0700

Quoted 4 lines · David S. Miller
Quoted 1 line

What do you really still need it for at this point?

PPP.

Please show me offline how PPP needs this in a way that can't be solved by ->compat_ioctl() or similar. Thanks. I looked at arch/parisc/kernel/ioctl32.c and didn't see anything obvious.

#5 lore raw
In reply to David S. Miller
Quoted 11 lines · David S. Miller

From: Matthew Wilcox <[email protected]>
Date: Tue, 13 Dec 2005 10:34:34 -0700

Quoted 2 lines

The 64-bit code doesn't compile because Andi keeps blocking the is_compat_task() stuff.

The one place where I ever thought that was necessary, the USB async userspace I/O operation stuff, was solved much more cleanly with ->compat_ioctl() file_operations handlers.

What do you really still need it for at this point?

input needs it :/ Take a look at drivers/input/evdev.c:evdev_write_compat Someone should roast in hell for that code.

Quoted 1 line

I also would like to avoid it if possible.

I have given in for now. Assuming the test is done on a flag that is only set by the system call entry path. But I still think it will result in a lot of ugly code. For for read/write it's hard to avoid because there are so many variants and we have too many message passing protocols now.

That said I have been too lazy so far to actually implement it:/

-Andi

#6 lore raw

From: Andi Kleen <[email protected]>
Date: 14 Dec 2005 02:41:42 +0100

Quoted 5 lines
Quoted 1 line · David S. Miller

What do you really still need it for at this point?

input needs it :/ Take a look at drivers/input/evdev.c:evdev_write_compat

...

Quoted 5 lines

I have given in for now. Assuming the test is done on a flag that is only set by the system call entry path. But I still think it will result in a lot of ugly code. For for read/write it's hard to avoid because there are so many variants and we have too many message passing protocols now.

I suppose. We could also funnel down ->compat_{read,write}() and so on down the call chain, but that would likely be even uglier.

I guess with is_compat_task() we can do the netlink and pfkeyv2 compat stuff on ia64/x86_64. I don't look forward to reviewing a patch implementing that, however :-/

#7 lore raw
Quoted 2 lines

I suppose. We could also funnel down ->compat_{read,write}() and so on down the call chain, but that would likely be even uglier.

The problem is that this would need to be done for all variants (write, writev, aio_write, send{,msg,to} etc.) Same for read. I probably forgot one or two.

Quoted 3 lines

I guess with is_compat_task() we can do the netlink and pfkeyv2 compat stuff on ia64/x86_64. I don't look forward to reviewing a patch implementing that, however :-/

And iptables, although that would be probably *really* ugly. It's a bit of a sore spot on x86-64 though. 64bit kernel with full 32bit userland works usually great except for iptables and ipsec.

-Andi