1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-18 17:50:29 +02:00

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!
This commit is contained in:
Andy Wingo 2017-02-08 15:05:03 +01:00
parent 8a4774dec8
commit 09a69dd712
8 changed files with 251 additions and 176 deletions

View file

@ -2080,7 +2080,7 @@ scm_i_scan_for_encoding (SCM port)
scm_t_port *pt;
SCM buf;
char header[SCM_ENCODING_SEARCH_SIZE+1];
size_t bytes_read, encoding_length, i;
size_t cur, bytes_read, encoding_length, i;
char *encoding = NULL;
char *pos, *encoding_start;
int in_comment;
@ -2091,11 +2091,10 @@ scm_i_scan_for_encoding (SCM port)
if (pt->rw_random)
scm_flush (port);
if (scm_port_buffer_can_take (buf) == 0)
if (scm_port_buffer_can_take (buf, &cur) == 0)
{
/* We can use the read buffer, and thus avoid a seek. */
buf = scm_fill_input (port, 0);
bytes_read = scm_port_buffer_can_take (buf);
buf = scm_fill_input (port, 0, &cur, &bytes_read);
if (bytes_read > SCM_ENCODING_SEARCH_SIZE)
bytes_read = SCM_ENCODING_SEARCH_SIZE;
@ -2103,7 +2102,7 @@ scm_i_scan_for_encoding (SCM port)
/* An unbuffered port -- don't scan. */
return NULL;
memcpy (header, scm_port_buffer_take_pointer (buf), bytes_read);
memcpy (header, scm_port_buffer_take_pointer (buf, cur), bytes_read);
header[bytes_read] = '\0';
}
else