aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/ipc-uapi.h
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-01-27 15:22:20 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2021-01-27 15:22:20 +0100
commite8fa0f662f2541952e745d9c7fff0eeaec538a5c (patch)
tree22c15d9eb53fdfef9d28a586b822ea188d1cbb97 /src/ipc-uapi.h
parentman: LOG_LEVEL variables changed nae (diff)
downloadwireguard-tools-e8fa0f662f2541952e745d9c7fff0eeaec538a5c.tar.xz
wireguard-tools-e8fa0f662f2541952e745d9c7fff0eeaec538a5c.zip
ipc: read trailing responses after set operation
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to '')
-rw-r--r--src/ipc-uapi.h33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/ipc-uapi.h b/src/ipc-uapi.h
index d2ba522..f582916 100644
--- a/src/ipc-uapi.h
+++ b/src/ipc-uapi.h
@@ -5,6 +5,7 @@
#include <arpa/inet.h>
#include <errno.h>
+#include <limits.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
@@ -30,8 +31,10 @@ static int userspace_set_device(struct wgdevice *dev)
struct wgpeer *peer;
struct wgallowedip *allowedip;
FILE *f;
- int ret;
+ int ret, set_errno = -EPROTO;
socklen_t addr_len;
+ size_t line_buffer_len = 0, line_len;
+ char *key = NULL, *value;
f = userspace_interface_file(dev->name);
if (!f)
@@ -92,10 +95,30 @@ static int userspace_set_device(struct wgdevice *dev)
fprintf(f, "\n");
fflush(f);
- if (fscanf(f, "errno=%d", &ret) != 1)
- ret = errno ? -errno : -EPROTO;
- if (getc(f) != '\n' || getc(f) != '\n')
- ret = -EPROTO;
+ while (getline(&key, &line_buffer_len, f) > 0) {
+ line_len = strlen(key);
+ ret = set_errno;
+ if (line_len == 1 && key[0] == '\n')
+ goto out;
+ value = strchr(key, '=');
+ if (!value || line_len == 0 || key[line_len - 1] != '\n')
+ break;
+ *value++ = key[--line_len] = '\0';
+
+ if (!strcmp(key, "errno")) {
+ long long num;
+ char *end;
+ if (value[0] != '-' && !char_is_digit(value[0]))
+ break;
+ num = strtoll(value, &end, 10);
+ if (*end || num > INT_MAX || num < INT_MIN)
+ break;
+ set_errno = num;
+ }
+ }
+ ret = errno ? -errno : -EPROTO;
+out:
+ free(key);
fclose(f);
errno = -ret;
return ret;