From d988d1d28b2e48655f0c3adb7c66a17ef1786333 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sat, 19 Apr 2025 11:50:33 +0200 Subject: [PATCH] proj: Adapt test scripts and fix bugs --- Makefile | 4 +- proj/intercept/src/intercept.c | 6 ++- proj/server/src/intercept/__init__.py | 58 ++++++++++++++++++--------- proj/server/src/test-interrupts | 3 +- proj/server/src/test-memory | 3 +- proj/server/src/test-return-values | 3 +- 6 files changed, 52 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index 59d5b41..36eb32d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: all clean all: $(MAKE) -C proj/test1/ - $(MAKE) -C proj/test2/ -C /usr/src/linux-`uname -r` SUBDIRS=$PWD modules + $(MAKE) -C proj/intercept/ clean: $(MAKE) -C proj/test1/ - $(MAKE) -C proj/test2/ + $(MAKE) -C proj/intercept/ diff --git a/proj/intercept/src/intercept.c b/proj/intercept/src/intercept.c index 9ee6ad9..b9c3679 100644 --- a/proj/intercept/src/intercept.c +++ b/proj/intercept/src/intercept.c @@ -2225,7 +2225,11 @@ int sym(getaddrinfo)(const char *restrict node, const char *restrict service, co else if_invalid(getaddrinfo) } const int ret = __real_getaddrinfo(node, service, hints, res); - msg("return %i; errno %s", ret, strerrorname_np(errno)); + if (res != NULL) { + msg("return %i; errno %s; res=%p", ret, strerrorname_np(errno), *res); + } else { + msg("return %i; errno %s", ret, strerrorname_np(errno), *res); + } return ret; } diff --git a/proj/server/src/intercept/__init__.py b/proj/server/src/intercept/__init__.py index f41672e..9835259 100644 --- a/proj/server/src/intercept/__init__.py +++ b/proj/server/src/intercept/__init__.py @@ -61,12 +61,12 @@ class Handler(StreamRequestHandler): self.after() @staticmethod - def parse_str(argument: str) -> tuple[str or bytes, int]: - if not ((len(argument) >= 2 and argument[0] == '"') or (len(argument) >= 3 and argument[0] == 'b' and argument[1] == '"')): + def parse_str(argument: str) -> tuple[bytes, int]: + if not (len(argument) >= 2 and argument[0] == '"'): raise ValueError() idx = 1 esc, fin = False, False - data = b'' if argument[0] == 'b' else '' + data = b'' tmp = None for ch in argument[1:]: idx += 1 @@ -79,22 +79,26 @@ class Handler(StreamRequestHandler): elif tmp: tmp += ch if len(tmp) == 2: - data += bytes([int(tmp, 16)]) if argument[0] == 'b' else chr(int(tmp, 16)) + data += bytes([int(tmp, 16)]) tmp = None elif esc: if ch in ('\\', '"'): - data += ch.encode('ascii') if argument[0] == 'b' else ch + data += ch.encode('ascii') + esc = False elif ch == 'x': - tmp = '' - esc = False + tmp = '' + esc = False + elif ch in ('n', 'r'): + data += b'\n' if ch == 'n' else b'\r' + esc = False else: - raise ValueError() + raise ValueError(ch) elif ch == '"': fin = True elif ch == '\\': esc = True else: - data += ch.encode('utf-8') if argument[0] == 'b' else ch + data += ch.encode('utf-8') if not fin: raise ValueError() return data, idx @@ -106,6 +110,14 @@ class Handler(StreamRequestHandler): m = re.match(r'^\s*(\(nil\)|NULL|null|nullptr)\s*(,|$)', argument) if m: return 0, len(m.group(0)) + m = re.match(r'\s*"', argument) + if m: + idx = len(m.group(0)) - 1 + s, i = Handler.parse_str(argument[idx:]) + idx = i + if idx < len(argument) and argument[idx] == ',': + idx += 1 + return s, idx m = re.match(r'^\s*(.*?)([,:]|$)', argument) a, e = m.group(1), m.group(2) idx = len(m.group(0)) @@ -141,20 +153,27 @@ class Handler(StreamRequestHandler): idx += 1 return (val, s), idx elif argument[idx] == '{': - m = re.match(r'^[^}]*', argument[idx:]) - value = m.group(0) - if not value.startswith('{') or not value.endswith('}'): + m = re.match(r'^[^}]*}', argument[idx:]) + if not m or not m.group(0).startswith('{') or not m.group(0).endswith('}'): raise ValueError() + value = m.group(0) idx += len(value) if idx < len(argument) and argument[idx] == ',': idx += 1 entries = {} - for e in [v.strip() for v in value[1:-1].split(',') if len(e.strip()) > 0]: + for e in [v.strip() for v in value[1:-1].split(',') if len(v.strip()) > 0]: k, v = e.split(':', 1) - entries[k.strip()] = int(v.strip(), 0) + entries[k.strip()] = Handler.parse_arg(v)[0] return (val, entries), idx else: - raise ValueError() + m = re.match(r'[A-Z0-9_]+', argument[idx:]) + if not m: + raise ValueError() + value = m.group(0) + idx += len(value) + if idx < len(argument) and argument[idx] == ',': + idx += 1 + return (val, value), idx @staticmethod def parse_args(arguments: str) -> tuple[tuple, int]: @@ -201,7 +220,8 @@ class Handler(StreamRequestHandler): self.wfile.write(command.encode('utf-8') + b'\n') else: ret = data.decode('utf-8') - ret_value, _ = Handler.parse_arg(ret[7:].split(';')[0]) + ret_value, _ = Handler.parse_arg(ret[7:].split(';', 1)[0]) + # FIXME parse return values (errno, ...) (self.ret_addr, self.dli_file_name, self.rel_ret_addr, self.dli_sym_name, func_name, args) = self.stack.pop() try: func = getattr(self, f'after_{func_name}') @@ -461,10 +481,10 @@ class Handler(StreamRequestHandler): def after_connect(self, sockfd: int, address: PointerTo[StructSockAddr], address_len: int, ret_value: int, errno: str = None) -> None: raise NotImplementedError() - def before_getaddrinfo(self, node: PointerTo[bytes], service: PointerTo[bytes], hints: PointerTo[StructAddrInfo], res: Pointer) -> str: + def before_getaddrinfo(self, node: PointerTo[bytes], service: PointerTo[bytes], hints: PointerTo[StructAddrInfo], res_ptr: Pointer) -> str: raise NotImplementedError() - def after_getaddrinfo(self, node: PointerTo[bytes], service: PointerTo[bytes], hints: PointerTo[StructAddrInfo], res: Pointer, - ret_value: int, errno: str = None) -> None: + def after_getaddrinfo(self, node: PointerTo[bytes], service: PointerTo[bytes], hints: PointerTo[StructAddrInfo], res_ptr: Pointer, + ret_value: int, errno: str = None, res: Pointer = None) -> None: raise NotImplementedError() def before_freeaddrinfo(self, res: Pointer) -> str: raise NotImplementedError() diff --git a/proj/server/src/test-interrupts b/proj/server/src/test-interrupts index c005edc..2d1410e 100755 --- a/proj/server/src/test-interrupts +++ b/proj/server/src/test-interrupts @@ -24,7 +24,8 @@ def main() -> None: subprocess.run(extra, env={ 'LD_PRELOAD': os.getcwd() + '/../../intercept/intercept.so', 'INTERCEPT': 'unix:' + socket_name, - 'INTERCEPT_FUNCTIONS': ','.join(['*', '-malloc', '-calloc', '-realloc', '-reallocarray', '-free']), + 'INTERCEPT_FUNCTIONS': '*', + 'INTERCEPT_LIBRARIES': '*,-/lib*,-/usr/lib*', }) diff --git a/proj/server/src/test-memory b/proj/server/src/test-memory index e94cd9e..5739fcc 100755 --- a/proj/server/src/test-memory +++ b/proj/server/src/test-memory @@ -24,7 +24,8 @@ def main() -> None: subprocess.run(extra, env={ 'LD_PRELOAD': os.getcwd() + '/../../intercept/intercept.so', 'INTERCEPT': 'unix:' + socket_name, - 'INTERCEPT_FUNCTIONS': ','.join(['malloc', 'calloc', 'realloc', 'reallocarray', 'free']), + 'INTERCEPT_FUNCTIONS': ','.join(['malloc', 'calloc', 'realloc', 'reallocarray', 'free', 'getaddrinfo', 'freeaddrinfo']), + 'INTERCEPT_LIBRARIES': '*,-/lib*,-/usr/lib*', }) diff --git a/proj/server/src/test-return-values b/proj/server/src/test-return-values index b59a3c6..025d5f4 100755 --- a/proj/server/src/test-return-values +++ b/proj/server/src/test-return-values @@ -35,7 +35,8 @@ def main() -> None: subprocess.run(extra, stdin=stdin, env={ 'LD_PRELOAD': os.getcwd() + '/../../intercept/intercept.so', 'INTERCEPT': 'unix:' + socket_name, - 'INTERCEPT_FUNCTIONS': ','.join(['*', '-malloc', '-calloc', '-realloc', '-reallocarray', '-free']), + 'INTERCEPT_FUNCTIONS': '*', + 'INTERCEPT_LIBRARIES': '*,-/lib*,-/usr/lib*', }) for i, name in enumerate(ctx['call_sequence']): errors = [r[1] for r in ctx['results'] if r[0] == i]