diff options
author | Andy Wingo <wingo@pobox.com> | 2017-02-08 15:05:03 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2017-02-08 15:09:14 +0100 |
commit | 09a69dd712536350b4b8feec8cdec3dc49cb71d5 (patch) | |
tree | ecf2fd427208fee72efbc0e47ca2da863eee3ba2 /libguile/filesys.c | |
parent | 8a4774dec8368def01af4126e77797468b0ce6de (diff) | |
download | guile-09a69dd712536350b4b8feec8cdec3dc49cb71d5.tar.gz |
Prevent TOCTTOU bugs in C ports
* libguile/ports-internal.h (scm_port_buffer_can_take):
(scm_port_buffer_can_put): Add cur/end output arguments so that when a
caller asks the buffer room, it can be relative to a fixed point in
the buffer and not whatever point it's at when we go to fill it.
(scm_port_buffer_did_take, scm_port_buffer_did_put): Similarly,
require that the caller knows where they took/put data in the buffer.
Prevents overflow.
(scm_port_buffer_take_pointer, scm_port_buffer_put_pointer): Likewise,
require that the caller has already checked and knows a position in
the buffer and therefore how much data is available.
(scm_port_buffer_take, scm_port_buffer_put, scm_port_buffer_putback):
Adapt.
* libguile/ports.h (scm_fill_input): Add cur/avail output arguments.
* libguile/filesys.c:
* libguile/poll.c:
* libguile/ports.c:
* libguile/r6rs-ports.c:
* libguile/read.c:
* libguile/rw.c: Adapt all callers. Gnarly work!
Diffstat (limited to 'libguile/filesys.c')
-rw-r--r-- | libguile/filesys.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/libguile/filesys.c b/libguile/filesys.c index ae164fe83..9f665c107 100644 --- a/libguile/filesys.c +++ b/libguile/filesys.c @@ -647,20 +647,21 @@ set_element (fd_set *set, SCM *ports_ready, SCM element, int pos) else { int use_buf = 0; + size_t cur; element = SCM_COERCE_OUTPORT (element); SCM_ASSERT (SCM_OPFPORTP (element), element, pos, "select"); if (pos == SCM_ARG1) { /* Check whether port has input buffered. */ - if (scm_port_buffer_can_take (SCM_PORT (element)->read_buf) > 0) + if (scm_port_buffer_can_take (SCM_PORT (element)->read_buf, &cur) > 0) use_buf = 1; } else if (pos == SCM_ARG2) { /* Check whether port's output buffer has room. > 1 since writing the last byte in the buffer causes flush. */ - if (scm_port_buffer_can_put (SCM_PORT (element)->write_buf) > 1) + if (scm_port_buffer_can_put (SCM_PORT (element)->write_buf, &cur) > 1) use_buf = 1; } fd = use_buf ? -1 : SCM_FPORT_FDES (element); |