Skip to content

Commit

Permalink
protocol: fix potential null pss access
Browse files Browse the repository at this point in the history
  • Loading branch information
tsl0922 committed Aug 17, 2022
1 parent b76c91e commit d7db637
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 67 deletions.
25 changes: 13 additions & 12 deletions src/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ static bool check_host_origin(struct lws *wsi) {
char buf[256];
memset(buf, 0, sizeof(buf));
int len = lws_hdr_copy(wsi, buf, (int)sizeof(buf), WSI_TOKEN_ORIGIN);
if (len <= 0) {
return false;
}
if (len <= 0) return false;

const char *prot, *address, *path;
int port;
Expand All @@ -71,8 +69,10 @@ static bool check_host_origin(struct lws *wsi) {
return len > 0 && strcasecmp(buf, host_buf) == 0;
}

static void process_read_cb(void *ctx, pty_buf_t *buf, bool eof) {
struct pss_tty *pss = (struct pss_tty *)ctx;
static void process_read_cb(pty_process *process, pty_buf_t *buf, bool eof) {
if (process->killed) return ;

struct pss_tty *pss = (struct pss_tty *)process->ctx;
if (eof && !process_running(pss->process))
pss->lws_close_status = pss->process->exit_code == 0 ? 1000 : 1006;
else
Expand All @@ -81,16 +81,17 @@ static void process_read_cb(void *ctx, pty_buf_t *buf, bool eof) {
lws_callback_on_writable(pss->wsi);
}

static void process_exit_cb(void *ctx, pty_process *process) {
struct pss_tty *pss = (struct pss_tty *)ctx;
pss->process = NULL;
static void process_exit_cb(pty_process *process) {
if (process->killed) {
lwsl_notice("process killed with signal %d, pid: %d\n", process->exit_signal, process->pid);
} else {
lwsl_notice("process exited with code %d, pid: %d\n", process->exit_code, process->pid);
pss->lws_close_status = process->exit_code == 0 ? 1000 : 1006;
lws_callback_on_writable(pss->wsi);
return ;
}

lwsl_notice("process exited with code %d, pid: %d\n", process->exit_code, process->pid);
struct pss_tty *pss = (struct pss_tty *)process->ctx;
pss->process = NULL;
pss->lws_close_status = process->exit_code == 0 ? 1000 : 1006;
lws_callback_on_writable(pss->wsi);
}

static char **build_args(struct pss_tty *pss) {
Expand Down
71 changes: 29 additions & 42 deletions src/pty.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ void pty_buf_free(pty_buf_t *buf) {

static void read_cb(uv_stream_t *stream, ssize_t n, const uv_buf_t *buf) {
uv_read_stop(stream);
pty_io_t *io = (pty_io_t *) stream->data;
pty_process *process = (pty_process *) stream->data;
if (n <= 0) {
if (n == UV_ENOBUFS || n == 0) return;
if (n != UV_EOF) printf("== uv_read failed with error %ld: %s\n", n, uv_strerror(n));
io->read_cb(io->ctx, NULL, true);
process->read_cb(process, NULL, true);
goto done;
}
io->read_cb(io->ctx, pty_buf_init(buf->base, (size_t) n), false);
process->read_cb(process, pty_buf_init(buf->base, (size_t) n), false);

done:
free(buf->base);
Expand All @@ -76,24 +76,6 @@ static void write_cb(uv_write_t *req, int unused) {
free(req);
}

static pty_io_t *pty_io_init(pty_process *process, pty_read_cb read_cb) {
pty_io_t *io = xmalloc(sizeof(pty_io_t));
io->in = xmalloc(sizeof(uv_pipe_t));
io->out = xmalloc(sizeof(uv_pipe_t));
uv_pipe_init(process->loop, io->in, 0);
uv_pipe_init(process->loop, io->out, 0);
io->paused = true;
io->read_cb = read_cb;
io->ctx = process->ctx;
return io;
}

static void pty_io_free(pty_io_t *io) {
uv_close((uv_handle_t *) io->in, close_cb);
uv_close((uv_handle_t *) io->out, close_cb);
free(io);
}

pty_process *process_init(void *ctx, uv_loop_t *loop, char *argv[], char *envp[]) {
pty_process *process = xmalloc(sizeof(pty_process));
memset(process, 0, sizeof(pty_process));
Expand Down Expand Up @@ -123,7 +105,8 @@ void process_free(pty_process *process) {
#else
uv_thread_join(&process->tid);
#endif
if (process->io != NULL) pty_io_free(process->io);
if (process->in != NULL) uv_close((uv_handle_t *) process->in, close_cb);
if (process->out != NULL) uv_close((uv_handle_t *) process->out, close_cb);
if (process->argv != NULL) free(process->argv);
if (process->cwd != NULL) free(process->cwd);
char **p = process->envp;
Expand All @@ -134,29 +117,26 @@ void process_free(pty_process *process) {

void pty_pause(pty_process *process) {
if (process == NULL) return;
pty_io_t *io = process->io;
if (io->paused) return;
uv_read_stop((uv_stream_t *) io->out);
if (process->paused) return;
uv_read_stop((uv_stream_t *) process->out);
}

void pty_resume(pty_process *process) {
if (process == NULL) return;
pty_io_t *io = process->io;
if (!io->paused) return;
io->out->data = io;
uv_read_start((uv_stream_t *) io->out, alloc_cb, read_cb);
if (!process->paused) return;
process->out->data = process;
uv_read_start((uv_stream_t *) process->out, alloc_cb, read_cb);
}

int pty_write(pty_process *process, pty_buf_t *buf) {
if (process == NULL) {
pty_buf_free(buf);
return UV_ESRCH;
}
pty_io_t *io = process->io;
uv_buf_t b = uv_buf_init(buf->base, buf->len);
uv_write_t *req = xmalloc(sizeof(uv_write_t));
req->data = buf;
return uv_write(req, (uv_stream_t *) io->in, &b, 1, write_cb);
return uv_write(req, (uv_stream_t *) process->in, &b, 1, write_cb);
}

bool pty_resize(pty_process *process) {
Expand Down Expand Up @@ -324,7 +304,7 @@ static void async_cb(uv_async_t *async) {
GetExitCodeProcess(process->handle, &exit_code);
process->exit_code = (int) exit_code;
process->exit_signal = 1;
process->exit_cb(process->ctx, process);
process->exit_cb(process);

uv_close((uv_handle_t *) async, NULL);
process_free(process);
Expand All @@ -341,12 +321,15 @@ int pty_spawn(pty_process *process, pty_read_cb read_cb, pty_exit_cb exit_cb) {
SetConsoleCtrlHandler(NULL, FALSE);

int status = 1;
pty_io_t *io = pty_io_init(process, read_cb);
process->in = xmalloc(sizeof(uv_pipe_t));
process->out = xmalloc(sizeof(uv_pipe_t));
uv_pipe_init(process->loop, process->in, 0);
uv_pipe_init(process->loop, process->out, 0);

uv_connect_t *in_req = xmalloc(sizeof(uv_connect_t));
uv_connect_t *out_req = xmalloc(sizeof(uv_connect_t));
uv_pipe_connect(in_req, io->in, in_name, connect_cb);
uv_pipe_connect(out_req, io->out, out_name, connect_cb);
uv_pipe_connect(in_req, process->in, in_name, connect_cb);
uv_pipe_connect(out_req, process->out, out_name, connect_cb);

PROCESS_INFORMATION pi = {0};
WCHAR *cmdline, *cwd;
Expand All @@ -373,14 +356,14 @@ int pty_spawn(pty_process *process, pty_read_cb read_cb, pty_exit_cb exit_cb) {

process->pid = pi.dwProcessId;
process->handle = pi.hProcess;
process->io = io;
process->paused = true;
process->read_cb = read_cb;
process->exit_cb = exit_cb;
process->async.data = process;
uv_async_init(process->loop, &process->async, async_cb);

if (!RegisterWaitForSingleObject(&process->wait, pi.hProcess, conpty_exit, process, INFINITE, WT_EXECUTEONLYONCE)) {
print_error("RegisterWaitForSingleObject");
pty_io_free(io);
goto cleanup;
}

Expand Down Expand Up @@ -434,7 +417,7 @@ static void wait_cb(void *arg) {

static void async_cb(uv_async_t *async) {
pty_process *process = (pty_process *) async->data;
process->exit_cb(process->ctx, process);
process->exit_cb(process);

uv_close((uv_handle_t *) async, NULL);
process_free(process);
Expand Down Expand Up @@ -479,16 +462,20 @@ int pty_spawn(pty_process *process, pty_read_cb read_cb, pty_exit_cb exit_cb) {
goto error;
}

pty_io_t *io = pty_io_init(process, read_cb);
if (!fd_duplicate(master, io->in) || !fd_duplicate(master, io->out)) {
process->in = xmalloc(sizeof(uv_pipe_t));
process->out = xmalloc(sizeof(uv_pipe_t));
uv_pipe_init(process->loop, process->in, 0);
uv_pipe_init(process->loop, process->out, 0);

if (!fd_duplicate(master, process->in) || !fd_duplicate(master, process->out)) {
status = -errno;
pty_io_free(io);
goto error;
}

process->pty = master;
process->pid = pid;
process->io = io;
process->paused = true;
process->read_cb = read_cb;
process->exit_cb = exit_cb;
process->async.data = process;
uv_async_init(process->loop, &process->async, async_cb);
Expand Down
20 changes: 7 additions & 13 deletions src/pty.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,10 @@ typedef struct {
size_t len;
} pty_buf_t;

typedef void (*pty_read_cb)(void *, pty_buf_t *, bool);

typedef struct {
uv_pipe_t *in;
uv_pipe_t *out;
bool paused;

pty_read_cb read_cb;
void *ctx;
} pty_io_t;

struct pty_process_;
typedef struct pty_process_ pty_process;
typedef void (*pty_exit_cb)(void *, pty_process *);
typedef void (*pty_read_cb)(pty_process *, pty_buf_t *, bool);
typedef void (*pty_exit_cb)(pty_process *);

struct pty_process_ {
int pid, exit_code, exit_signal;
Expand All @@ -55,7 +45,11 @@ struct pty_process_ {

uv_loop_t *loop;
uv_async_t async;
pty_io_t *io;
uv_pipe_t *in;
uv_pipe_t *out;
bool paused;

pty_read_cb read_cb;
pty_exit_cb exit_cb;
void *ctx;
};
Expand Down

0 comments on commit d7db637

Please sign in to comment.