diff --git a/arch/arm/parasite-head.S b/arch/arm/parasite-head.S index c7e341f..7357f94 100644 --- a/arch/arm/parasite-head.S +++ b/arch/arm/parasite-head.S @@ -25,21 +25,14 @@ __parasite_head_start: adr sp, __parasite_stack - adr r0, __parasite_cmd - ldr r0, [r0] - adr r1, __parasite_args + adr r0, __parasite_args bl service udf #16 @ SIGTRAP .align 4, 0x00 -__parasite_cmd: - .long 0 - __parasite_args: - .long 0 .space PARASITE_ARG_SIZE, 0 - .space PARASITE_STACK_SIZE, 0 - .space 224, 0 /* 8+4 fill */ + .space 56, 0 /* 8+4 fill */ __parasite_stack: - .long 0 + .space PARASITE_STACK_SIZE, 0 diff --git a/arch/arm64/parasite-head.S b/arch/arm64/parasite-head.S index 0cead12..e831871 100644 --- a/arch/arm64/parasite-head.S +++ b/arch/arm64/parasite-head.S @@ -24,23 +24,15 @@ .align 4, 0x00 __parasite_head_start: - adr x1, __parasite_stack - mov sp, x1 - adr x0, __parasite_cmd - ldr x0, [x0] - adr x1, __parasite_args + adr x0, __parasite_stack + mov sp, x0 + adr x0, __parasite_args bl service brk #0 /* SIGTRAP */ .align 4, 0x00 -__parasite_cmd: - .quad 0 - __parasite_args: - .quad 0 .space PARASITE_ARG_SIZE, 0 - .space PARASITE_STACK_SIZE, 0 - .space 224, 0 /* 8+4 fill */ __parasite_stack: - .quad 0 + .space PARASITE_STACK_SIZE, 0 diff --git a/arch/x86_64/parasite-head.S b/arch/x86_64/parasite-head.S index 239a2c0..347051c 100644 --- a/arch/x86_64/parasite-head.S +++ b/arch/x86_64/parasite-head.S @@ -25,23 +25,13 @@ __parasite_head_start: leaq __parasite_stack(%rip), %rsp - subq $16, %rsp - andq $~15, %rsp - pushq $0 - movq %rsp, %rbp - movl __parasite_cmd(%rip), %edi - leaq __parasite_args(%rip), %rsi + leaq __parasite_args(%rip), %rdi call service int $0x03 /* SIGTRAP */ .align 8, 0x90 -__parasite_cmd: - .long 0 - __parasite_args: - .long 0 .space PARASITE_ARG_SIZE, 0 - .space PARASITE_STACK_SIZE, 0 __parasite_stack: - .long 0 + .space PARASITE_STACK_SIZE, 0 diff --git a/memcr.c b/memcr.c index 7251321..b93bbc4 100644 --- a/memcr.c +++ b/memcr.c @@ -309,32 +309,32 @@ static int parasite_status_ok(void) return ret; } -static void create_filesystem_socketname(char * addr, int addr_size, pid_t pid) +static void parasite_socket_init(struct sockaddr_un *addr, pid_t pid) { - snprintf(addr, addr_size, "%s/memcr%u", parasite_socket_dir, pid); -} - -static void create_abstract_socketname(char * addr, int addr_size, pid_t pid) -{ - snprintf(addr, addr_size, "#memcr%u", pid); -} + memset(addr, 0x00, sizeof(struct sockaddr_un)); -static void cleanup_socket(int pid) -{ - char socketaddr[108]; + addr->sun_family = AF_UNIX; - create_filesystem_socketname(socketaddr, sizeof(socketaddr), pid); - unlink(socketaddr); + if (parasite_socket_dir) + snprintf(addr->sun_path, sizeof(addr->sun_path), "%s/memcr%u", parasite_socket_dir, pid); + else { + snprintf(addr->sun_path, sizeof(addr->sun_path), "#memcr%u", pid); + addr->sun_path[0] = '\0'; + } } static void cleanup_pid(pid_t pid) { char path[PATH_MAX]; + snprintf(path, sizeof(path), "%s/pages-%d.img", dump_dir, pid); unlink(path); - if (parasite_socket_dir) - cleanup_socket(pid); + if (!parasite_socket_dir) + return; + + snprintf(path, sizeof(path), "%s/memcr%u", parasite_socket_dir, pid); + unlink(path); } static void cleanup_checkpointed_pids(void) @@ -552,7 +552,7 @@ static int unseize_target(void) static int parasite_connect(pid_t pid) { int cd; - struct sockaddr_un addr = { 0 }; + struct sockaddr_un addr; int ret; int cnt = 0; @@ -562,14 +562,7 @@ static int parasite_connect(pid_t pid) return -1; } - addr.sun_family = PF_UNIX; - - if (parasite_socket_dir) { - create_filesystem_socketname(addr.sun_path, sizeof(addr.sun_path), pid); - } else { - create_abstract_socketname(addr.sun_path, sizeof(addr.sun_path), pid); - addr.sun_path[0] = '\0'; - } + parasite_socket_init(&addr, pid); /* parasite needs some time to start listening on a socket */ retry: @@ -854,10 +847,10 @@ static int setup_listen_socket(struct sockaddr *addr, socklen_t addrlen) static int setup_listen_unix_socket(const char *client_socket_path) { - struct sockaddr_un addr; + struct sockaddr_un addr = { + .sun_family = AF_UNIX, + }; - addr.sun_family = PF_UNIX; - memset(addr.sun_path, 0, sizeof(addr.sun_path)); snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", client_socket_path); fprintf(stdout, "[x] Trying to configure UNIX %s socket.\n", addr.sun_path); @@ -1750,15 +1743,11 @@ static int setup_parasite_args(pid_t pid, void *base) unsigned long *src = (unsigned long *)&pa; unsigned long *dst = (unsigned long *)PARASITE_ARGS_ADDR(base); - if (parasite_socket_dir) - create_filesystem_socketname(pa.addr, sizeof(pa.addr), pid); - else - create_abstract_socketname(pa.addr, sizeof(pa.addr), pid); + parasite_socket_init(&pa.addr, pid); return poke(pid, dst, src, sizeof(pa)); } - static void *parasite_watch_thread(void *ptr) { int ret; diff --git a/memcr.h b/memcr.h index a2fdbb7..d4a8fea 100644 --- a/memcr.h +++ b/memcr.h @@ -26,7 +26,7 @@ #endif struct parasite_args { - char addr[108]; /* abstract or filesystem socket address */ + struct sockaddr_un addr; }; typedef enum { diff --git a/parasite.c b/parasite.c index 94d6f43..1a8740a 100644 --- a/parasite.c +++ b/parasite.c @@ -16,15 +16,11 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include -#include -#include #include #include #include #include "memcr.h" - #include "arch/syscall.h" #define VERBOSE 1 @@ -32,41 +28,11 @@ #define __stringify_1(x...) #x #define __stringify(x...) __stringify_1(x) -#define BOOM() do { *((int *)NULL) = 1; } while (0) - static int finish; -void service(unsigned int cmd, void *args); +void service(struct parasite_args *args); #if VERBOSE == 1 -static char *long_to_str(long v) -{ - static char buf[sizeof(unsigned long) * 3]; - char *p = buf + sizeof(buf) - 1; - int minus = 0; - - *p = '\0'; - - if (v == 0) { - *--p = '0'; - return p; - } - - if (v < 0) { - minus = 1; - v = -v; - } - - while (v) { - *--p = '0' + (v % 10); - v /= 10; - } - - if (minus) - *--p = '-'; - - return p; -} static char *ulong_to_hstr(unsigned long v) { @@ -76,10 +42,8 @@ static char *ulong_to_hstr(unsigned long v) *p = '\0'; - if (v == 0) { + if (v == 0) *--p = '0'; - return p; - } while (v) { x = v % 16; @@ -90,7 +54,7 @@ static char *ulong_to_hstr(unsigned long v) return p; } -static void print_msg(int fd, const char *msg) +static void print(int fd, const char *msg) { int size; @@ -99,92 +63,53 @@ static void print_msg(int fd, const char *msg) sys_write(fd, msg, size); } -#define __DEBUG__ do { \ - print_msg(1, __func__); \ - print_msg(1, "() +" __stringify(__LINE__) "\n"); \ -} while (0); - -#define print_err(fd, txt, ret) do { \ - print_msg((fd), __func__); \ - print_msg((fd), "() +" __stringify(__LINE__) ": " txt); \ - print_msg((fd), long_to_str(ret)); \ - print_msg((fd), "\n"); \ -} while (0); +#else /* VERBOSE */ -#define die(txt, ret) do { \ - print_msg(2, __func__); \ - print_msg(2, "() +" __stringify(__LINE__) ": " txt); \ - print_msg(2, long_to_str(ret)); \ - print_msg(2, "\n"); \ - *((int *)NULL) = 1; \ -} while (0); -#else /* VERBOSE*/ +#define print(fd, msg) {} -#define print_msg(fd, msg) {} -#define __DEBUG__ -#define print_err(fd, txt, ret) {} -#define die(txt, ret) { \ - *((int *)NULL) = 1; \ -} #endif -static void xstrcpy(char *dst, char *src) -{ - int idx; - - for (idx = 0; src[idx] != '\0'; idx++) - dst[idx] = src[idx]; +#define die(txt, ret) do { \ + print(2, __stringify(__LINE__) ": " txt); \ + print(2, ulong_to_hstr(ret)); \ + print(2, "\n"); \ + __builtin_trap(); \ +} while (0); - dst[idx + 1] = '\0'; -} -static int xread(int fd, void *buf, int size) +static int read(int fd, void *buf, int size) { int ret; - int off = 0; + int done = 0; - while (1) { - ret = sys_read(fd, buf + off, size - off); + while (done < size) { + ret = sys_read(fd, buf + done, size - done); if (ret == 0) break; - if (ret < 0) { - print_err(2, "sys_read() failed with ret ", ret); - break; - } - - if (ret < size - off) { - off += ret; - continue; - } + if (ret < 0) + die("sys_read() failed: ", ret); - return size; + done += ret; } - return ret; + return done; } -static int xwrite(int fd, void *buf, int size) +static int write(int fd, const void *buf, int size) { int ret; - int off = 0; + int done = 0; - while (1) { - ret = sys_write(fd, buf + off, size - off); - if (ret < 0) { - print_err(2, "sys_write() failed with ret ", ret); - break; - } - - if (ret < size - off) { - off += ret; - continue; - } + while (done < size) { + ret = sys_write(fd, buf + done, size - done); + if (ret < 0) + die("sys_write() failed: ", ret); - return size; + done += ret; } - return ret; + return done; } static int cmd_mprotect(int cd) @@ -193,20 +118,13 @@ static int cmd_mprotect(int cd) struct vm_mprotect req; while (1) { - ret = xread(cd, &req, sizeof(req)); + ret = read(cd, &req, sizeof(req)); if (ret == 0) break; - if (ret < 0) { - print_err(2, "xread() failed with ret ", ret); - BOOM(); - } - ret = sys_mprotect(req.addr, req.len, req.prot); - if (ret == -1) { - print_err(2, "sys_mprotect() failed with ret ", ret); - BOOM(); - } + if (ret < 0) + die("sys_mprotect() failed: ", ret); } return 0; @@ -218,26 +136,16 @@ static int cmd_get_pages(int cd) struct vm_region_req req; while (1) { - ret = xread(cd, &req, sizeof(req)); + ret = read(cd, &req, sizeof(req)); if (ret == 0) break; - if (ret < 0) { - print_err(2, "xread() failed with ret ", ret); - BOOM(); - } - if (req.flags & VM_REGION_TX) - xwrite(cd, (void *)req.vmr.addr, req.vmr.len); + write(cd, (void *)req.vmr.addr, req.vmr.len); ret = sys_madvise(req.vmr.addr, req.vmr.len, MADV_DONTNEED); - if (ret < 0) { - print_msg(2, "sys_madvise() MADV_DONTNEED of "); - print_msg(2, ulong_to_hstr((long)req.vmr.addr)); - print_msg(2, " failed with "); - print_msg(2, long_to_str(ret)); - print_msg(2, "\n"); - } + if (ret < 0) + die("sys_madvise() failed: ", ret); } return 0; @@ -249,11 +157,11 @@ static int cmd_set_pages(int cd) struct vm_region_req req; while (1) { - ret = xread(cd, &req, sizeof(req)); + ret = read(cd, &req, sizeof(req)); if (ret == 0) break; - xread(cd, (void *)req.vmr.addr, req.vmr.len); + read(cd, (void *)req.vmr.addr, req.vmr.len); } return 0; @@ -272,10 +180,8 @@ static int handle_connection(int cd) char cmd; ret = sys_read(cd, &cmd, 1); - if (ret != 1) { - print_err(2, "sys_read() failed: ", ret); - return ret; - } + if (ret != 1) + die("sys_read() failed: ", ret); switch (cmd) { case CMD_MPROTECT: @@ -287,48 +193,36 @@ static int handle_connection(int cd) case CMD_END: return cmd_end(cd); default: - print_err(2, "unhandled cmd ", cmd); - break; + die("unhandled cmd: ", cmd); } return 0; } -void __attribute__((__used__)) service(unsigned int cmd, void *args) +void __attribute__((__used__)) service(struct parasite_args *args) { int ret; - struct parasite_args *pa = args; int srvd; - struct sockaddr_un addr; - srvd = sys_socket(PF_UNIX, SOCK_STREAM, 0); - if (srvd < 0) { + srvd = sys_socket(AF_UNIX, SOCK_STREAM, 0); + if (srvd < 0) die("sys_socket() failed: ", srvd); - } - - addr.sun_family = PF_UNIX; - xstrcpy(addr.sun_path, pa->addr); - if ('#' == addr.sun_path[0]) - addr.sun_path[0] = '\0'; - ret = sys_bind(srvd, (struct sockaddr *)&addr, sizeof(addr)); - if (ret) { + ret = sys_bind(srvd, (struct sockaddr *)&args->addr, sizeof(args->addr)); + if (ret < 0) die("sys_bind() failed: ", ret); - } - ret = sys_listen(srvd, 8); - if (ret < 0) { + ret = sys_listen(srvd, 1); + if (ret < 0) die("sys_listen() failed: ", ret); - } while (!finish) { ret = sys_accept(srvd, NULL, NULL); - if (ret < 0) { - print_err(2, "sys_accept() failed: ", ret); - } else { - handle_connection(ret); - sys_close(ret); - } + if (ret < 0) + die("sys_accept() failed: ", ret); + + handle_connection(ret); + sys_close(ret); } sys_close(srvd);