diff options
| author | Roy Marples <roy@marples.name> | 2020-08-04 03:49:11 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2020-08-04 03:49:11 +0100 |
| commit | 7e0666e2059b66927d5144a20f0846bb4db54ab5 (patch) | |
| tree | 3a81e4e530373dbf9ab505eabf19d0d9a7dd8b5e | |
| parent | 9851e0a9a411afa60fd14c14dca6db4f150669de (diff) | |
| download | dhcpcd-ui-7e0666e2059b66927d5144a20f0846bb4db54ab5.tar.xz | |
libdhcpcd: harden reading of dhcpcd socket
Matches recent dhcpcd internal socket behaviour.
| -rw-r--r-- | src/dhcpcd-online/Makefile | 2 | ||||
| -rw-r--r-- | src/libdhcpcd/dhcpcd.c | 25 |
2 files changed, 19 insertions, 8 deletions
diff --git a/src/dhcpcd-online/Makefile b/src/dhcpcd-online/Makefile index a7875b5..c324e65 100644 --- a/src/dhcpcd-online/Makefile +++ b/src/dhcpcd-online/Makefile @@ -17,6 +17,8 @@ CLEANFILES+= ${FILES} .SUFFIXES: .in +.PHONY: dhcpcd-online + .in: ${SED} -e 's:@BINDIR@:${BINDIR}:g' $< > $@ diff --git a/src/libdhcpcd/dhcpcd.c b/src/libdhcpcd/dhcpcd.c index f8f558b..f1d663f 100644 --- a/src/libdhcpcd/dhcpcd.c +++ b/src/libdhcpcd/dhcpcd.c @@ -155,6 +155,7 @@ dhcpcd_command_fd(DHCPCD_CONNECTION *con, buf[len - 1] = '\0'; } else buf[len - 1] = '\0'; + if (write(fd, buf, len) == -1) return -1; if (buffer == NULL) @@ -892,17 +893,16 @@ dhcpcd_new_if(DHCPCD_CONNECTION *con, char *data, size_t len) static DHCPCD_IF * dhcpcd_read_if(DHCPCD_CONNECTION *con, int fd) { - char sbuf[sizeof(size_t)], *rbuf; + char *rbuf, *rbufp; size_t len; ssize_t bytes; DHCPCD_IF *i; - bytes = read(fd, sbuf, sizeof(sbuf)); + bytes = read(fd, &len, sizeof(len)); if (bytes == 0 || bytes == -1) { dhcpcd_close(con); return NULL; } - memcpy(&len, sbuf, sizeof(len)); if (len >= SSIZE_MAX) { /* Even this is probably too big! */ errno = ENOBUFS; @@ -911,20 +911,27 @@ dhcpcd_read_if(DHCPCD_CONNECTION *con, int fd) rbuf = malloc(len + 1); if (rbuf == NULL) return NULL; - bytes = read(fd, rbuf, len); + rbufp = rbuf; +again: + bytes = read(fd, rbufp, len); if (bytes == 0 || bytes == -1) { free(rbuf); dhcpcd_close(con); return NULL; } + if ((size_t)bytes < len) { + rbufp += bytes; + len -= (size_t)bytes; + goto again; + } if ((size_t)bytes != len) { free(rbuf); errno = EINVAL; return NULL; } - rbuf[bytes] = '\0'; + rbufp[bytes] = '\0'; - i = dhcpcd_new_if(con, rbuf, len); + i = dhcpcd_new_if(con, rbuf, (size_t)((rbufp - rbuf) + bytes)); if (i == NULL) free(rbuf); return i; @@ -1063,8 +1070,10 @@ dhcpcd_open(DHCPCD_CONNECTION *con, bool privileged) memcpy(&nifs, cmd, sizeof(nifs)); /* We don't dispatch each interface here as that * causes too much notification spam when the GUI starts */ - for (n = 0; n < nifs; n++) - dhcpcd_read_if(con, con->command_fd); + for (n = 0; n < nifs; n++) { + if (dhcpcd_read_if(con, con->command_fd) == NULL) + goto err_exit; + } update_status(con, DHC_UNKNOWN); |
