From 6a0aeea88a3bb2b8962fb989c6f8f966d8a5eb06 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Thu, 30 Apr 2026 17:25:21 +0200 Subject: [PATCH] Fix stream life-time race condition by reversing ownership --- ce/edit.c | 4 ++-- ce/interp.c | 39 +++++++++++++++++++++++---------------- include/syscall_defs.h | 1 + init/init.c | 2 +- kernel/amd64/proc.c | 2 +- kernel/syscall/syscall.c | 24 +++++++++++++----------- libu/in_input.c | 2 +- libu/mprintf.c | 3 ++- libu/system.c | 6 ++++-- libu/system.h | 5 ++++- 10 files changed, 52 insertions(+), 36 deletions(-) diff --git a/ce/edit.c b/ce/edit.c index 2ce39b0..05b8a3d 100644 --- a/ce/edit.c +++ b/ce/edit.c @@ -233,11 +233,11 @@ void edit_start(const char* volume, const char* file_path, const char* text, siz (int)(editor.cursor.line - editor.row_offset) + 1, (int)(editor.cursor.col - editor.col_offset) + 1 + (int)gutter_width); - stream_write(process_get_pgid(), STREAM_OUT, backbuffer, bbptr - backbuffer); + stream_write(process_get_exec_pgid(), STREAM_OUT, backbuffer, bbptr - backbuffer); uint8_t ch = 0; for (;;) { - if (stream_read(process_get_pgid(), STREAM_IN, &ch, 1) > 0) + if (stream_read(STREAM_IN, &ch, 1) > 0) break; else sched(); diff --git a/ce/interp.c b/ce/interp.c index c231ccf..c007488 100644 --- a/ce/interp.c +++ b/ce/interp.c @@ -188,7 +188,7 @@ static void cat(struct context* context, char** file_paths, size_t files_count) return; } - stream_write(process_get_pgid(), STREAM_OUT, buffer, chunk_size); + stream_write(process_get_exec_pgid(), STREAM_OUT, buffer, chunk_size); } if (rem > 0) { @@ -198,7 +198,7 @@ static void cat(struct context* context, char** file_paths, size_t files_count) return; } - stream_write(process_get_pgid(), STREAM_OUT, buffer, rem); + stream_write(process_get_exec_pgid(), STREAM_OUT, buffer, rem); } filereader_fini(&fr); @@ -463,25 +463,17 @@ struct cmd_write_proc_ctx { int cancel_pid; }; -static void cmd_collect_proc(void* arg) { - int pgid = (int)(uintptr_t)arg; - - char recv[1024]; - int n; - for (;;) { - if ((n = stream_read(pgid, STREAM_OUT, (void*)recv, sizeof(recv) - 1)) > 0) - stream_write(process_get_pgid(), STREAM_OUT, (void*)recv, n); - else - sched(); - } -} +struct cmd_collect_proc_ctx { + int pgid; + int collect_pid; +}; static void cmd_write_proc(void* arg) { struct cmd_write_proc_ctx* ctx = arg; uint8_t ch = 0; for (;;) { - if (stream_read(process_get_pgid(), STREAM_IN, &ch, 1) > 0) { + if (stream_read(STREAM_IN, &ch, 1) > 0) { if (ch == KB_CTRL('C')) { kill(ctx->cancel_pid); return; @@ -494,6 +486,20 @@ static void cmd_write_proc(void* arg) { } } +static void cmd_collect_proc(void* arg) { + struct cmd_collect_proc_ctx* ctx = arg; + + int n; + char recv[1024]; + for (;;) { + if ((n = stream_read(STREAM_OUT, recv, sizeof(recv))) > 0) { + stream_write(process_get_exec_pgid(), STREAM_OUT, recv, n); + } else { + sched(); + } + } +} + static void execute_cmd(struct ast_cmd* cmd, struct context* context, bool run_bg) { if (strcmp(cmd->name, "echo") == 0) { echo(context, cmd->args, cmd->arg_count); @@ -576,9 +582,10 @@ static void execute_cmd(struct ast_cmd* cmd, struct context* context, bool run_b cprintf(context, "started background process: PID %d\n", pid); } else { struct cmd_write_proc_ctx wpctx = {.pgid = pgid, .cancel_pid = pid}; + struct cmd_collect_proc_ctx cpctx = {.pgid = pgid, .collect_pid = pid}; struct process_data* write_pdata = process_spawn(&cmd_write_proc, (void*)&wpctx); - struct process_data* collect_pdata = process_spawn(&cmd_collect_proc, (void*)(uintptr_t)pgid); + struct process_data* collect_pdata = process_spawn(&cmd_collect_proc, (void*)&cpctx); exec_partial_fini(pid); wait_for_pid(pid); diff --git a/include/syscall_defs.h b/include/syscall_defs.h index 4b058d2..cd79cc4 100644 --- a/include/syscall_defs.h +++ b/include/syscall_defs.h @@ -41,5 +41,6 @@ #define SYS_VOLUME_DELETE 40 #define SYS_DATE_TIME 41 #define SYS_GET_CMDLINE 42 +#define SYS_PROC_IS_ALIVE 43 #endif // _M_SYSCALL_DEFS_H diff --git a/init/init.c b/init/init.c index 5ccaa46..ea32b26 100644 --- a/init/init.c +++ b/init/init.c @@ -18,7 +18,7 @@ static void receiver(void* arg) { char recv[RECV_MAX]; int n; for (;;) { - n = stream_read(ce_pgid, STREAM_OUT, (void*)recv, RECV_MAX - 1); + n = stream_read(STREAM_OUT, (void*)recv, RECV_MAX - 1); if (n > 0) terminal_print(recv, n); diff --git a/kernel/amd64/proc.c b/kernel/amd64/proc.c index 1b2fa3e..f19a458 100644 --- a/kernel/amd64/proc.c +++ b/kernel/amd64/proc.c @@ -60,7 +60,7 @@ struct proc* proc_from_elf(uint8_t* elf_contents) { proc->pdata.regs.rip = aux.entry; fx_init(proc->pdata.fx_env); - proc->exec_pid = -1; + proc->exec_pid = proc->pid; return proc; } diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 87ff49b..1af4a6d 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -770,17 +770,11 @@ DEFINE_SYSCALL(sys_stream_write) { return SYSRESULT(ST_OK); } -/* int stream_read (int pgid, int rid, void* buffer, size_t size) */ +/* int stream_read (int rid, void* buffer, size_t size) */ DEFINE_SYSCALL(sys_stream_read) { - int pgid = (int)a1; - int rid = (int)a2; - uintptr_t uvaddr_buffer = a3; - size_t buffer_size = (size_t)a4; - - struct procgroup* target_procgroup = procgroup_find(pgid); - - if (target_procgroup == NULL) - return SYSRESULT(-ST_NOT_FOUND); + int rid = (int)a1; + uintptr_t uvaddr_buffer = a2; + size_t buffer_size = (size_t)a3; struct procgroup* procgroup = proc->procgroup; @@ -789,7 +783,7 @@ DEFINE_SYSCALL(sys_stream_read) { if (buffer == NULL) return SYSRESULT(-ST_BAD_ADDRESS_SPACE); - struct proc_resource* stream_resource = proc_find_resource(target_procgroup, rid); + struct proc_resource* stream_resource = proc_find_resource(procgroup, rid); if (stream_resource == NULL) return SYSRESULT(-ST_NOT_FOUND); @@ -893,6 +887,13 @@ DEFINE_SYSCALL(sys_get_cmdline) { return SYSRESULT(procgroup->uvaddr_cmdline); } +/* int proc_is_alive(int pid) */ +DEFINE_SYSCALL(sys_proc_is_alive) { + int pid = (int)a1; + + return SYSRESULT(proc_find_pid(pid) != NULL ? 1 : 0); +} + static syscall_handler_func_t handler_table[] = { [SYS_QUIT] = &sys_quit, [SYS_TEST] = &sys_test, @@ -934,6 +935,7 @@ static syscall_handler_func_t handler_table[] = { [SYS_VOLUME_DELETE] = &sys_volume_delete, [SYS_DATE_TIME] = &sys_date_time, [SYS_GET_CMDLINE] = &sys_get_cmdline, + [SYS_PROC_IS_ALIVE] = &sys_proc_is_alive, }; syscall_handler_func_t syscall_find_handler(int syscall_num) { diff --git a/libu/in_input.c b/libu/in_input.c index a180d72..52675a0 100644 --- a/libu/in_input.c +++ b/libu/in_input.c @@ -46,7 +46,7 @@ void in_stream_read_line(const char* prompt, char* buffer, size_t max) { for (;;) { uint8_t ch; - if (stream_read(process_get_pgid(), STREAM_IN, &ch, 1) <= 0) { + if (stream_read(STREAM_IN, &ch, 1) <= 0) { sched(); continue; } diff --git a/libu/mprintf.c b/libu/mprintf.c index 18b6811..7f4db53 100644 --- a/libu/mprintf.c +++ b/libu/mprintf.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -32,7 +33,7 @@ void mprintf(const char* fmt, ...) { va_end(args); - stream_write(process_get_pgid(), STREAM_OUT, mprintf_buffer, len); + stream_write(process_get_exec_pgid(), STREAM_OUT, mprintf_buffer, len); mprintf_buffer_unlock(); } diff --git a/libu/system.c b/libu/system.c index 2776d65..94efe8f 100644 --- a/libu/system.c +++ b/libu/system.c @@ -101,8 +101,8 @@ int stream_write(int pgid, int rid, void* buffer, size_t size) { return (int)do_syscall(SYS_STREAM_WRITE, pgid, rid, buffer, size); } -int stream_read(int pgid, int rid, void* buffer, size_t size) { - return (int)do_syscall(SYS_STREAM_READ, pgid, rid, buffer, size); +int stream_read(int rid, void* buffer, size_t size) { + return (int)do_syscall(SYS_STREAM_READ, rid, buffer, size); } int get_proc_info(struct proc_info* infos, size_t count) { @@ -122,3 +122,5 @@ int volume_delete(const char* key) { return (int)do_syscall(SYS_VOLUME_DELETE, k int date_time(struct date_time* dt) { return (int)do_syscall(SYS_DATE_TIME, dt); } const char* get_cmdline(void) { return (const char*)do_syscall(SYS_GET_CMDLINE, 0); } + +int proc_is_alive(int pid) { return (int)do_syscall(SYS_PROC_IS_ALIVE, pid); } diff --git a/libu/system.h b/libu/system.h index 6540549..63f8331 100644 --- a/libu/system.h +++ b/libu/system.h @@ -110,7 +110,7 @@ int get_self_pid(void); int stream_write(int pgid, int rid, void* buffer, size_t size); /* Read from a stream */ -int stream_read(int pgid, int rid, void* buffer, size_t size); +int stream_read(int rid, void* buffer, size_t size); /* get process information */ int get_proc_info(struct proc_info* infos, size_t count); @@ -130,4 +130,7 @@ int date_time(struct date_time* dt); /* Get commandline string */ const char* get_cmdline(void); +/* check if PID is alive */ +int proc_is_alive(int pid); + #endif // _LIBMSL_M_SYSTEM_H