Browse Source

[Pal/Linux-SGX] Fail with ENOEXEC if loading non-ELF file

Previously, there was no check that the file is non-ELF before trying to read
the ELF header. This led to segmentation faults while loading non-ELF files
(e.g., bash scripts). This commit adds an explicit check, as well as the
corresponding PAL regression test.
jack.wxz 4 years ago
parent
commit
ad6b5210e5

+ 3 - 0
Pal/regression/nonelf_binary

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo "pal_load needs to recognize that this file is not an elf file"

+ 2 - 0
Pal/regression/nonelf_binary.manifest.template

@@ -0,0 +1,2 @@
+loader.exec = file:./nonelf_binary
+loader.debug_type = inline

+ 7 - 0
Pal/regression/test_pal.py

@@ -117,6 +117,13 @@ class TC_01_Bootstrap(RegressionTestCase):
         self.assertIn('Loaded Executable: file:Bootstrap', stderr)
         self.assertIn('argv[0] = Bootstrap', stderr)
 
+    @unittest.skipUnless(HAS_SGX, 'need SGX')
+    def test_107_manifest_with_nonelf_binary(self):
+        manifest = self.get_manifest('nonelf_binary')
+        #Expect return code is -ENOEXEC(248 as unsigned char)
+        with self.expect_returncode(248):
+            self.run_binary([manifest])
+
     def test_110_preload_libraries(self):
         stdout, stderr = self.run_binary(['Bootstrap3'])
         self.assertIn('Binary 1 Preloaded', stderr)

+ 6 - 0
Pal/src/host/Linux-SGX/sgx_main.c

@@ -111,10 +111,16 @@ int scan_enclave_binary (int fd, unsigned long * base, unsigned long * size,
     if (IS_ERR(ret))
         return -ERRNO(ret);
 
+    if ((size_t)ret < sizeof(ElfW(Ehdr)))
+        return -ENOEXEC;
+
     const ElfW(Ehdr) * header = (void *) filebuf;
     const ElfW(Phdr) * phdr = (void *) filebuf + header->e_phoff;
     const ElfW(Phdr) * ph;
 
+    if (memcmp(header->e_ident, ELFMAG, SELFMAG) != 0)
+        return -ENOEXEC;
+
     struct loadcmd {
         ElfW(Addr) mapstart, mapend;
     } loadcmds[16], *c;