Skip to content

Commit

Permalink
Make do_execve() take a const filename pointer
Browse files Browse the repository at this point in the history
Make do_execve() take a const filename pointer so that kernel_execve() compiles
correctly on ARM:

arch/arm/kernel/sys_arm.c:88: warning: passing argument 1 of 'do_execve' discards qualifiers from pointer target type

This also requires the argv and envp arguments to be consted twice, once for
the pointer array and once for the strings the array points to.  This is
because do_execve() passes a pointer to the filename (now const) to
copy_strings_kernel().  A simpler alternative would be to cast the filename
pointer in do_execve() when it's passed to copy_strings_kernel().

do_execve() may not change any of the strings it is passed as part of the argv
or envp lists as they are some of them in .rodata, so marking these strings as
const should be fine.

Further kernel_execve() and sys_execve() need to be changed to match.

This has been test built on x86_64, frv, arm and mips.

Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
dhowells authored and torvalds committed Aug 18, 2010
1 parent da5cabf commit d762746
Show file tree
Hide file tree
Showing 50 changed files with 179 additions and 98 deletions.
5 changes: 3 additions & 2 deletions arch/alpha/kernel/process.c
Expand Up @@ -387,8 +387,9 @@ EXPORT_SYMBOL(dump_elf_task_fp);
* sys_execve() executes a new program.
*/
asmlinkage int
do_sys_execve(const char __user *ufilename, char __user * __user *argv,
char __user * __user *envp, struct pt_regs *regs)
do_sys_execve(const char __user *ufilename,
const char __user *const __user *argv,
const char __user *const __user *envp, struct pt_regs *regs)
{
int error;
char *filename;
Expand Down
14 changes: 9 additions & 5 deletions arch/arm/kernel/sys_arm.c
Expand Up @@ -62,8 +62,9 @@ asmlinkage int sys_vfork(struct pt_regs *regs)
/* sys_execve() executes a new program.
* This is called indirectly via a small wrapper
*/
asmlinkage int sys_execve(const char __user *filenamei, char __user * __user *argv,
char __user * __user *envp, struct pt_regs *regs)
asmlinkage int sys_execve(const char __user *filenamei,
const char __user *const __user *argv,
const char __user *const __user *envp, struct pt_regs *regs)
{
int error;
char * filename;
Expand All @@ -78,14 +79,17 @@ asmlinkage int sys_execve(const char __user *filenamei, char __user * __user *ar
return error;
}

int kernel_execve(const char *filename, char *const argv[], char *const envp[])
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
struct pt_regs regs;
int ret;

memset(&regs, 0, sizeof(struct pt_regs));
ret = do_execve(filename, (char __user * __user *)argv,
(char __user * __user *)envp, &regs);
ret = do_execve(filename,
(const char __user *const __user *)argv,
(const char __user *const __user *)envp, &regs);
if (ret < 0)
goto out;

Expand Down
5 changes: 3 additions & 2 deletions arch/avr32/kernel/process.c
Expand Up @@ -384,8 +384,9 @@ asmlinkage int sys_vfork(struct pt_regs *regs)
}

asmlinkage int sys_execve(const char __user *ufilename,
char __user *__user *uargv,
char __user *__user *uenvp, struct pt_regs *regs)
const char __user *const __user *uargv,
const char __user *const __user *uenvp,
struct pt_regs *regs)
{
int error;
char *filename;
Expand Down
4 changes: 3 additions & 1 deletion arch/avr32/kernel/sys_avr32.c
Expand Up @@ -7,7 +7,9 @@
*/
#include <linux/unistd.h>

int kernel_execve(const char *file, char **argv, char **envp)
int kernel_execve(const char *file,
const char *const *argv,
const char *const *envp)
{
register long scno asm("r8") = __NR_execve;
register long sc1 asm("r12") = (long)file;
Expand Down
4 changes: 3 additions & 1 deletion arch/blackfin/kernel/process.c
Expand Up @@ -209,7 +209,9 @@ copy_thread(unsigned long clone_flags,
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char __user *name, char __user * __user *argv, char __user * __user *envp)
asmlinkage int sys_execve(const char __user *name,
const char __user *const __user *argv,
const char __user *const __user *envp)
{
int error;
char *filename;
Expand Down
4 changes: 3 additions & 1 deletion arch/cris/arch-v10/kernel/process.c
Expand Up @@ -204,7 +204,9 @@ asmlinkage int sys_vfork(long r10, long r11, long r12, long r13, long mof, long
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char *fname, char **argv, char **envp,
asmlinkage int sys_execve(const char *fname,
const char *const *argv,
const char *const *envp,
long r13, long mof, long srp,
struct pt_regs *regs)
{
Expand Down
6 changes: 4 additions & 2 deletions arch/cris/arch-v32/kernel/process.c
Expand Up @@ -218,8 +218,10 @@ sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp,

/* sys_execve() executes a new program. */
asmlinkage int
sys_execve(const char *fname, char **argv, char **envp, long r13, long mof, long srp,
struct pt_regs *regs)
sys_execve(const char *fname,
const char *const *argv,
const char *const *envp, long r13, long mof, long srp,
struct pt_regs *regs)
{
int error;
char *filename;
Expand Down
5 changes: 3 additions & 2 deletions arch/frv/kernel/process.c
Expand Up @@ -250,8 +250,9 @@ int copy_thread(unsigned long clone_flags,
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char __user *name, char __user * __user *argv,
char __user * __user *envp)
asmlinkage int sys_execve(const char __user *name,
const char __user *const __user *argv,
const char __user *const __user *envp)
{
int error;
char * filename;
Expand Down
5 changes: 4 additions & 1 deletion arch/h8300/kernel/process.c
Expand Up @@ -212,7 +212,10 @@ int copy_thread(unsigned long clone_flags,
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char *name, char **argv, char **envp,int dummy,...)
asmlinkage int sys_execve(const char *name,
const char *const *argv,
const char *const *envp,
int dummy, ...)
{
int error;
char * filename;
Expand Down
4 changes: 3 additions & 1 deletion arch/h8300/kernel/sys_h8300.c
Expand Up @@ -51,7 +51,9 @@ asmlinkage void syscall_print(void *dummy,...)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register long res __asm__("er0");
register char *const *_c __asm__("er3") = envp;
Expand Down
4 changes: 3 additions & 1 deletion arch/ia64/kernel/process.c
Expand Up @@ -633,7 +633,9 @@ dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
}

long
sys_execve (const char __user *filename, char __user * __user *argv, char __user * __user *envp,
sys_execve (const char __user *filename,
const char __user *const __user *argv,
const char __user *const __user *envp,
struct pt_regs *regs)
{
char *fname;
Expand Down
4 changes: 2 additions & 2 deletions arch/m32r/kernel/process.c
Expand Up @@ -289,8 +289,8 @@ asmlinkage int sys_vfork(unsigned long r0, unsigned long r1, unsigned long r2,
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char __user *ufilename,
char __user * __user *uargv,
char __user * __user *uenvp,
const char __user *const __user *uargv,
const char __user *const __user *uenvp,
unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, struct pt_regs regs)
{
Expand Down
4 changes: 3 additions & 1 deletion arch/m32r/kernel/sys_m32r.c
Expand Up @@ -93,7 +93,9 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register long __scno __asm__ ("r7") = __NR_execve;
register long __arg3 __asm__ ("r2") = (long)(envp);
Expand Down
4 changes: 3 additions & 1 deletion arch/m68k/kernel/process.c
Expand Up @@ -315,7 +315,9 @@ EXPORT_SYMBOL(dump_fpu);
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char __user *name, char __user * __user *argv, char __user * __user *envp)
asmlinkage int sys_execve(const char __user *name,
const char __user *const __user *argv,
const char __user *const __user *envp)
{
int error;
char * filename;
Expand Down
4 changes: 3 additions & 1 deletion arch/m68k/kernel/sys_m68k.c
Expand Up @@ -459,7 +459,9 @@ asmlinkage int sys_getpagesize(void)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register long __res asm ("%d0") = __NR_execve;
register long __a asm ("%d1") = (long)(filename);
Expand Down
4 changes: 3 additions & 1 deletion arch/m68knommu/kernel/process.c
Expand Up @@ -350,7 +350,9 @@ void dump(struct pt_regs *fp)
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char *name, char **argv, char **envp)
asmlinkage int sys_execve(const char *name,
const char *const *argv,
const char *const *envp)
{
int error;
char * filename;
Expand Down
4 changes: 3 additions & 1 deletion arch/m68knommu/kernel/sys_m68k.c
Expand Up @@ -44,7 +44,9 @@ asmlinkage int sys_getpagesize(void)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register long __res asm ("%d0") = __NR_execve;
register long __a asm ("%d1") = (long)(filename);
Expand Down
10 changes: 7 additions & 3 deletions arch/microblaze/kernel/sys_microblaze.c
Expand Up @@ -47,8 +47,10 @@ asmlinkage long microblaze_clone(int flags, unsigned long stack, struct pt_regs
return do_fork(flags, stack, regs, 0, NULL, NULL);
}

asmlinkage long microblaze_execve(const char __user *filenamei, char __user *__user *argv,
char __user *__user *envp, struct pt_regs *regs)
asmlinkage long microblaze_execve(const char __user *filenamei,
const char __user *const __user *argv,
const char __user *const __user *envp,
struct pt_regs *regs)
{
int error;
char *filename;
Expand Down Expand Up @@ -77,7 +79,9 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register const char *__a __asm__("r5") = filename;
register const void *__b __asm__("r6") = argv;
Expand Down
10 changes: 7 additions & 3 deletions arch/mips/kernel/syscall.c
Expand Up @@ -258,8 +258,10 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs)
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename, (char __user *__user *) (long)regs.regs[5],
(char __user *__user *) (long)regs.regs[6], &regs);
error = do_execve(filename,
(const char __user *const __user *) (long)regs.regs[5],
(const char __user *const __user *) (long)regs.regs[6],
&regs);
putname(filename);

out:
Expand Down Expand Up @@ -436,7 +438,9 @@ asmlinkage void bad_stack(void)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register unsigned long __a0 asm("$4") = (unsigned long) filename;
register unsigned long __a1 asm("$5") = (unsigned long) argv;
Expand Down
4 changes: 2 additions & 2 deletions arch/mn10300/kernel/process.c
Expand Up @@ -269,8 +269,8 @@ asmlinkage long sys_vfork(void)
}

asmlinkage long sys_execve(const char __user *name,
char __user * __user *argv,
char __user * __user *envp)
const char __user *const __user *argv,
const char __user *const __user *envp)
{
char *filename;
int error;
Expand Down
6 changes: 4 additions & 2 deletions arch/parisc/hpux/fs.c
Expand Up @@ -41,8 +41,10 @@ int hpux_execve(struct pt_regs *regs)
if (IS_ERR(filename))
goto out;

error = do_execve(filename, (char __user * __user *) regs->gr[25],
(char __user * __user *) regs->gr[24], regs);
error = do_execve(filename,
(const char __user *const __user *) regs->gr[25],
(const char __user *const __user *) regs->gr[24],
regs);

putname(filename);

Expand Down
15 changes: 10 additions & 5 deletions arch/parisc/kernel/process.c
Expand Up @@ -348,17 +348,22 @@ asmlinkage int sys_execve(struct pt_regs *regs)
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename, (char __user * __user *) regs->gr[25],
(char __user * __user *) regs->gr[24], regs);
error = do_execve(filename,
(const char __user *const __user *) regs->gr[25],
(const char __user *const __user *) regs->gr[24],
regs);
putname(filename);
out:

return error;
}

extern int __execve(const char *filename, char *const argv[],
char *const envp[], struct task_struct *task);
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
extern int __execve(const char *filename,
const char *const argv[],
const char *const envp[], struct task_struct *task);
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
return __execve(filename, argv, envp, current);
}
Expand Down
5 changes: 3 additions & 2 deletions arch/powerpc/kernel/process.c
Expand Up @@ -1034,8 +1034,9 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
flush_fp_to_thread(current);
flush_altivec_to_thread(current);
flush_spe_to_thread(current);
error = do_execve(filename, (char __user * __user *) a1,
(char __user * __user *) a2, regs);
error = do_execve(filename,
(const char __user *const __user *) a1,
(const char __user *const __user *) a2, regs);
putname(filename);
out:
return error;
Expand Down
5 changes: 3 additions & 2 deletions arch/s390/kernel/process.c
Expand Up @@ -267,8 +267,9 @@ asmlinkage void execve_tail(void)
/*
* sys_execve() executes a new program.
*/
SYSCALL_DEFINE3(execve, const char __user *, name, char __user * __user *, argv,
char __user * __user *, envp)
SYSCALL_DEFINE3(execve, const char __user *, name,
const char __user *const __user *, argv,
const char __user *const __user *, envp)
{
struct pt_regs *regs = task_pt_regs(current);
char *filename;
Expand Down
10 changes: 7 additions & 3 deletions arch/score/kernel/sys_score.c
Expand Up @@ -99,8 +99,10 @@ score_execve(struct pt_regs *regs)
if (IS_ERR(filename))
return error;

error = do_execve(filename, (char __user *__user*)regs->regs[5],
(char __user *__user *) regs->regs[6], regs);
error = do_execve(filename,
(const char __user *const __user *)regs->regs[5],
(const char __user *const __user *)regs->regs[6],
regs);

putname(filename);
return error;
Expand All @@ -110,7 +112,9 @@ score_execve(struct pt_regs *regs)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register unsigned long __r4 asm("r4") = (unsigned long) filename;
register unsigned long __r5 asm("r5") = (unsigned long) argv;
Expand Down
7 changes: 4 additions & 3 deletions arch/sh/kernel/process_32.c
Expand Up @@ -296,9 +296,10 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv,
char __user * __user *uenvp, unsigned long r7,
struct pt_regs __regs)
asmlinkage int sys_execve(const char __user *ufilename,
const char __user *const __user *uargv,
const char __user *const __user *uenvp,
unsigned long r7, struct pt_regs __regs)
{
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
int error;
Expand Down
4 changes: 2 additions & 2 deletions arch/sh/kernel/process_64.c
Expand Up @@ -497,8 +497,8 @@ asmlinkage int sys_execve(const char *ufilename, char **uargv,
goto out;

error = do_execve(filename,
(char __user * __user *)uargv,
(char __user * __user *)uenvp,
(const char __user *const __user *)uargv,
(const char __user *const __user *)uenvp,
pregs);
putname(filename);
out:
Expand Down
4 changes: 3 additions & 1 deletion arch/sh/kernel/sys_sh32.c
Expand Up @@ -71,7 +71,9 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register long __sc0 __asm__ ("r3") = __NR_execve;
register long __sc4 __asm__ ("r4") = (long) filename;
Expand Down

0 comments on commit d762746

Please sign in to comment.