From f6d0cd4e8e9c386ed48e1bbb30af88f801b8ae3a Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Fri, 11 May 2018 17:43:27 +0200 Subject: [PATCH] Partially implement chroot(2) (#891) * Partially implement chroot(2) Really this return EPERM (permission denied), which seems to be absolutely fine since a non-privileged user is currently assumed. This is what would normally be returned in this scenario. * update chroot implementation --- manticore/platforms/linux.py | 19 +++++++++++++++++++ tests/test_linux.py | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/manticore/platforms/linux.py b/manticore/platforms/linux.py index a74fa21..4546533 100644 --- a/manticore/platforms/linux.py +++ b/manticore/platforms/linux.py @@ -1557,6 +1557,25 @@ class Linux(Platform): return newfd + def sys_chroot(self, path): + ''' + An implementation of chroot that does perform some basic error checking, + but does not actually chroot. + + :param path: Path to chroot + ''' + if path not in self.current.memory: + return -errno.EFAULT + + path_s = self.current.read_string(path) + if not os.path.exists(path_s): + return -errno.ENOENT + + if not os.path.isdir(path_s): + return -errno.ENOTDIR + + return -errno.EPERM + def sys_close(self, fd): ''' Closes a file descriptor diff --git a/tests/test_linux.py b/tests/test_linux.py index 374d30d..9522d8d 100644 --- a/tests/test_linux.py +++ b/tests/test_linux.py @@ -1,4 +1,5 @@ import os +import errno import shutil import tempfile import unittest @@ -184,3 +185,21 @@ class LinuxTest(unittest.TestCase): self.assertLess(_min, len(platform.files)) self.assertGreater(_max, len(platform.files)-1) + + def test_chroot(self): + # Create a minimal state + platform = self.symbolic_linux + platform.current.memory.mmap(0x1000, 0x1000, 'rw ') + platform.current.SP = 0x2000-4 + + # should error with ENOENT + this_file = os.path.realpath(__file__) + path = platform.current.push_bytes('{}\x00'.format(this_file)) + fd = platform.sys_chroot(path) + self.assertEqual(fd, -errno.ENOTDIR) + + # valid dir, but should always fail with EPERM + this_dir = os.path.dirname(this_file) + path = platform.current.push_bytes('{}\x00'.format(this_dir)) + fd = platform.sys_chroot(path) + self.assertEqual(fd, -errno.EPERM)