summaryrefslogtreecommitdiffhomepage
path: root/src/netlink.c
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-07-08 13:59:04 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-07-08 13:59:38 +0200
commitcb0804a5f0ea650a8ab4068058801d7f17917294 (patch)
treebbfc3fc3d8e3bdda9f4dfc0388e20528f1d6cc3e /src/netlink.c
parent87b809b88e1bf41a9c142d22a6e29f08d992ca41 (diff)
netlink: enforce that unused bits of flags are zero
Reported-by: Toke Høiland-Jørgensen <toke@toke.dk> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/netlink.c')
-rw-r--r--src/netlink.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/netlink.c b/src/netlink.c
index 6fa5ba7..a50eaa7 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -373,8 +373,12 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs)
if (attrs[WGPEER_A_PRESHARED_KEY] &&
nla_len(attrs[WGPEER_A_PRESHARED_KEY]) == NOISE_SYMMETRIC_KEY_LEN)
preshared_key = nla_data(attrs[WGPEER_A_PRESHARED_KEY]);
+
if (attrs[WGPEER_A_FLAGS])
flags = nla_get_u32(attrs[WGPEER_A_FLAGS]);
+ ret = -EOPNOTSUPP;
+ if (flags & ~__WGPEER_F_ALL)
+ goto out;
ret = -EPFNOSUPPORT;
if (attrs[WGPEER_A_PROTOCOL_VERSION]) {
@@ -492,6 +496,7 @@ out:
static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
{
struct wg_device *wg = lookup_interface(info->attrs, skb);
+ u32 flags = 0;
int ret;
if (IS_ERR(wg)) {
@@ -502,6 +507,12 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
rtnl_lock();
mutex_lock(&wg->device_update_lock);
+ if (info->attrs[WGDEVICE_A_FLAGS])
+ flags = nla_get_u32(info->attrs[WGDEVICE_A_FLAGS]);
+ ret = -EOPNOTSUPP;
+ if (flags & ~__WGDEVICE_F_ALL)
+ goto out;
+
ret = -EPERM;
if ((info->attrs[WGDEVICE_A_LISTEN_PORT] ||
info->attrs[WGDEVICE_A_FWMARK]) &&
@@ -525,9 +536,7 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
goto out;
}
- if (info->attrs[WGDEVICE_A_FLAGS] &&
- nla_get_u32(info->attrs[WGDEVICE_A_FLAGS]) &
- WGDEVICE_F_REPLACE_PEERS)
+ if (flags & WGDEVICE_F_REPLACE_PEERS)
wg_peer_remove_all(wg);
if (info->attrs[WGDEVICE_A_PRIVATE_KEY] &&