diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2018-12-15 23:56:07 +0100 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2019-02-28 00:46:04 +0100 |
commit | c9ed80d46ef714dd15626a4a4e98468e154e473f (patch) | |
tree | 0139fbec82d255a48539823f912a1d30df863896 | |
parent | 62763c769f59569de7d6e53968f1170b2bd0c239 (diff) |
wireguard: update library
-rw-r--r-- | sysdep/linux/wireguard.c | 55 | ||||
-rw-r--r-- | sysdep/linux/wireguard.h | 4 |
2 files changed, 32 insertions, 27 deletions
diff --git a/sysdep/linux/wireguard.c b/sysdep/linux/wireguard.c index a7135678..b8368e9f 100644 --- a/sysdep/linux/wireguard.c +++ b/sysdep/linux/wireguard.c @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: LGPL-2.1+ - * +// SPDX-License-Identifier: LGPL-2.1+ +/* * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2008-2012 Pablo Neira Ayuso <pablo@netfilter.org>. */ @@ -358,11 +358,15 @@ static void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, { struct nlattr *attr = mnl_nlmsg_get_payload_tail(nlh); uint16_t payload_len = MNL_ALIGN(sizeof(struct nlattr)) + len; + int pad; attr->nla_type = type; attr->nla_len = payload_len; memcpy(mnl_attr_get_payload(attr), data, len); nlh->nlmsg_len += MNL_ALIGN(payload_len); + pad = MNL_ALIGN(len) - len; + if (pad > 0) + memset(mnl_attr_get_payload(attr) + len, 0, pad); } static void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data) @@ -994,8 +998,15 @@ another: goto cleanup; } if ((len = mnl_cb_run(rtnl_buffer, len, seq, portid, read_devices_cb, buffer)) < 0) { - ret = -errno; - goto cleanup; + /* Netlink returns NLM_F_DUMP_INTR if the set of all tunnels changed + * during the dump. That's unfortunate, but is pretty common on busy + * systems that are adding and removing tunnels all the time. Rather + * than retrying, potentially indefinitely, we just work with the + * partial results. */ + if (errno != EINTR) { + ret = -errno; + goto cleanup; + } } if (len == MNL_CB_OK + 1) goto another; @@ -1070,7 +1081,6 @@ cleanup: int wg_set_device(wg_device *dev) { int ret = 0; - size_t i, j; wg_peer *peer = NULL; wg_allowedip *allowedip = NULL; struct nlattr *peers_nest, *peer_nest, *allowedips_nest, *allowedip_nest; @@ -1103,10 +1113,10 @@ again: goto send; peers_nest = peer_nest = allowedips_nest = allowedip_nest = NULL; peers_nest = mnl_attr_nest_start(nlh, WGDEVICE_A_PEERS); - for (i = 0, peer = peer ? peer : dev->first_peer; peer; peer = peer->next_peer) { + for (peer = peer ? peer : dev->first_peer; peer; peer = peer->next_peer) { uint32_t flags = 0; - peer_nest = mnl_attr_nest_start_check(nlh, MNL_SOCKET_BUFFER_SIZE, i++); + peer_nest = mnl_attr_nest_start_check(nlh, MNL_SOCKET_BUFFER_SIZE, 0); if (!peer_nest) goto toobig_peers; if (!mnl_attr_put_check(nlh, MNL_SOCKET_BUFFER_SIZE, WGPEER_A_PUBLIC_KEY, sizeof(peer->public_key), peer->public_key)) @@ -1142,8 +1152,8 @@ again: allowedips_nest = mnl_attr_nest_start_check(nlh, MNL_SOCKET_BUFFER_SIZE, WGPEER_A_ALLOWEDIPS); if (!allowedips_nest) goto toobig_allowedips; - for (j = 0; allowedip; allowedip = allowedip->next_allowedip) { - allowedip_nest = mnl_attr_nest_start_check(nlh, MNL_SOCKET_BUFFER_SIZE, j++); + for (; allowedip; allowedip = allowedip->next_allowedip) { + allowedip_nest = mnl_attr_nest_start_check(nlh, MNL_SOCKET_BUFFER_SIZE, 0); if (!allowedip_nest) goto toobig_allowedips; if (!mnl_attr_put_u16_check(nlh, MNL_SOCKET_BUFFER_SIZE, WGALLOWEDIP_A_FAMILY, allowedip->family)) @@ -1510,7 +1520,7 @@ void wg_free_device(wg_device *dev) free(dev); } -static void encode_base64(char dest[4], const uint8_t src[3]) +static void encode_base64(char dest[static 4], const uint8_t src[static 3]) { const uint8_t input[] = { (src[0] >> 2) & 63, ((src[0] << 4) | (src[1] >> 4)) & 63, ((src[1] << 2) | (src[2] >> 6)) & 63, src[2] & 63 }; unsigned int i; @@ -1535,7 +1545,7 @@ void wg_key_to_base64(wg_key_b64_string base64, const wg_key key) base64[sizeof(wg_key_b64_string) - 1] = '\0'; } -static int decode_base64(const char src[4]) +static int decode_base64(const char src[static 4]) { int val = 0; unsigned int i; @@ -1555,25 +1565,25 @@ int wg_key_from_base64(wg_key key, const wg_key_b64_string base64) { unsigned int i; int val; + volatile uint8_t ret = 0; - errno = EINVAL; - if (strlen(base64) != sizeof(wg_key_b64_string) - 1 || base64[sizeof(wg_key_b64_string) - 2] != '=') + if (strlen(base64) != sizeof(wg_key_b64_string) - 1 || base64[sizeof(wg_key_b64_string) - 2] != '=') { + errno = EINVAL; goto out; + } for (i = 0; i < 32 / 3; ++i) { val = decode_base64(&base64[i * 4]); - if (val < 0) - goto out; + ret |= (uint32_t)val >> 31; key[i * 3 + 0] = (val >> 16) & 0xff; key[i * 3 + 1] = (val >> 8) & 0xff; key[i * 3 + 2] = val & 0xff; } val = decode_base64((const char[]){ base64[i * 4 + 0], base64[i * 4 + 1], base64[i * 4 + 2], 'A' }); - if (val < 0 || val & 0xff) - goto out; + ret |= ((uint32_t)val >> 31) | (val & 0xff); key[i * 3 + 0] = (val >> 16) & 0xff; key[i * 3 + 1] = (val >> 8) & 0xff; - errno = 0; + errno = EINVAL & ~((ret - 1) >> 8); out: return -errno; } @@ -1589,16 +1599,11 @@ static __attribute__((noinline)) void memzero_explicit(void *s, size_t count) static void carry(fe o) { int i; - int64_t c; for (i = 0; i < 16; ++i) { - o[i] += (1LL << 16); - c = o[i] >> 16; - o[(i + 1) * (i < 15)] += c - 1 + 37 * (c - 1) * (i == 15); - o[i] -= c << 16; + o[(i + 1) % 16] += (i == 15 ? 38 : 1) * (o[i] >> 16); + o[i] &= 0xffff; } - - memzero_explicit(&c, sizeof(c)); } static void cswap(fe p, fe q, int b) diff --git a/sysdep/linux/wireguard.h b/sysdep/linux/wireguard.h index 53d9d5d7..e9210a41 100644 --- a/sysdep/linux/wireguard.h +++ b/sysdep/linux/wireguard.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: LGPL-2.1+ - * +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */ |