A few Linux syscalls have variadic arguments. These include open(2) that accepts either two or three arguments and reboot(2) that takes either three or four. Make the debug argument-count verification code accept variadic syscalls with a dedicated count check as special cases. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> --- Jan-Benedict, I gather you have not yet applied the original open(2) patch this one builds upon: Message-ID: <alpine.LFD.1.10.0905172337160.14684@ftp.linux-mips.org> Date: Mon, 18 May 2009 00:57:01 +0100 (BST) From: Maciej W. Rozycki <macro@linux-mips.org> To: Jan-Benedict Glaw <jbglaw@lug-owl.de> Cc: linux-vax@pergamentum.com Subject: [PATCH] Permit 2- and 3-argument calls to open(2) Please replace it with the following one. Note that glibc (up to current GIT HEAD) is particularly keen on calling reboot(2) with three arguments only. I found this one with init(8). There might be more such syscalls still undiscovered. Please apply. Maciej patch-mips-2.6.25-20080422-vax-scall-varargs-0 Index: linux-mips-2.6.18-20060920-cougar/arch/vax/kernel/syscall.c =================================================================== --- linux-mips-2.6.18-20060920-cougar.orig/arch/vax/kernel/syscall.c +++ linux-mips-2.6.18-20060920-cougar/arch/vax/kernel/syscall.c @@ -58,7 +58,7 @@ extern asmlinkage long sys_rt_sigaction( static struct { unsigned long *sc_func; - unsigned int nr_args; + int nr_args; } syscall[] = { #define SC(num, func, args) \ [num] = { \ @@ -69,7 +69,7 @@ static struct { SC (__NR_fork, sys_fork, 0), SC (__NR_read, sys_read, 3), SC (__NR_write, sys_write, 3), - SC (__NR_open, sys_open, 3), + SC (__NR_open, sys_open, -1), SC (__NR_close, sys_close, 1), SC (__NR_waitpid, sys_waitpid, 3), SC (__NR_creat, sys_creat, 2), @@ -140,7 +140,7 @@ static struct { SC (__NR_readlink, sys_readlink, 3), SC (__NR_uselib, sys_uselib, 1), SC (__NR_swapon, sys_swapon, 2), - SC (__NR_reboot, sys_reboot, 4), + SC (__NR_reboot, sys_reboot, -1), SC (__NR_mmap, sys_mmap, 6), SC (__NR_munmap, sys_munmap, 2), SC (__NR_truncate, sys_truncate, 2), @@ -287,7 +287,8 @@ void syscall_handler(struct pt_regs *reg { unsigned int sc_number; unsigned int *user_ap; - unsigned int nr_args; + int sc_args; + int nr_args; sc_number = *(unsigned int *)(excep_info); @@ -347,17 +348,33 @@ void syscall_handler(struct pt_regs *reg /* * Check number of syscall arguments */ - if (unlikely (syscall[sc_number].nr_args != nr_args)) { - printk (KERN_DEBUG "%s(%d): stack mismatch (should=%d, caller=%d) on syscall %d\n", + sc_args = syscall[sc_number].nr_args; + if (unlikely(sc_args != nr_args)) + switch (sc_args) { + case -1: + /* Variadic syscalls: */ + + /* open(2) takes two or three args. */ + if (sc_number == __NR_open && !((nr_args - 2) & ~1)) + break; + + /* reboot(2) takes three or four args. */ + if (sc_number == __NR_reboot && !((nr_args - 3) & ~1)) + break; + + /* Fall through. */ + default: + printk(KERN_DEBUG "%s(%d): stack mismatch " + "(should=%d, caller=%d) on syscall %d\n", current->comm, current->pid, - syscall[sc_number].nr_args, nr_args, sc_number); - printk (KERN_DEBUG "Please report to " + sc_args, nr_args, sc_number); + printk(KERN_DEBUG "Please report to " "<linux-vax@pergamentum.com>.\n"); #ifdef CONFIG_DEBUG_VAX_CHECK_CHMx_ARGS_ABORT - regs->r0 = -EFAULT; - return; + regs->r0 = -EFAULT; + return; #endif /* CONFIG_DEBUG_VAX_CHECK_CHMx_ARGS_ABORT */ - } + } #endif /* CONFIG_DEBUG_VAX_CHECK_CHMx_ARGS */ /* _______________________________________________ Linux-Vax mailing list Linux-Vax@mail.pergamentum.com http://mail.pergamentum.com/mailman/listinfo/linux-vax