From 0c95114f32fda5eca4d9c37822ae8ba6e5960c54 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Mon, 21 Jan 2019 13:52:56 +0100 Subject: [PATCH] logger: fix data corruption for listening sockets The sockets are of the type SOCK_STREAM which can receive data in chunks. This is quite unlikely due to small data sizes but is not impossible. Change-Id: I5efa42c52c58fcd913eb882a77641f595fc99e9e Signed-off-by: Michal Bloch --- src/logger/logger.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/logger/logger.c b/src/logger/logger.c index ddf8507..e7126f0 100644 --- a/src/logger/logger.c +++ b/src/logger/logger.c @@ -1504,17 +1504,18 @@ static int service_writer_socket(struct logger* server, struct writer* wr, struc if (r > 0) wr->readed += r; - if (wr->readed < sizeof(msg->length)) - continue; - - if (wr->readed < msg->length) - continue; + /* The socket is SOCK_STREAM (see `listen_fd_create`), so one message + * could be split into chunks returned across multiple read() calls. */ + if (wr->readed < sizeof(msg->length) + || wr->readed < msg->length) + goto dont_process_yet_and_read_more_data; assert(wr->service_socket); r = wr->service_socket(server, wr, msg); if (r <= 0) return r; +dont_process_yet_and_read_more_data: r = read(wr->fd_entity.fd, wr->buffer + wr->readed, sizeof wr->buffer - wr->readed); } while (r > 0 || ((wr->readed >= sizeof(msg->length) && wr->readed >= msg->length))); -- 2.7.4