Skip to content

Commit

Permalink
add CSAW unfork
Browse files Browse the repository at this point in the history
  • Loading branch information
BrieflyX committed Dec 4, 2019
1 parent bb81eee commit 61ab0c4
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Some of my ctf pwn challenge collections.

## Index

- [Unfork - CSAW CTF 2019 Finals](./kernel/unfork)
- [ASIS CTF Finals 2018 - Modern KeX](./kernel/KeX)
- [Gnote - TWCTF 2019](./kernel/gnote)
- [\*CTF Finals 2019 - Hack Me](./kernel/hackme)
Expand Down
7 changes: 7 additions & 0 deletions kernel/unfork/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Unfork - CSAW CTF 2019 Finals

A new syscall `unfork` handling file descriptors between parent and child.

## Source code

https://github.com/osirislab/CSAW-CTF-2019-Finals/tree/master/pwn/unfork
Binary file added kernel/unfork/bzImage
Binary file not shown.
Binary file added kernel/unfork/disk.img
Binary file not shown.
11 changes: 11 additions & 0 deletions kernel/unfork/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh

DIR="$(dirname "$(readlink -f "$0")")"

qemu-system-x86_64 -monitor /dev/null \
-cpu max,+smap,+smep,check \
-m 256 \
-kernel "${DIR}/bzImage" \
-drive file="${DIR}/disk.img",format=raw -snapshot \
-append "console=ttyS0 root=/dev/sda panic=-1" \
-nographic -no-reboot
74 changes: 74 additions & 0 deletions kernel/unfork/unfork.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index c29976eca4a8..9b0517e6fffc 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -357,6 +357,7 @@
433 common fspick __x64_sys_fspick
434 common pidfd_open __x64_sys_pidfd_open
435 common clone3 __x64_sys_clone3/ptregs
+436 common unfork __x64_sys_unfork

#
# x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/fs/file.c b/fs/file.c
index 3da91a112bab..3022b3fe4f7a 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -1015,3 +1015,40 @@ int iterate_fd(struct files_struct *files, unsigned n,
return res;
}
EXPORT_SYMBOL(iterate_fd);
+
+int unfork_files(void)
+{
+ int fd, err = 0;
+ struct files_struct *files = get_files_struct(current);
+ struct files_struct *parent_files = get_files_struct(current->parent);
+ struct fdtable *fdt = files_fdtable(files);
+
+ spin_lock(&files->file_lock);
+ for (fd = 0; fd < fdt->max_fds; fd++) {
+ struct file *f;
+ int new_fd;
+
+ f = rcu_dereference(fdt->fd[fd]);
+ if (!f)
+ continue;
+
+ unsigned long parent_nofile = READ_ONCE(current->parent->signal->rlim[RLIMIT_NOFILE].rlim_cur);
+ err = __alloc_fd(parent_files, 0, parent_nofile, 0);
+ if (err < 0) {
+ fput(f);
+ break;
+ }
+
+ new_fd = err;
+ __fd_install(parent_files, new_fd, f);
+
+ rcu_assign_pointer(fdt->fd[fd], NULL);
+ __put_unused_fd(files, fd);
+ }
+ spin_unlock(&files->file_lock);
+
+ put_files_struct(files);
+ put_files_struct(parent_files);
+
+ return err;
+}
diff --git a/kernel/exit.c b/kernel/exit.c
index 5b4a5dcce8f8..dd429ad4464e 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1769,3 +1769,12 @@ __weak void abort(void)
panic("Oops failed to kill thread");
}
EXPORT_SYMBOL(abort);
+
+extern int unfork_files(void);
+
+SYSCALL_DEFINE0(unfork)
+{
+ int err = 0;
+ err = unfork_files();
+ return err;
+}

0 comments on commit 61ab0c4

Please sign in to comment.