Skip to content

Commit dd54d13

Browse files
bugaevcawesomekling
authored andcommitted
Kernel+LibC: Allow passing mount flags to chroot()
Since a chroot is in many ways similar to a separate root mount, we can also apply mount flags to it as if it was an actual mount. These flags will apply whenever the chrooted process accesses its root directory, but not when other processes access this same directory for the outside. Since it's common to chdir("/") immediately after chrooting (so that files accessed through the current directory inherit the same mount flags), this effectively allows one to apply additional limitations to a process confined inside a chroot. To this effect, sys$chroot() gains a mount_flags argument (exposed as chroot_with_mount_flags() in userspace) which can be set to all the same values as the flags argument for sys$mount(), and additionally to -1 to keep the flags set for that file system. Note that passing 0 as mount_flags will unset any flags that may have been set for the file system, not keep them.
1 parent fee6d0a commit dd54d13

File tree

4 files changed

+11
-4
lines changed

4 files changed

+11
-4
lines changed

Kernel/Process.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4337,8 +4337,9 @@ int Process::sys$chroot(const char* user_path, size_t path_length)
43374337
if (directory_or_error.is_error())
43384338
return directory_or_error.error();
43394339
auto directory = directory_or_error.value();
4340-
m_root_directory_for_procfs = directory;
4341-
set_root_directory(Custody::create(nullptr, "", directory->inode(), directory->mount_flags()));
4340+
m_root_directory_relative_to_global_root = directory;
4341+
int chroot_mount_flags = mount_flags == -1 ? directory->mount_flags() : mount_flags;
4342+
set_root_directory(Custody::create(nullptr, "", directory->inode(), chroot_mount_flags));
43424343
return 0;
43434344
}
43444345

Kernel/Process.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ class Process : public InlineLinkedListNode<Process>
254254
int sys$futex(const Syscall::SC_futex_params*);
255255
int sys$set_thread_boost(int tid, int amount);
256256
int sys$set_process_boost(pid_t, int amount);
257-
int sys$chroot(const char* path, size_t path_length);
257+
int sys$chroot(const char* path, size_t path_length, int mount_flags);
258258
int sys$pledge(const Syscall::SC_pledge_params*);
259259

260260
static void initialize();

Libraries/LibC/unistd.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,12 +644,17 @@ int get_process_name(char* buffer, int buffer_size)
644644
}
645645

646646
int chroot(const char* path)
647+
{
648+
return chroot_with_mount_flags(path, -1);
649+
}
650+
651+
int chroot_with_mount_flags(const char* path, int mount_flags)
647652
{
648653
if (!path) {
649654
errno = EFAULT;
650655
return -1;
651656
}
652-
int rc = syscall(SC_chroot, path, strlen(path));
657+
int rc = syscall(SC_chroot, path, strlen(path), mount_flags);
653658
__RETURN_WITH_ERRNO(rc, rc, -1);
654659
}
655660

Libraries/LibC/unistd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ int execvp(const char* filename, char* const argv[]);
5252
int execl(const char* filename, const char* arg, ...);
5353
int execlp(const char* filename, const char* arg, ...);
5454
int chroot(const char* path);
55+
int chroot_with_mount_flags(const char* path, int mount_flags);
5556
void sync();
5657
void _exit(int status);
5758
pid_t getsid(pid_t);

0 commit comments

Comments
 (0)