Skip to content

Commit 9cf80d2

Browse files
committed
io UPDATE add chunk size limits and checks
Refs #574
1 parent 3536626 commit 9cf80d2

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

src/io.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ nc_read_until(struct nc_session *session, const char *endtag, uint32_t inact_tim
190190
char **buf, uint32_t *buf_size)
191191
{
192192
char *local_buf = NULL;
193-
int r, len, i, matched = 0, count = 0;
194-
uint32_t local_size = 0;
193+
ssize_t r;
194+
uint32_t len, i, matched = 0, count = 0, local_size = 0;
195195

196196
assert(session);
197197
assert(endtag);
@@ -204,7 +204,7 @@ nc_read_until(struct nc_session *session, const char *endtag, uint32_t inact_tim
204204
len = strlen(endtag);
205205
do {
206206
/* resize buffer if needed */
207-
if ((count + (len - matched)) > (signed)*buf_size) {
207+
if ((count + (len - matched)) > *buf_size) {
208208
*buf_size += NC_READ_BUF_SIZE_STEP;
209209
*buf = nc_realloc(*buf, (*buf_size + 1) * sizeof **buf);
210210
NC_CHECK_ERRMEM_GOTO(!*buf, count = -1, cleanup);
@@ -243,9 +243,9 @@ nc_read_until(struct nc_session *session, const char *endtag, uint32_t inact_tim
243243
int
244244
nc_read_msg_io(struct nc_session *session, int io_timeout, int passing_io_lock, char **buf, uint32_t *buf_len)
245245
{
246-
int ret = -1, r, io_locked = 0, chunk_len, buf_used = 0;
246+
int ret = -1, r, io_locked = 0;
247247
char *frame_size_buf = NULL;
248-
uint32_t inact_timeout, frame_buf_len;
248+
uint32_t inact_timeout, frame_buf_len, chunk_len, buf_used = 0;
249249
struct timespec ts_act_timeout;
250250

251251
assert(session && buf && buf_len);
@@ -314,13 +314,21 @@ nc_read_msg_io(struct nc_session *session, int io_timeout, int passing_io_lock,
314314
/* convert string to the size of the following chunk */
315315
chunk_len = strtoul(frame_size_buf, NULL, 10);
316316
if (!chunk_len) {
317-
ERR(session, "Invalid frame chunk size detected, fatal error.");
317+
ERR(session, "Invalid frame chunk size, fatal error.");
318+
ret = -2;
319+
goto cleanup;
320+
} else if (chunk_len > NC_READ_CHUNK_SIZE_MAX) {
321+
ERR(session, "Maximum frame chunk size %" PRIu32 " B exceeded.", (uint32_t)NC_READ_CHUNK_SIZE_MAX);
318322
ret = -2;
319323
goto cleanup;
320324
}
321325

322326
/* now we have size of next chunk, prepare a buffer large enough */
323-
if ((signed)*buf_len < buf_used + chunk_len + 1) {
327+
if (UINT32_MAX - buf_used < chunk_len + 1) {
328+
ERR(session, "Maximum supported message size %" PRIu32 " B exceeded.", UINT32_MAX);
329+
ret = -2;
330+
goto cleanup;
331+
} else if (*buf_len < buf_used + chunk_len + 1) {
324332
*buf_len = buf_used + chunk_len + 1;
325333
*buf = nc_realloc(*buf, *buf_len);
326334
NC_CHECK_ERRMEM_GOTO(!*buf, ret = -1, cleanup);

src/session_p.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,15 @@ extern struct nc_server_opts server_opts;
4747
#define NC_READ_BUF_SIZE_STEP 512
4848

4949
/**
50-
* Maximum size of a framing message chunk (spec max is 2^32 - 1).
50+
* Maximum size of a written framing message chunk (spec max is 2^32 - 1).
5151
*/
5252
#define NC_WRITE_CHUNK_SIZE_MAX 1024 * 10
5353

54+
/**
55+
* Maximum size of a read framing message chunk.
56+
*/
57+
#define NC_READ_CHUNK_SIZE_MAX 1024 * 1024 * 10
58+
5459
/**
5560
* Sleep time in usec to wait between nc_recv_notif() calls.
5661
*/

0 commit comments

Comments
 (0)