diff options
author | Michał Łyszczek <michal.lyszczek@bofc.pl> | 2018-09-27 00:14:11 +0200 |
---|---|---|
committer | Michał Łyszczek <michal.lyszczek@bofc.pl> | 2018-09-27 00:20:32 +0200 |
commit | 1bfd182d9916f912d68531e1c9d4ecabc0dadf8e (patch) | |
tree | e64b69d1c262a4a6762b5da1190fd70cb29fe102 | |
parent | 886270ba9264a60dc0d37ee48e49c99bd0e022bf (diff) | |
download | librb-1bfd182d9916f912d68531e1c9d4ecabc0dadf8e.tar.gz librb-1bfd182d9916f912d68531e1c9d4ecabc0dadf8e.tar.bz2 librb-1bfd182d9916f912d68531e1c9d4ecabc0dadf8e.zip |
add: protection against overflow in read/write
-rw-r--r-- | man/rb_read.3 | 33 | ||||
-rw-r--r-- | man/rb_write.3 | 21 | ||||
-rw-r--r-- | rb.c | 41 |
3 files changed, 92 insertions, 3 deletions
diff --git a/man/rb_read.3 b/man/rb_read.3 index 4fe2797..1568d5d 100644 --- a/man/rb_read.3 +++ b/man/rb_read.3 @@ -55,6 +55,27 @@ number than call it in a loop with .I count == 1. .PP +Altough +.I count +is of +.B size_t +type, functions will not read more than +.B LONG_MAX +elements. +If +.I count +is bigger than +.B LONG_MAX +it will be set to +.B LONG_MAX +internaly anyway. +Also make sure that formula +.IR count * rb->object_size +does not exceed +.B size_t +type or you will overflow internal integer and that will result in Undefined +Behaviour. +.PP By default buffer works in single-threaded mode. In this mode all calls on .I rb @@ -259,11 +280,17 @@ Reading frames by multiple parsers. Error handling ommited for clarity. * NOTE: rb will now be locked from writing, only * this thread will be able to write to rb, don't * try to call another rb_write() function, it will - * be blocked until this function return (SIZE_MAX - * bytes have been read from fd) or error occurs + * be blocked until this function returns - and it + * may take a while to read LONG_MAX / OBJECT_SIZE. + * + * LONG_MAX / OBJECT_SIZE is passed as count because + * we want this function to be called as rarely as + * possible, and still we don't want to overflow + * internal integer. OBJECT_SIZE is size of a single + * rb object set during creation of rb */ - if (rb_fd_write(rb, fd, SIZE_MAX) == -1) + if (rb_fd_write(rb, fd, LONG_MAX / OBJECT_SIZE) == -1) { if (errno == ECANCELED) { diff --git a/man/rb_write.3 b/man/rb_write.3 index a052013..2c87ca4 100644 --- a/man/rb_write.3 +++ b/man/rb_write.3 @@ -58,6 +58,27 @@ number instead of calling it in a loop with .I count == 1. .PP +Altough +.I count +is of +.B size_t +type, functions will not write more than +.B LONG_MAX +elements. +If +.I count +is bigger than +.B LONG_MAX +it will be set to +.B LONG_MAX +internaly anyway. +Also make sure that formula +.IR count * rb->object_size +does not exceed +.B size_t +type or you will overflow internal integer and that will result in Undefined +Behaviour. +.PP By default .B rb works in single-threaded mode. @@ -53,6 +53,7 @@ #endif /* HAVE_ASSERT_H */ #include <errno.h> +#include <limits.h> #include <stddef.h> #include <stdlib.h> #include <string.h> @@ -2056,6 +2057,16 @@ long rb_recv VALID(EINVAL, buffer); VALID(EINVAL, rb->buffer); + if (count > (size_t)LONG_MAX) + { + /* + * function cannot read more than LONG_MAX count of elements, trim + * users count to acceptable value + */ + + count = LONG_MAX; + } + #if ENABLE_THREADS if ((rb->flags & O_MULTITHREAD) == 0) { @@ -2133,6 +2144,16 @@ long rb_posix_recv VALID(EINVAL, rb->buffer); VALID(EINVAL, fd >= 0); + if (count > (size_t)LONG_MAX) + { + /* + * function cannot read more than LONG_MAX count of elements, trim + * users count to acceptable value + */ + + count = LONG_MAX; + } + # if ENABLE_THREADS if ((rb->flags & O_MULTITHREAD) == 0) @@ -2233,6 +2254,16 @@ long rb_send VALID(EINVAL, buffer); VALID(EINVAL, rb->buffer); + if (count > (size_t)LONG_MAX) + { + /* + * function cannot read more than LONG_MAX count of elements, trim + * users count to acceptable value + */ + + count = LONG_MAX; + } + #if ENABLE_THREADS if ((rb->flags & O_MULTITHREAD) == 0) { @@ -2294,6 +2325,16 @@ long rb_posix_send VALID(EINVAL, rb->buffer); VALID(EINVAL, fd >= 0); + if (count > (size_t)LONG_MAX) + { + /* + * function cannot read more than LONG_MAX count of elements, trim + * users count to acceptable value + */ + + count = LONG_MAX; + } + # if ENABLE_THREADS if ((rb->flags & O_MULTITHREAD) == 0) |