aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Łyszczek <michal.lyszczek@bofc.pl>2018-09-27 00:14:11 +0200
committerMichał Łyszczek <michal.lyszczek@bofc.pl>2018-09-27 00:20:32 +0200
commit1bfd182d9916f912d68531e1c9d4ecabc0dadf8e (patch)
treee64b69d1c262a4a6762b5da1190fd70cb29fe102
parent886270ba9264a60dc0d37ee48e49c99bd0e022bf (diff)
downloadlibrb-1bfd182d9916f912d68531e1c9d4ecabc0dadf8e.tar.gz
librb-1bfd182d9916f912d68531e1c9d4ecabc0dadf8e.tar.bz2
librb-1bfd182d9916f912d68531e1c9d4ecabc0dadf8e.zip
add: protection against overflow in read/write
-rw-r--r--man/rb_read.333
-rw-r--r--man/rb_write.321
-rw-r--r--rb.c41
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.
diff --git a/rb.c b/rb.c
index a16c7ec..aa0ef4c 100644
--- a/rb.c
+++ b/rb.c
@@ -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)