stabbish

:)
git clone https://git.sr.ht/~ashymad/stabbish
Log | Files | Refs | README | LICENSE

commit 76531e58f66072cbf1db8d42d2b5730bd2c73865
parent 4398cff49f7b9d2b65348d3857206deb777957f2
Author: Szymon Mikulicz <szymon.mikulicz@posteo.net>
Date:   Tue,  7 Jul 2026 17:17:42 +0200

Cleaner try()

Diffstat:
MMakefile | 20+++++++++-----------
Msrc/Makefile | 2+-
Msrc/magic.c | 2+-
Msrc/main.c | 12++++++------
Msrc/payload.c | 6+++---
Msrc/utils.c | 2+-
Msrc/utils.h | 18++++++++++--------
Mtest/Makefile | 4+++-
8 files changed, 34 insertions(+), 32 deletions(-)

diff --git a/Makefile b/Makefile @@ -10,26 +10,24 @@ STABBISH=$(MKFILE_DIR)/src/stabbish BUSYBOX=$(BUSYBOX_PATH)/busybox CC=$(MUSL_PATH)/gcc -MAKEFLAGS=--no-print-directory +MAKEFLAGS += --no-print-directory -s CFLAGS=-static NPROC=$(shell nproc) export PATH:=$(MUSL_PATH):$(PATH) -.PHONY: test clean.% clean.all +.PHONY: test $(STABBISH) $(CC) $(BUSYBOX) clean.% clean.all -test: FORCE - @$(MAKE) $(MAKEFLAGS) -C $(MKFILE_DIR)/test +test: + @$(MAKE) -C $(MKFILE_DIR)/test -$(STABBISH): FORCE - @$(MAKE) $(MAKEFLAGS) -C $(MKFILE_DIR)/src +$(STABBISH): + @$(MAKE) -C $(MKFILE_DIR)/src -$(CC) $(BUSYBOX): FORCE - @$(MAKE) $(MAKEFLAGS) -C $(MKFILE_DIR)/deps +$(CC) $(BUSYBOX): + @$(MAKE) -C $(MKFILE_DIR)/deps clean.all: clean.src clean.test clean.deps clean.%: - @$(MAKE) $(MAKEFLAGS) -C $(MKFILE_DIR)/$(patsubst clean.%,%,$@) clean - -FORCE: ; + @$(MAKE) -C $(MKFILE_DIR)/$(patsubst clean.%,%,$@) clean diff --git a/src/Makefile b/src/Makefile @@ -8,7 +8,7 @@ stabbish: main.o payload.o magic.o utils.o busybox/busybox.inc.o $(info $() LD $@) @$(CC) $(CFLAGS) $^ -o $@ -main.o: main.c busybox/busybox.inc.h +main.o: main.c busybox/busybox.inc.h utils.h payload.h magic.h $(info $() CC $@) @$(CC) $(CFLAGS) -c $< -o $@ diff --git a/src/magic.c b/src/magic.c @@ -13,7 +13,7 @@ struct magic magic_detect(fd file) { unsigned char header[10]; - size_t trys(header_len, read(file, &header, 10)); + size_t header_len = try(read(file, &header, 10)); for (int i = 0; i < tsizeof(MAGICS); i++) { if (header_len > MAGICS[i].length && diff --git a/src/main.c b/src/main.c @@ -21,11 +21,9 @@ int main(int argc, char **argv) { if (start_shell) shift(1); - fd trys(busybox, memfd_create("busybox", 0)); - fd trys(rcfile, memfd_create("rcfile", 0)); - fd trys(payload, get_payload("/proc/self/exe")); - - try(write(busybox, _inc_busybox, _inc_busybox_size)); + fd busybox = try(memfd_create("busybox", 0)); + fd rcfile = try(memfd_create("rcfile", 0)); + fd payload = try(get_payload("/proc/self/exe")); setenv("ENV", pasprintf("/dev/fd/%i", rcfile), 1); setenv("BUSYBOX", pasprintf("/dev/fd/%i", busybox), 1); @@ -36,6 +34,8 @@ int main(int argc, char **argv) { setenv("PAYLOAD", pasprintf("/dev/fd/%i", payload), 1); } + try(write(busybox, _inc_busybox, _inc_busybox_size)); + if (start_shell || payload == ENOPAYLOAD) { argv[0] = strdup("ash"); return fexecve(busybox, argv, environ); @@ -43,7 +43,7 @@ int main(int argc, char **argv) { struct magic magic = magic_detect(payload); if (magic.tool) { - fd trys(extracted, memfd_create("extracted", 0)); + fd extracted = try(memfd_create("extracted", 0)); char *tool = strdup(magic.tool); struct stdstream std = {payload, extracted, -1}; diff --git a/src/payload.c b/src/payload.c @@ -17,12 +17,12 @@ fd get_payload(string path) { static fd try_return = -1; - fd trys(in, open(path, O_RDONLY)); + fd in = try(open(path, O_RDONLY)); ElfW(Ehdr) header; try(read(in, &header, sizeof(header))); - size_t trys(size, lseek(in, 0, SEEK_END)); + size_t size = try(lseek(in, 0, SEEK_END)); off_t offset = header.e_shoff + (header.e_shentsize * header.e_shnum); size_t payload_size = size - offset; @@ -31,7 +31,7 @@ fd get_payload(string path) { return ENOPAYLOAD; } - int trys(payload, memfd_create("payload", 0)); + int payload = try(memfd_create("payload", 0)); try(sendfile(payload, in, &offset, payload_size)); try(lseek(payload, SEEK_SET, 0)); diff --git a/src/utils.c b/src/utils.c @@ -22,7 +22,7 @@ char *pasprintf(string __restrict str, ...) { int memexecv(fd exe, char **argv, char **envp, struct stdstream std) { int try_return = -1; - pid_t trys(pid, fork()); + pid_t pid = try(fork()); if (pid) { int wstatus; diff --git a/src/utils.h b/src/utils.h @@ -7,6 +7,9 @@ typedef int fd; typedef const char *string; +_Thread_local static int __try_tmp_int; +_Thread_local static long __try_tmp_long; + #define shift(n) \ if (n < argc) { \ argv[n] = argv[0]; \ @@ -16,21 +19,20 @@ typedef const char *string; #define tsizeof(table) sizeof(table) / sizeof(table[0]) -#define trys2(nam, cmd, chk) \ - nam = cmd; \ - try2(nam, chk) +#define append_type(A, X) _Generic((X), int: A##_int, long: A##_long) + +#define get_1st_arg(arg1, ...) arg1 -#define trys(nam, cmd) trys2(nam, cmd, != -1) +#define default_arg(VAL, ...) get_1st_arg(__VA_ARGS__ __VA_OPT__(, ) VAL) -#define try2(cmd, chk) \ - if (!((cmd)chk)) { \ +#define try(cmd, ...) \ + (append_type(__try_tmp, cmd) = cmd); \ + if (append_type(__try_tmp, cmd) default_arg(== -1, ##__VA_ARGS__)) { \ fprintf(stderr, "%s:%i: %s: %s\n", __FILE__, __LINE__, #cmd, \ strerror(errno)); \ return try_return; \ } -#define try(cmd) try2(cmd, != -1) - struct stdstream { fd in; fd out; diff --git a/test/Makefile b/test/Makefile @@ -11,7 +11,9 @@ all: $(TESTS) test.%: %.stab $(info $() TST $@) - @[ "$$($(<D)/$(<F) output)" = "$$($(<D)/$(<F) input)" ] + @IN="$$($(<D)/$(<F) input)" || exit 1; \ + OUT="$$($(<D)/$(<F) output)" || exit 2; \ + [ "$$IN" = "$$OUT" ] || exit 3 %.stab: %.test $(STABBISH) $(info $() GEN $@)