From 4fdae6c8479f6c1a256bc95099cae2fdc23e9256 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 19 Sep 2015 00:47:08 +0200 Subject: util: minor cleanups for loop_read() and friends When 0 bytes are to be written, make sure to go into read() at least once, in order to validate the parameters, such as the passed fd. Return error on huge values, add a couple of asserts and casts where appropriate. --- src/basic/util.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/basic/util.c b/src/basic/util.c index 0c3ef2a68c..368b556229 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -2144,7 +2144,13 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { assert(fd >= 0); assert(buf); - while (nbytes > 0) { + /* If called with nbytes == 0, let's call read() at least + * once, to validate the operation */ + + if (nbytes > (size_t) SSIZE_MAX) + return -EINVAL; + + do { ssize_t k; k = read(fd, p, nbytes); @@ -2158,7 +2164,7 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { * and expect that any error/EOF is reported * via read() */ - fd_wait_for_event(fd, POLLIN, USEC_INFINITY); + (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY); continue; } @@ -2168,10 +2174,12 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { if (k == 0) return n; + assert((size_t) k <= nbytes); + p += k; nbytes -= k; n += k; - } + } while (nbytes > 0); return n; } @@ -2181,9 +2189,10 @@ int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) { n = loop_read(fd, buf, nbytes, do_poll); if (n < 0) - return n; + return (int) n; if ((size_t) n != nbytes) return -EIO; + return 0; } @@ -2193,7 +2202,8 @@ int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { assert(fd >= 0); assert(buf); - errno = 0; + if (nbytes > (size_t) SSIZE_MAX) + return -EINVAL; do { ssize_t k; @@ -2208,16 +2218,18 @@ int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { * and expect that any error/EOF is reported * via write() */ - fd_wait_for_event(fd, POLLOUT, USEC_INFINITY); + (void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY); continue; } return -errno; } - if (nbytes > 0 && k == 0) /* Can't really happen */ + if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */ return -EIO; + assert((size_t) k <= nbytes); + p += k; nbytes -= k; } while (nbytes > 0); -- cgit v1.2.3-54-g00ecf