From c903f49249a2b5fa8fc92c4021347c894d771dc7 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 8 Jul 2019 13:59:04 +0200 Subject: netlink: enforce that unused bits of flags are zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Toke Høiland-Jørgensen --- src/netlink.c | 15 ++++++++++++--- 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, -- cgit v1.2.3-59-g8ed1b