summaryrefslogtreecommitdiff
path: root/fs/binfmt_script.c
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill@shutemov.name>2008-10-15 22:02:39 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2008-12-13 15:29:33 -0800
commit0993210979a0ce0b25a1949fdbeeb07782747978 (patch)
tree60d448e00f9fa0462c3fe466c5dda1b3f491311f /fs/binfmt_script.c
parentf8220954306c6fdc127a5ec645e825991fc97812 (diff)
Allow recursion in binfmt_script and binfmt_misc
commit bf2a9a39639b8b51377905397a5005f444e9a892 upstream. binfmt_script and binfmt_misc disallow recursion to avoid stack overflow using sh_bang and misc_bang. It causes problem in some cases: $ echo '#!/bin/ls' > /tmp/t0 $ echo '#!/tmp/t0' > /tmp/t1 $ echo '#!/tmp/t1' > /tmp/t2 $ chmod +x /tmp/t* $ /tmp/t2 zsh: exec format error: /tmp/t2 Similar problem with binfmt_misc. This patch introduces field 'recursion_depth' into struct linux_binprm to track recursion level in binfmt_misc and binfmt_script. If recursion level more then BINPRM_MAX_RECURSION it generates -ENOEXEC. [akpm@linux-foundation.org: make linux_binprm.recursion_depth a uint] Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> Cc: Pavel Emelyanov <xemul@openvz.org> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/binfmt_script.c')
-rw-r--r--fs/binfmt_script.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 9e3963f7ebf1..08343505e184 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -22,14 +22,15 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
char interp[BINPRM_BUF_SIZE];
int retval;
- if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang))
+ if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') ||
+ (bprm->recursion_depth > BINPRM_MAX_RECURSION))
return -ENOEXEC;
/*
* This section does the #! interpretation.
* Sorta complicated, but hopefully it will work. -TYT
*/
- bprm->sh_bang = 1;
+ bprm->recursion_depth++;
allow_write_access(bprm->file);
fput(bprm->file);
bprm->file = NULL;