Skip to content

Commit d7db637

Browse files
committed
protocol: fix potential null pss access
1 parent b76c91e commit d7db637

File tree

3 files changed

+49
-67
lines changed

3 files changed

+49
-67
lines changed

src/protocol.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ static bool check_host_origin(struct lws *wsi) {
5151
char buf[256];
5252
memset(buf, 0, sizeof(buf));
5353
int len = lws_hdr_copy(wsi, buf, (int)sizeof(buf), WSI_TOKEN_ORIGIN);
54-
if (len <= 0) {
55-
return false;
56-
}
54+
if (len <= 0) return false;
5755

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

74-
static void process_read_cb(void *ctx, pty_buf_t *buf, bool eof) {
75-
struct pss_tty *pss = (struct pss_tty *)ctx;
72+
static void process_read_cb(pty_process *process, pty_buf_t *buf, bool eof) {
73+
if (process->killed) return ;
74+
75+
struct pss_tty *pss = (struct pss_tty *)process->ctx;
7676
if (eof && !process_running(pss->process))
7777
pss->lws_close_status = pss->process->exit_code == 0 ? 1000 : 1006;
7878
else
@@ -81,16 +81,17 @@ static void process_read_cb(void *ctx, pty_buf_t *buf, bool eof) {
8181
lws_callback_on_writable(pss->wsi);
8282
}
8383

84-
static void process_exit_cb(void *ctx, pty_process *process) {
85-
struct pss_tty *pss = (struct pss_tty *)ctx;
86-
pss->process = NULL;
84+
static void process_exit_cb(pty_process *process) {
8785
if (process->killed) {
8886
lwsl_notice("process killed with signal %d, pid: %d\n", process->exit_signal, process->pid);
89-
} else {
90-
lwsl_notice("process exited with code %d, pid: %d\n", process->exit_code, process->pid);
91-
pss->lws_close_status = process->exit_code == 0 ? 1000 : 1006;
92-
lws_callback_on_writable(pss->wsi);
87+
return ;
9388
}
89+
90+
lwsl_notice("process exited with code %d, pid: %d\n", process->exit_code, process->pid);
91+
struct pss_tty *pss = (struct pss_tty *)process->ctx;
92+
pss->process = NULL;
93+
pss->lws_close_status = process->exit_code == 0 ? 1000 : 1006;
94+
lws_callback_on_writable(pss->wsi);
9495
}
9596

9697
static char **build_args(struct pss_tty *pss) {

src/pty.c

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ void pty_buf_free(pty_buf_t *buf) {
5757

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

6969
done:
7070
free(buf->base);
@@ -76,24 +76,6 @@ static void write_cb(uv_write_t *req, int unused) {
7676
free(req);
7777
}
7878

79-
static pty_io_t *pty_io_init(pty_process *process, pty_read_cb read_cb) {
80-
pty_io_t *io = xmalloc(sizeof(pty_io_t));
81-
io->in = xmalloc(sizeof(uv_pipe_t));
82-
io->out = xmalloc(sizeof(uv_pipe_t));
83-
uv_pipe_init(process->loop, io->in, 0);
84-
uv_pipe_init(process->loop, io->out, 0);
85-
io->paused = true;
86-
io->read_cb = read_cb;
87-
io->ctx = process->ctx;
88-
return io;
89-
}
90-
91-
static void pty_io_free(pty_io_t *io) {
92-
uv_close((uv_handle_t *) io->in, close_cb);
93-
uv_close((uv_handle_t *) io->out, close_cb);
94-
free(io);
95-
}
96-
9779
pty_process *process_init(void *ctx, uv_loop_t *loop, char *argv[], char *envp[]) {
9880
pty_process *process = xmalloc(sizeof(pty_process));
9981
memset(process, 0, sizeof(pty_process));
@@ -123,7 +105,8 @@ void process_free(pty_process *process) {
123105
#else
124106
uv_thread_join(&process->tid);
125107
#endif
126-
if (process->io != NULL) pty_io_free(process->io);
108+
if (process->in != NULL) uv_close((uv_handle_t *) process->in, close_cb);
109+
if (process->out != NULL) uv_close((uv_handle_t *) process->out, close_cb);
127110
if (process->argv != NULL) free(process->argv);
128111
if (process->cwd != NULL) free(process->cwd);
129112
char **p = process->envp;
@@ -134,29 +117,26 @@ void process_free(pty_process *process) {
134117

135118
void pty_pause(pty_process *process) {
136119
if (process == NULL) return;
137-
pty_io_t *io = process->io;
138-
if (io->paused) return;
139-
uv_read_stop((uv_stream_t *) io->out);
120+
if (process->paused) return;
121+
uv_read_stop((uv_stream_t *) process->out);
140122
}
141123

142124
void pty_resume(pty_process *process) {
143125
if (process == NULL) return;
144-
pty_io_t *io = process->io;
145-
if (!io->paused) return;
146-
io->out->data = io;
147-
uv_read_start((uv_stream_t *) io->out, alloc_cb, read_cb);
126+
if (!process->paused) return;
127+
process->out->data = process;
128+
uv_read_start((uv_stream_t *) process->out, alloc_cb, read_cb);
148129
}
149130

150131
int pty_write(pty_process *process, pty_buf_t *buf) {
151132
if (process == NULL) {
152133
pty_buf_free(buf);
153134
return UV_ESRCH;
154135
}
155-
pty_io_t *io = process->io;
156136
uv_buf_t b = uv_buf_init(buf->base, buf->len);
157137
uv_write_t *req = xmalloc(sizeof(uv_write_t));
158138
req->data = buf;
159-
return uv_write(req, (uv_stream_t *) io->in, &b, 1, write_cb);
139+
return uv_write(req, (uv_stream_t *) process->in, &b, 1, write_cb);
160140
}
161141

162142
bool pty_resize(pty_process *process) {
@@ -324,7 +304,7 @@ static void async_cb(uv_async_t *async) {
324304
GetExitCodeProcess(process->handle, &exit_code);
325305
process->exit_code = (int) exit_code;
326306
process->exit_signal = 1;
327-
process->exit_cb(process->ctx, process);
307+
process->exit_cb(process);
328308

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

343323
int status = 1;
344-
pty_io_t *io = pty_io_init(process, read_cb);
324+
process->in = xmalloc(sizeof(uv_pipe_t));
325+
process->out = xmalloc(sizeof(uv_pipe_t));
326+
uv_pipe_init(process->loop, process->in, 0);
327+
uv_pipe_init(process->loop, process->out, 0);
345328

346329
uv_connect_t *in_req = xmalloc(sizeof(uv_connect_t));
347330
uv_connect_t *out_req = xmalloc(sizeof(uv_connect_t));
348-
uv_pipe_connect(in_req, io->in, in_name, connect_cb);
349-
uv_pipe_connect(out_req, io->out, out_name, connect_cb);
331+
uv_pipe_connect(in_req, process->in, in_name, connect_cb);
332+
uv_pipe_connect(out_req, process->out, out_name, connect_cb);
350333

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

374357
process->pid = pi.dwProcessId;
375358
process->handle = pi.hProcess;
376-
process->io = io;
359+
process->paused = true;
360+
process->read_cb = read_cb;
377361
process->exit_cb = exit_cb;
378362
process->async.data = process;
379363
uv_async_init(process->loop, &process->async, async_cb);
380364

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

@@ -434,7 +417,7 @@ static void wait_cb(void *arg) {
434417

435418
static void async_cb(uv_async_t *async) {
436419
pty_process *process = (pty_process *) async->data;
437-
process->exit_cb(process->ctx, process);
420+
process->exit_cb(process);
438421

439422
uv_close((uv_handle_t *) async, NULL);
440423
process_free(process);
@@ -479,16 +462,20 @@ int pty_spawn(pty_process *process, pty_read_cb read_cb, pty_exit_cb exit_cb) {
479462
goto error;
480463
}
481464

482-
pty_io_t *io = pty_io_init(process, read_cb);
483-
if (!fd_duplicate(master, io->in) || !fd_duplicate(master, io->out)) {
465+
process->in = xmalloc(sizeof(uv_pipe_t));
466+
process->out = xmalloc(sizeof(uv_pipe_t));
467+
uv_pipe_init(process->loop, process->in, 0);
468+
uv_pipe_init(process->loop, process->out, 0);
469+
470+
if (!fd_duplicate(master, process->in) || !fd_duplicate(master, process->out)) {
484471
status = -errno;
485-
pty_io_free(io);
486472
goto error;
487473
}
488474

489475
process->pty = master;
490476
process->pid = pid;
491-
process->io = io;
477+
process->paused = true;
478+
process->read_cb = read_cb;
492479
process->exit_cb = exit_cb;
493480
process->async.data = process;
494481
uv_async_init(process->loop, &process->async, async_cb);

src/pty.h

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,10 @@ typedef struct {
2121
size_t len;
2222
} pty_buf_t;
2323

24-
typedef void (*pty_read_cb)(void *, pty_buf_t *, bool);
25-
26-
typedef struct {
27-
uv_pipe_t *in;
28-
uv_pipe_t *out;
29-
bool paused;
30-
31-
pty_read_cb read_cb;
32-
void *ctx;
33-
} pty_io_t;
34-
3524
struct pty_process_;
3625
typedef struct pty_process_ pty_process;
37-
typedef void (*pty_exit_cb)(void *, pty_process *);
26+
typedef void (*pty_read_cb)(pty_process *, pty_buf_t *, bool);
27+
typedef void (*pty_exit_cb)(pty_process *);
3828

3929
struct pty_process_ {
4030
int pid, exit_code, exit_signal;
@@ -55,7 +45,11 @@ struct pty_process_ {
5545

5646
uv_loop_t *loop;
5747
uv_async_t async;
58-
pty_io_t *io;
48+
uv_pipe_t *in;
49+
uv_pipe_t *out;
50+
bool paused;
51+
52+
pty_read_cb read_cb;
5953
pty_exit_cb exit_cb;
6054
void *ctx;
6155
};

0 commit comments

Comments
 (0)