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 | |
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')
-rw-r--r-- | src/netlink.c | 15 | ||||
-rw-r--r-- | src/uapi/wireguard.h | 6 |
2 files changed, 16 insertions, 5 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] && diff --git a/src/uapi/wireguard.h b/src/uapi/wireguard.h index 912f216..5a3e5a7 100644 --- a/src/uapi/wireguard.h +++ b/src/uapi/wireguard.h @@ -142,7 +142,8 @@ enum wg_cmd { #define WG_CMD_MAX (__WG_CMD_MAX - 1) enum wgdevice_flag { - WGDEVICE_F_REPLACE_PEERS = 1U << 0 + WGDEVICE_F_REPLACE_PEERS = 1U << 0, + __WGDEVICE_F_ALL = WGDEVICE_F_REPLACE_PEERS }; enum wgdevice_attribute { WGDEVICE_A_UNSPEC, @@ -160,7 +161,8 @@ enum wgdevice_attribute { enum wgpeer_flag { WGPEER_F_REMOVE_ME = 1U << 0, - WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1 + WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1, + __WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS }; enum wgpeer_attribute { WGPEER_A_UNSPEC, |