Add check for is_valid_elf() before loading in exec
authorKevin Klues <klueska@cs.berkeley.edu>
Mon, 7 Apr 2014 19:22:46 +0000 (12:22 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Mon, 7 Apr 2014 21:35:12 +0000 (14:35 -0700)
If the program is not a valid elf file, then set errno to ENOEXEC.
Busybox and other shells recognize this and try to re-exec the program
through the shell itself (i.e. bash ifconfig instead of just
./ifconfig).

To support this, sh and bash symlinks have been set up to point to ash
in busybox

kern/include/elf.h
kern/src/elf.c
kern/src/syscall.c
tools/patches/busybox-1.17.3-config

index ad01c64..d331d91 100644 (file)
@@ -148,6 +148,7 @@ typedef long elf_aux_t[2];
 #define ELF_HWCAP_SPARC_FLUSH  1
 
 struct file;
+bool is_valid_elf(struct file *f);
 int load_elf(struct proc* p, struct file* f);
 
 #endif /* !ROS_INC_ELF_H */
index 9162fc8..663f56b 100644 (file)
 # define elf_field(obj, field) ((obj##32)->field)
 #endif
 
+/* Check if the file is valid elf file (i.e. by checking for ELF_MAGIC in the
+ * header) */
+bool is_valid_elf(struct file *f)
+{
+       elf64_t h;
+       off64_t o = 0;
+       struct proc *c = switch_to(0);
+
+       if (f->f_op->read(f, (char*)&h, sizeof(elf64_t), &o) != sizeof(elf64_t)) {
+               goto fail;
+       }
+       if (h.e_magic != ELF_MAGIC) {
+               goto fail;
+       }
+success:
+       switch_back(0, c);
+       return TRUE;
+fail:
+       switch_back(0, c);
+       return FALSE;
+}
+
 /* We need the writable flag for ld.  Even though the elf header says it wants
  * RX (and not W) for its main program header, it will page fault (eip 56f0,
  * 46f0 after being relocated to 0x1000, va 0x20f4). */
index 7454f38..e626a9b 100644 (file)
@@ -579,6 +579,10 @@ static int sys_exec(struct proc *p, char *path, size_t path_l,
        user_memdup_free(p, t_path);
        if (!program)
                goto early_error;
+       if (!is_valid_elf(program)) {
+               set_errno(ENOEXEC);
+               goto early_error;
+       }
        /* Set the argument stuff needed by glibc */
        if (memcpy_from_user_errno(p, p->procinfo->argp, pi->argp,
                                   sizeof(pi->argp)))
index 5cc8d73..064bf16 100644 (file)
@@ -919,12 +919,12 @@ CONFIG_ASH_EXPAND_PRMT=y
 # CONFIG_HUSH_LOCAL is not set
 # CONFIG_HUSH_EXPORT_N is not set
 # CONFIG_HUSH_RANDOM_SUPPORT is not set
-# CONFIG_FEATURE_SH_IS_ASH is not set
+CONFIG_FEATURE_SH_IS_ASH=y
 # CONFIG_FEATURE_SH_IS_HUSH is not set
-CONFIG_FEATURE_SH_IS_NONE=y
-# CONFIG_FEATURE_BASH_IS_ASH is not set
+# CONFIG_FEATURE_SH_IS_NONE is not set
+CONFIG_FEATURE_BASH_IS_ASH=y
 # CONFIG_FEATURE_BASH_IS_HUSH is not set
-CONFIG_FEATURE_BASH_IS_NONE=y
+# CONFIG_FEATURE_BASH_IS_NONE is not set
 # CONFIG_LASH is not set
 # CONFIG_MSH is not set
 CONFIG_SH_MATH_SUPPORT=y