diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-07-08 13:59:04 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-07-08 13:59:38 +0200 |
commit | cb0804a5f0ea650a8ab4068058801d7f17917294 (patch) | |
tree | bbfc3fc3d8e3bdda9f4dfc0388e20528f1d6cc3e /src/netlink.c | |
parent | 87b809b88e1bf41a9c142d22a6e29f08d992ca41 (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.c | 15 |
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] && |