diff --git a/net/wireguard/compat/compat.h b/net/wireguard/compat/compat.h index fde263ce2606..9f6e725db531 100644 --- a/net/wireguard/compat/compat.h +++ b/net/wireguard/compat/compat.h @@ -37,9 +37,6 @@ #define ISUBUNTU1910 #endif #endif -#if defined(CONFIG_SUSE_KERNEL) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) -#define ISOPENSUSE151 -#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) #error "WireGuard requires Linux >= 3.10" @@ -287,7 +284,7 @@ static const struct in6_addr __compat_in6addr_any = IN6ADDR_ANY_INIT; #define in6addr_any __compat_in6addr_any #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) && !defined(ISOPENSUSE151) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) #include #include #include @@ -383,7 +380,7 @@ static inline bool rng_is_initialized(void) } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) && !defined(ISOPENSUSE151) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) static inline int get_random_bytes_wait(void *buf, int nbytes) { int ret = wait_for_random_bytes(); @@ -526,7 +523,7 @@ static inline void __compat_kvfree(const void *addr) #define priv_destructor destructor #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) && !defined(ISOPENSUSE151) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) #define wg_newlink(a,b,c,d,e) wg_newlink(a,b,c,d) #endif @@ -665,12 +662,12 @@ struct __compat_dummy_container { char dev; }; #define COMPAT_CANNOT_USE_AVX512 #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) && !defined(ISOPENSUSE151) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) #include #define genl_dump_check_consistent(a, b) genl_dump_check_consistent(a, b, &genl_family) #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) && !defined(ISRHEL7) && !defined(ISOPENSUSE151) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) && !defined(ISRHEL7) static inline void *skb_put_data(struct sk_buff *skb, const void *data, unsigned int len) { void *tmp = skb_put(skb, len); @@ -727,7 +724,7 @@ static inline void cpu_to_le32_array(u32 *buf, unsigned int words) } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) && !defined(ISOPENSUSE151) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) #include static inline void crypto_xor_cpy(u8 *dst, const u8 *src1, const u8 *src2, unsigned int size) @@ -829,7 +826,7 @@ static __always_inline void old_rcu_barrier(void) #define COMPAT_CANNOT_DEPRECIATE_BH_RCU #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 10) && !defined(ISRHEL8) && !defined(ISOPENSUSE151) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 10) && !defined(ISRHEL8) static inline void skb_mark_not_on_list(struct sk_buff *skb) { skb->next = NULL; @@ -837,10 +834,10 @@ static inline void skb_mark_not_on_list(struct sk_buff *skb) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) && !defined(ISRHEL8) -#define NLA_EXACT_LEN NLA_UNSPEC +#define NLA_POLICY_EXACT_LEN(_len) { .type = NLA_UNSPEC, .len = _len } #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) && !defined(ISRHEL8) -#define NLA_MIN_LEN NLA_UNSPEC +#define NLA_POLICY_MIN_LEN(_len) { .type = NLA_UNSPEC, .len = _len } #define COMPAT_CANNOT_INDIVIDUAL_NETLINK_OPS_POLICY #endif @@ -1070,6 +1067,10 @@ static const struct header_ops ip_tunnel_header_ops = { .parse_protocol = ip_tun #endif #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0) +#define kfree_sensitive(a) kzfree(a) +#endif + #if defined(ISUBUNTU1604) || defined(ISRHEL7) #include #ifndef _WG_LINUX_SIPHASH_H diff --git a/net/wireguard/dkms.conf b/net/wireguard/dkms.conf index 6a72e4ef64c6..33a1840cad17 100644 --- a/net/wireguard/dkms.conf +++ b/net/wireguard/dkms.conf @@ -1,5 +1,5 @@ PACKAGE_NAME="wireguard" -PACKAGE_VERSION="1.0.20200729" +PACKAGE_VERSION="1.0.20200908" AUTOINSTALL=yes BUILT_MODULE_NAME="wireguard" diff --git a/net/wireguard/netlink.c b/net/wireguard/netlink.c index 3dde0ede48d3..ef239ab1e2d6 100644 --- a/net/wireguard/netlink.c +++ b/net/wireguard/netlink.c @@ -20,8 +20,8 @@ static struct genl_family genl_family; static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = { [WGDEVICE_A_IFINDEX] = { .type = NLA_U32 }, [WGDEVICE_A_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 }, - [WGDEVICE_A_PRIVATE_KEY] = { .type = NLA_EXACT_LEN, .len = NOISE_PUBLIC_KEY_LEN }, - [WGDEVICE_A_PUBLIC_KEY] = { .type = NLA_EXACT_LEN, .len = NOISE_PUBLIC_KEY_LEN }, + [WGDEVICE_A_PRIVATE_KEY] = NLA_POLICY_EXACT_LEN(NOISE_PUBLIC_KEY_LEN), + [WGDEVICE_A_PUBLIC_KEY] = NLA_POLICY_EXACT_LEN(NOISE_PUBLIC_KEY_LEN), [WGDEVICE_A_FLAGS] = { .type = NLA_U32 }, [WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 }, [WGDEVICE_A_FWMARK] = { .type = NLA_U32 }, @@ -29,12 +29,12 @@ static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = { }; static const struct nla_policy peer_policy[WGPEER_A_MAX + 1] = { - [WGPEER_A_PUBLIC_KEY] = { .type = NLA_EXACT_LEN, .len = NOISE_PUBLIC_KEY_LEN }, - [WGPEER_A_PRESHARED_KEY] = { .type = NLA_EXACT_LEN, .len = NOISE_SYMMETRIC_KEY_LEN }, + [WGPEER_A_PUBLIC_KEY] = NLA_POLICY_EXACT_LEN(NOISE_PUBLIC_KEY_LEN), + [WGPEER_A_PRESHARED_KEY] = NLA_POLICY_EXACT_LEN(NOISE_SYMMETRIC_KEY_LEN), [WGPEER_A_FLAGS] = { .type = NLA_U32 }, - [WGPEER_A_ENDPOINT] = { .type = NLA_MIN_LEN, .len = sizeof(struct sockaddr) }, + [WGPEER_A_ENDPOINT] = NLA_POLICY_MIN_LEN(sizeof(struct sockaddr)), [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NLA_U16 }, - [WGPEER_A_LAST_HANDSHAKE_TIME] = { .type = NLA_EXACT_LEN, .len = sizeof(struct __kernel_timespec) }, + [WGPEER_A_LAST_HANDSHAKE_TIME] = NLA_POLICY_EXACT_LEN(sizeof(struct __kernel_timespec)), [WGPEER_A_RX_BYTES] = { .type = NLA_U64 }, [WGPEER_A_TX_BYTES] = { .type = NLA_U64 }, [WGPEER_A_ALLOWEDIPS] = { .type = NLA_NESTED }, @@ -43,7 +43,7 @@ static const struct nla_policy peer_policy[WGPEER_A_MAX + 1] = { static const struct nla_policy allowedip_policy[WGALLOWEDIP_A_MAX + 1] = { [WGALLOWEDIP_A_FAMILY] = { .type = NLA_U16 }, - [WGALLOWEDIP_A_IPADDR] = { .type = NLA_MIN_LEN, .len = sizeof(struct in_addr) }, + [WGALLOWEDIP_A_IPADDR] = NLA_POLICY_MIN_LEN(sizeof(struct in_addr)), [WGALLOWEDIP_A_CIDR_MASK] = { .type = NLA_U8 } }; diff --git a/net/wireguard/noise.c b/net/wireguard/noise.c index 5fbe06368e31..5cc08060a572 100644 --- a/net/wireguard/noise.c +++ b/net/wireguard/noise.c @@ -114,7 +114,7 @@ static struct noise_keypair *keypair_create(struct wg_peer *peer) static void keypair_free_rcu(struct rcu_head *rcu) { - kzfree(container_of(rcu, struct noise_keypair, rcu)); + kfree_sensitive(container_of(rcu, struct noise_keypair, rcu)); } static void keypair_free_kref(struct kref *kref) @@ -823,7 +823,7 @@ bool wg_noise_handshake_begin_session(struct noise_handshake *handshake, handshake->entry.peer->device->index_hashtable, &handshake->entry, &new_keypair->entry); } else { - kzfree(new_keypair); + kfree_sensitive(new_keypair); } rcu_read_unlock_bh(); diff --git a/net/wireguard/peer.c b/net/wireguard/peer.c index 1d634bd3038f..b3b6370e6b95 100644 --- a/net/wireguard/peer.c +++ b/net/wireguard/peer.c @@ -203,7 +203,7 @@ static void rcu_release(struct rcu_head *rcu) /* The final zeroing takes care of clearing any remaining handshake key * material and other potentially sensitive information. */ - kzfree(peer); + kfree_sensitive(peer); } static void kref_release(struct kref *refcount) diff --git a/net/wireguard/peerlookup.c b/net/wireguard/peerlookup.c index e4deb331476b..f2783aa7a88f 100644 --- a/net/wireguard/peerlookup.c +++ b/net/wireguard/peerlookup.c @@ -167,9 +167,13 @@ bool wg_index_hashtable_replace(struct index_hashtable *table, struct index_hashtable_entry *old, struct index_hashtable_entry *new) { - if (unlikely(hlist_unhashed(&old->index_hash))) - return false; + bool ret; + spin_lock_bh(&table->lock); + ret = !hlist_unhashed(&old->index_hash); + if (unlikely(!ret)) + goto out; + new->index = old->index; hlist_replace_rcu(&old->index_hash, &new->index_hash); @@ -180,8 +184,9 @@ bool wg_index_hashtable_replace(struct index_hashtable *table, * simply gets dropped, which isn't terrible. */ INIT_HLIST_NODE(&old->index_hash); +out: spin_unlock_bh(&table->lock); - return true; + return ret; } void wg_index_hashtable_remove(struct index_hashtable *table, diff --git a/net/wireguard/version.h b/net/wireguard/version.h index 93ee76c9196b..138165f690c0 100644 --- a/net/wireguard/version.h +++ b/net/wireguard/version.h @@ -1,3 +1,3 @@ #ifndef WIREGUARD_VERSION -#define WIREGUARD_VERSION "1.0.20200729" +#define WIREGUARD_VERSION "1.0.20200908" #endif