Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiromu/1446657 to your computer and use it in GitHub Desktop.
Save hiromu/1446657 to your computer and use it in GitHub Desktop.
sys_brainfuck(): syscall of brainfuck interpreter
From 0696a912ecf5ba37bfb5670a79ec3840271c9591 Mon Sep 17 00:00:00 2001
From: Hiromu Yakura <hiromu1996@gmail.com>
Date: Thu, 8 Dec 2011 14:16:56 +0900
Subject: [PATCH] Added syscall of brainfuck interpreter as sys_brainfuck
---
arch/arm/include/asm/unistd.h | 1 +
arch/arm/kernel/calls.S | 1 +
arch/x86/include/asm/unistd_32.h | 5 +-
arch/x86/include/asm/unistd_64.h | 2 +
arch/x86/kernel/syscall_table_32.S | 1 +
include/asm-generic/unistd.h | 7 ++-
include/linux/syscalls.h | 4 ++
kernel/Makefile | 2 +-
kernel/brainfuck.c | 77 ++++++++++++++++++++++++++++++++++++
9 files changed, 95 insertions(+), 5 deletions(-)
create mode 100644 kernel/brainfuck.c
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 4a11237..9c32749 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -404,6 +404,7 @@
#define __NR_setns (__NR_SYSCALL_BASE+375)
#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
+#define __NR_brainfuck (__NR_SYSCALL_BASE+378)
/*
* The following SWIs are ARM private.
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 463ff4a..8ba0d3e 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -387,6 +387,7 @@
/* 375 */ CALL(sys_setns)
CALL(sys_process_vm_readv)
CALL(sys_process_vm_writev)
+ CALL(sys_brainfuck)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
index 599c77d..8f1b6e2 100644
--- a/arch/x86/include/asm/unistd_32.h
+++ b/arch/x86/include/asm/unistd_32.h
@@ -353,11 +353,12 @@
#define __NR_sendmmsg 345
#define __NR_setns 346
#define __NR_process_vm_readv 347
-#define __NR_process_vm_writev 348
+#define __NR_process_vm_writev 348
+#define __NR_brainfuck 349
#ifdef __KERNEL__
-#define NR_syscalls 349
+#define NR_syscalls 350
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
index 0431f19..35cd90c 100644
--- a/arch/x86/include/asm/unistd_64.h
+++ b/arch/x86/include/asm/unistd_64.h
@@ -686,6 +686,8 @@ __SYSCALL(__NR_getcpu, sys_getcpu)
__SYSCALL(__NR_process_vm_readv, sys_process_vm_readv)
#define __NR_process_vm_writev 311
__SYSCALL(__NR_process_vm_writev, sys_process_vm_writev)
+#define __NR_brainfuck 312
+__SYSCALL(__NR_brainfuc, sys_brainfuck)
#ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index 9a0e312..48084fb 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -348,3 +348,4 @@ ENTRY(sys_call_table)
.long sys_setns
.long sys_process_vm_readv
.long sys_process_vm_writev
+ .long sys_brainfuck
diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h
index f4c38d8c..2d4f748 100644
--- a/include/asm-generic/unistd.h
+++ b/include/asm-generic/unistd.h
@@ -657,12 +657,14 @@ __SYSCALL(__NR_perf_event_open, sys_perf_event_open)
__SYSCALL(__NR_accept4, sys_accept4)
#define __NR_recvmmsg 243
__SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
+#define __NR_brainfuck 244
+__SYSCALL(__NR_brainfuck, sys_brainfuck)
/*
* Architectures may provide up to 16 syscalls of their own
* starting with this value.
*/
-#define __NR_arch_specific_syscall 244
+#define __NR_arch_specific_syscall 245
#define __NR_wait4 260
__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
@@ -685,9 +687,10 @@ __SYSCALL(__NR_syncfs, sys_syncfs)
__SYSCALL(__NR_setns, sys_setns)
#define __NR_sendmmsg 269
__SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg)
+#define __NR_brainfuck 270
#undef __NR_syscalls
-#define __NR_syscalls 270
+#define __NR_syscalls 271
/*
* All syscalls below here should go away really,
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 86a24b1..4e35c4a 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -856,5 +856,9 @@ asmlinkage long sys_process_vm_writev(pid_t pid,
const struct iovec __user *rvec,
unsigned long riovcnt,
unsigned long flags);
+asmlinkage long sys_brainfuck(char *source_user, char *input_user,
+ char *output_user, unsigned int source_len,
+ unsigned int input_len, unsigned int output_len);
+
#endif
diff --git a/kernel/Makefile b/kernel/Makefile
index e898c5b..4a767bb 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -10,7 +10,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
notifier.o ksysfs.o sched_clock.o cred.o \
- async.o range.o
+ async.o range.o brainfuck.o
obj-y += groups.o
ifdef CONFIG_FUNCTION_TRACER
diff --git a/kernel/brainfuck.c b/kernel/brainfuck.c
new file mode 100644
index 0000000..f0eb8f0
--- /dev/null
+++ b/kernel/brainfuck.c
@@ -0,0 +1,77 @@
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <asm/uaccess.h>
+
+#define MEMORY_UNIT unsigned char
+#define BF_MEMORY_SIZE 30000
+
+SYSCALL_DEFINE6(brainfuck, char *, source_user, char *, input_user,
+ char *, output_user, unsigned int, source_len,
+ unsigned int input_len, unsigned int, output_len)
+{
+ int ptr = 0, len = 0, len2 = 0, i, count;
+ MEMORY_UNIT *mem;
+ char *source, *input, *output;
+
+ mem = (MEMORY_UNIT *)kmalloc(sizeof(MEMORY_UNIT) * BF_MEMORY_SIZE, GFP_KERNEL);
+ source = (char *)kmalloc(sizeof(char) * source_len, GFP_KERNEL);
+ input = (char *)kmalloc(sizeof(char) * input_len, GFP_KERNEL);
+ output = (char *)kmalloc(sizeof(char) * output_len, GFP_KERNEL);
+
+ memset(mem, 0, sizeof(mem));
+ copy_from_user(source, source_user, sizeof(char) * source_len);
+ copy_from_user(input, input_user, sizeof(char) * input_len);
+
+ for(i = 0; i < source_len; i++) {
+ if(source[i] == '>') {
+ ptr++;
+ } else if(source[i] == '<') {
+ ptr--;
+ } else if(source[i] == '+') {
+ mem[ptr]++;
+ } else if(source[i] == '-') {
+ mem[ptr]--;
+ } else if(source[i] == '.') {
+ output[len] = mem[ptr];
+ len++;
+ } else if(source[i] == ',') {
+ mem[ptr] = input[len2];
+ len2++;
+ } else if(source[i] == '[') {
+ if(!mem[ptr]) {
+ count = 1;
+ while(1) {
+ i++;
+ if(source[i] == '[') {
+ count++;
+ } else if(source[i] == ']') {
+ count--;
+ if(!count)
+ break;
+ }
+ }
+ }
+ } else if(source[i] == ']') {
+ count = 1;
+ while(1) {
+ i--;
+ if(source[i] == ']') {
+ count++;
+ } else if(source[i] == '[') {
+ count--;
+ if(!count)
+ break;
+ }
+ }
+ i--;
+ }
+ }
+
+ output[len] = '\0';
+ copy_to_user(output_user, output, sizeof(char) * (len + 1));
+ return 0;
+}
+
--
1.7.5.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment