Created
December 8, 2011 10:27
-
-
Save hiromu/1446657 to your computer and use it in GitHub Desktop.
sys_brainfuck(): syscall of brainfuck interpreter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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