diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-09-19 00:47:08 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-09-22 16:30:51 +0200 |
commit | 4fdae6c8479f6c1a256bc95099cae2fdc23e9256 (patch) | |
tree | 5698cab1dbf361ad17f6eae065bb8092bc14358e /src/basic | |
parent | 1fc464f6fbecfc5d8ba9f7b98d19e21fb324bfb9 (diff) |
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.
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/util.c | 26 |
1 files changed, 19 insertions, 7 deletions
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); |