do_coredump: fix the "ispipe" error check
[pandora-kernel.git] / fs / exec.c
index d9576f2..f8fad7f 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1114,6 +1114,13 @@ out:
 }
 EXPORT_SYMBOL(flush_old_exec);
 
+void would_dump(struct linux_binprm *bprm, struct file *file)
+{
+       if (inode_permission(file->f_path.dentry->d_inode, MAY_READ) < 0)
+               bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
+}
+EXPORT_SYMBOL(would_dump);
+
 void setup_new_exec(struct linux_binprm * bprm)
 {
        int i, ch;
@@ -1153,9 +1160,10 @@ void setup_new_exec(struct linux_binprm * bprm)
        if (bprm->cred->uid != current_euid() ||
            bprm->cred->gid != current_egid()) {
                current->pdeath_signal = 0;
-       } else if (file_permission(bprm->file, MAY_READ) ||
-                  bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP) {
-               set_dumpable(current->mm, suid_dumpable);
+       } else {
+               would_dump(bprm, bprm->file);
+               if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)
+                       set_dumpable(current->mm, suid_dumpable);
        }
 
        /*
@@ -1641,15 +1649,26 @@ expand_fail:
        return ret;
 }
 
+static void cn_escape(char *str)
+{
+       for (; *str; str++)
+               if (*str == '/')
+                       *str = '!';
+}
+
 static int cn_print_exe_file(struct core_name *cn)
 {
        struct file *exe_file;
-       char *pathbuf, *path, *p;
+       char *pathbuf, *path;
        int ret;
 
        exe_file = get_mm_exe_file(current->mm);
-       if (!exe_file)
-               return cn_printf(cn, "(unknown)");
+       if (!exe_file) {
+               char *commstart = cn->corename + cn->used;
+               ret = cn_printf(cn, "%s (path unknown)", current->comm);
+               cn_escape(commstart);
+               return ret;
+       }
 
        pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
        if (!pathbuf) {
@@ -1663,9 +1682,7 @@ static int cn_print_exe_file(struct core_name *cn)
                goto free_buf;
        }
 
-       for (p = path; *p; p++)
-               if (*p == '/')
-                       *p = '!';
+       cn_escape(path);
 
        ret = cn_printf(cn, "%s", path);
 
@@ -1737,16 +1754,22 @@ static int format_corename(struct core_name *cn, long signr)
                                break;
                        }
                        /* hostname */
-                       case 'h':
+                       case 'h': {
+                               char *namestart = cn->corename + cn->used;
                                down_read(&uts_sem);
                                err = cn_printf(cn, "%s",
                                              utsname()->nodename);
                                up_read(&uts_sem);
+                               cn_escape(namestart);
                                break;
+                       }
                        /* executable */
-                       case 'e':
+                       case 'e': {
+                               char *commstart = cn->corename + cn->used;
                                err = cn_printf(cn, "%s", current->comm);
+                               cn_escape(commstart);
                                break;
+                       }
                        case 'E':
                                err = cn_print_exe_file(cn);
                                break;
@@ -2110,16 +2133,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
 
        ispipe = format_corename(&cn, signr);
 
-       if (ispipe == -ENOMEM) {
-               printk(KERN_WARNING "format_corename failed\n");
-               printk(KERN_WARNING "Aborting core\n");
-               goto fail_corename;
-       }
-
        if (ispipe) {
                int dump_count;
                char **helper_argv;
 
+               if (ispipe < 0) {
+                       printk(KERN_WARNING "format_corename failed\n");
+                       printk(KERN_WARNING "Aborting core\n");
+                       goto fail_corename;
+               }
+
                if (cprm.limit == 1) {
                        /*
                         * Normally core limits are irrelevant to pipes, since