mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-27 04:35:27 +07:00
Merge branch 'wireguard-fixes'
Jason A. Donenfeld says: ==================== wireguard fixes for 5.6-rc7 I originally intended to spend this cycle working on fun optimizations and architecture for WireGuard for 5.7, but I've been a bit neurotic about having 5.6 ship without any show stopper bugs. WireGuard has been stable for a long time now, but that doesn't make me any less nervous about the real deal in 5.6. To that end, I've been doing code reviews and having discussions, and we also had a security firm audit the code. That audit didn't turn up any vulnerabilities, but they did make a good defense-in-depth suggestion. This series contains: 1) Removal of a duplicated header, from YueHaibing. 2) Testing with 64-bit time in our test suite. 3) Account for skb->protocol==0 due to AF_PACKET sockets, suggested by Florian Fainelli. 4) Clean up some code in an unreachable switch/case branch, suggested by Florian Fainelli. 5) Better handling of low-order points, discussed with Mathias Hall-Andersen. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
3c025b6317
@ -122,7 +122,7 @@ static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
u32 mtu;
|
||||
int ret;
|
||||
|
||||
if (unlikely(wg_skb_examine_untrusted_ip_hdr(skb) != skb->protocol)) {
|
||||
if (unlikely(!wg_check_packet_protocol(skb))) {
|
||||
ret = -EPROTONOSUPPORT;
|
||||
net_dbg_ratelimited("%s: Invalid IP packet\n", dev->name);
|
||||
goto err;
|
||||
|
@ -411,11 +411,7 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs)
|
||||
|
||||
peer = wg_peer_create(wg, public_key, preshared_key);
|
||||
if (IS_ERR(peer)) {
|
||||
/* Similar to the above, if the key is invalid, we skip
|
||||
* it without fanfare, so that services don't need to
|
||||
* worry about doing key validation themselves.
|
||||
*/
|
||||
ret = PTR_ERR(peer) == -EKEYREJECTED ? 0 : PTR_ERR(peer);
|
||||
ret = PTR_ERR(peer);
|
||||
peer = NULL;
|
||||
goto out;
|
||||
}
|
||||
@ -569,7 +565,7 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
|
||||
private_key);
|
||||
list_for_each_entry_safe(peer, temp, &wg->peer_list,
|
||||
peer_list) {
|
||||
BUG_ON(!wg_noise_precompute_static_static(peer));
|
||||
wg_noise_precompute_static_static(peer);
|
||||
wg_noise_expire_current_peer_keypairs(peer);
|
||||
}
|
||||
wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
|
||||
|
@ -44,32 +44,23 @@ void __init wg_noise_init(void)
|
||||
}
|
||||
|
||||
/* Must hold peer->handshake.static_identity->lock */
|
||||
bool wg_noise_precompute_static_static(struct wg_peer *peer)
|
||||
void wg_noise_precompute_static_static(struct wg_peer *peer)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
down_write(&peer->handshake.lock);
|
||||
if (peer->handshake.static_identity->has_identity) {
|
||||
ret = curve25519(
|
||||
peer->handshake.precomputed_static_static,
|
||||
if (!peer->handshake.static_identity->has_identity ||
|
||||
!curve25519(peer->handshake.precomputed_static_static,
|
||||
peer->handshake.static_identity->static_private,
|
||||
peer->handshake.remote_static);
|
||||
} else {
|
||||
u8 empty[NOISE_PUBLIC_KEY_LEN] = { 0 };
|
||||
|
||||
ret = curve25519(empty, empty, peer->handshake.remote_static);
|
||||
peer->handshake.remote_static))
|
||||
memset(peer->handshake.precomputed_static_static, 0,
|
||||
NOISE_PUBLIC_KEY_LEN);
|
||||
}
|
||||
up_write(&peer->handshake.lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool wg_noise_handshake_init(struct noise_handshake *handshake,
|
||||
struct noise_static_identity *static_identity,
|
||||
const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN],
|
||||
const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN],
|
||||
struct wg_peer *peer)
|
||||
void wg_noise_handshake_init(struct noise_handshake *handshake,
|
||||
struct noise_static_identity *static_identity,
|
||||
const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN],
|
||||
const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN],
|
||||
struct wg_peer *peer)
|
||||
{
|
||||
memset(handshake, 0, sizeof(*handshake));
|
||||
init_rwsem(&handshake->lock);
|
||||
@ -81,7 +72,7 @@ bool wg_noise_handshake_init(struct noise_handshake *handshake,
|
||||
NOISE_SYMMETRIC_KEY_LEN);
|
||||
handshake->static_identity = static_identity;
|
||||
handshake->state = HANDSHAKE_ZEROED;
|
||||
return wg_noise_precompute_static_static(peer);
|
||||
wg_noise_precompute_static_static(peer);
|
||||
}
|
||||
|
||||
static void handshake_zero(struct noise_handshake *handshake)
|
||||
@ -403,6 +394,19 @@ static bool __must_check mix_dh(u8 chaining_key[NOISE_HASH_LEN],
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __must_check mix_precomputed_dh(u8 chaining_key[NOISE_HASH_LEN],
|
||||
u8 key[NOISE_SYMMETRIC_KEY_LEN],
|
||||
const u8 precomputed[NOISE_PUBLIC_KEY_LEN])
|
||||
{
|
||||
static u8 zero_point[NOISE_PUBLIC_KEY_LEN];
|
||||
if (unlikely(!crypto_memneq(precomputed, zero_point, NOISE_PUBLIC_KEY_LEN)))
|
||||
return false;
|
||||
kdf(chaining_key, key, NULL, precomputed, NOISE_HASH_LEN,
|
||||
NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN,
|
||||
chaining_key);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void mix_hash(u8 hash[NOISE_HASH_LEN], const u8 *src, size_t src_len)
|
||||
{
|
||||
struct blake2s_state blake;
|
||||
@ -531,10 +535,9 @@ wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst,
|
||||
NOISE_PUBLIC_KEY_LEN, key, handshake->hash);
|
||||
|
||||
/* ss */
|
||||
kdf(handshake->chaining_key, key, NULL,
|
||||
handshake->precomputed_static_static, NOISE_HASH_LEN,
|
||||
NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN,
|
||||
handshake->chaining_key);
|
||||
if (!mix_precomputed_dh(handshake->chaining_key, key,
|
||||
handshake->precomputed_static_static))
|
||||
goto out;
|
||||
|
||||
/* {t} */
|
||||
tai64n_now(timestamp);
|
||||
@ -595,9 +598,9 @@ wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src,
|
||||
handshake = &peer->handshake;
|
||||
|
||||
/* ss */
|
||||
kdf(chaining_key, key, NULL, handshake->precomputed_static_static,
|
||||
NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN,
|
||||
chaining_key);
|
||||
if (!mix_precomputed_dh(chaining_key, key,
|
||||
handshake->precomputed_static_static))
|
||||
goto out;
|
||||
|
||||
/* {t} */
|
||||
if (!message_decrypt(t, src->encrypted_timestamp,
|
||||
|
@ -94,11 +94,11 @@ struct noise_handshake {
|
||||
struct wg_device;
|
||||
|
||||
void wg_noise_init(void);
|
||||
bool wg_noise_handshake_init(struct noise_handshake *handshake,
|
||||
struct noise_static_identity *static_identity,
|
||||
const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN],
|
||||
const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN],
|
||||
struct wg_peer *peer);
|
||||
void wg_noise_handshake_init(struct noise_handshake *handshake,
|
||||
struct noise_static_identity *static_identity,
|
||||
const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN],
|
||||
const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN],
|
||||
struct wg_peer *peer);
|
||||
void wg_noise_handshake_clear(struct noise_handshake *handshake);
|
||||
static inline void wg_noise_reset_last_sent_handshake(atomic64_t *handshake_ns)
|
||||
{
|
||||
@ -116,7 +116,7 @@ void wg_noise_expire_current_peer_keypairs(struct wg_peer *peer);
|
||||
void wg_noise_set_static_identity_private_key(
|
||||
struct noise_static_identity *static_identity,
|
||||
const u8 private_key[NOISE_PUBLIC_KEY_LEN]);
|
||||
bool wg_noise_precompute_static_static(struct wg_peer *peer);
|
||||
void wg_noise_precompute_static_static(struct wg_peer *peer);
|
||||
|
||||
bool
|
||||
wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst,
|
||||
|
@ -34,11 +34,8 @@ struct wg_peer *wg_peer_create(struct wg_device *wg,
|
||||
return ERR_PTR(ret);
|
||||
peer->device = wg;
|
||||
|
||||
if (!wg_noise_handshake_init(&peer->handshake, &wg->static_identity,
|
||||
public_key, preshared_key, peer)) {
|
||||
ret = -EKEYREJECTED;
|
||||
goto err_1;
|
||||
}
|
||||
wg_noise_handshake_init(&peer->handshake, &wg->static_identity,
|
||||
public_key, preshared_key, peer);
|
||||
if (dst_cache_init(&peer->endpoint_cache, GFP_KERNEL))
|
||||
goto err_1;
|
||||
if (wg_packet_queue_init(&peer->tx_queue, wg_packet_tx_worker, false,
|
||||
|
@ -66,7 +66,7 @@ struct packet_cb {
|
||||
#define PACKET_PEER(skb) (PACKET_CB(skb)->keypair->entry.peer)
|
||||
|
||||
/* Returns either the correct skb->protocol value, or 0 if invalid. */
|
||||
static inline __be16 wg_skb_examine_untrusted_ip_hdr(struct sk_buff *skb)
|
||||
static inline __be16 wg_examine_packet_protocol(struct sk_buff *skb)
|
||||
{
|
||||
if (skb_network_header(skb) >= skb->head &&
|
||||
(skb_network_header(skb) + sizeof(struct iphdr)) <=
|
||||
@ -81,6 +81,12 @@ static inline __be16 wg_skb_examine_untrusted_ip_hdr(struct sk_buff *skb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool wg_check_packet_protocol(struct sk_buff *skb)
|
||||
{
|
||||
__be16 real_protocol = wg_examine_packet_protocol(skb);
|
||||
return real_protocol && skb->protocol == real_protocol;
|
||||
}
|
||||
|
||||
static inline void wg_reset_packet(struct sk_buff *skb)
|
||||
{
|
||||
skb_scrub_packet(skb, true);
|
||||
|
@ -56,7 +56,7 @@ static int prepare_skb_header(struct sk_buff *skb, struct wg_device *wg)
|
||||
size_t data_offset, data_len, header_len;
|
||||
struct udphdr *udp;
|
||||
|
||||
if (unlikely(wg_skb_examine_untrusted_ip_hdr(skb) != skb->protocol ||
|
||||
if (unlikely(!wg_check_packet_protocol(skb) ||
|
||||
skb_transport_header(skb) < skb->head ||
|
||||
(skb_transport_header(skb) + sizeof(struct udphdr)) >
|
||||
skb_tail_pointer(skb)))
|
||||
@ -388,7 +388,7 @@ static void wg_packet_consume_data_done(struct wg_peer *peer,
|
||||
*/
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
skb->csum_level = ~0; /* All levels */
|
||||
skb->protocol = wg_skb_examine_untrusted_ip_hdr(skb);
|
||||
skb->protocol = wg_examine_packet_protocol(skb);
|
||||
if (skb->protocol == htons(ETH_P_IP)) {
|
||||
len = ntohs(ip_hdr(skb)->tot_len);
|
||||
if (unlikely(len < sizeof(struct iphdr)))
|
||||
@ -587,8 +587,7 @@ void wg_packet_receive(struct wg_device *wg, struct sk_buff *skb)
|
||||
wg_packet_consume_data(wg, skb);
|
||||
break;
|
||||
default:
|
||||
net_dbg_skb_ratelimited("%s: Invalid packet from %pISpfsc\n",
|
||||
wg->dev->name, skb);
|
||||
WARN(1, "Non-exhaustive parsing of packet header lead to unknown packet type!\n");
|
||||
goto err;
|
||||
}
|
||||
return;
|
||||
|
@ -527,11 +527,16 @@ n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0
|
||||
n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75
|
||||
n0 wg set wg0 peer "$pub2" allowed-ips ::/0
|
||||
n0 wg set wg0 peer "$pub2" remove
|
||||
low_order_points=( AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38= )
|
||||
n0 wg set wg0 private-key /dev/null ${low_order_points[@]/#/peer }
|
||||
[[ -z $(n0 wg show wg0 peers) ]]
|
||||
n0 wg set wg0 private-key <(echo "$key1") ${low_order_points[@]/#/peer }
|
||||
[[ -z $(n0 wg show wg0 peers) ]]
|
||||
for low_order_point in AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38=; do
|
||||
n0 wg set wg0 peer "$low_order_point" persistent-keepalive 1 endpoint 127.0.0.1:1111
|
||||
done
|
||||
[[ -n $(n0 wg show wg0 peers) ]]
|
||||
exec 4< <(n0 ncat -l -u -p 1111)
|
||||
ncat_pid=$!
|
||||
waitncatudp $netns0 $ncat_pid
|
||||
ip0 link set wg0 up
|
||||
! read -r -n 1 -t 2 <&4 || false
|
||||
kill $ncat_pid
|
||||
ip0 link del wg0
|
||||
|
||||
declare -A objects
|
||||
|
@ -41,7 +41,7 @@ $(DISTFILES_PATH)/$(1):
|
||||
flock -x $$@.lock -c '[ -f $$@ ] && exit 0; wget -O $$@.tmp $(MIRROR)$(1) || wget -O $$@.tmp $(2)$(1) || rm -f $$@.tmp; [ -f $$@.tmp ] || exit 1; if echo "$(3) $$@.tmp" | sha256sum -c -; then mv $$@.tmp $$@; else rm -f $$@.tmp; exit 71; fi'
|
||||
endef
|
||||
|
||||
$(eval $(call tar_download,MUSL,musl,1.1.24,.tar.gz,https://www.musl-libc.org/releases/,1370c9a812b2cf2a7d92802510cca0058cc37e66a7bedd70051f0a34015022a3))
|
||||
$(eval $(call tar_download,MUSL,musl,1.2.0,.tar.gz,https://musl.libc.org/releases/,c6de7b191139142d3f9a7b5b702c9cae1b5ee6e7f57e582da9328629408fd4e8))
|
||||
$(eval $(call tar_download,IPERF,iperf,3.7,.tar.gz,https://downloads.es.net/pub/iperf/,d846040224317caf2f75c843d309a950a7db23f9b44b94688ccbe557d6d1710c))
|
||||
$(eval $(call tar_download,BASH,bash,5.0,.tar.gz,https://ftp.gnu.org/gnu/bash/,b4a80f2ac66170b2913efbfb9f2594f1f76c7b1afd11f799e22035d63077fb4d))
|
||||
$(eval $(call tar_download,IPROUTE2,iproute2,5.4.0,.tar.xz,https://www.kernel.org/pub/linux/utils/net/iproute2/,fe97aa60a0d4c5ac830be18937e18dc3400ca713a33a89ad896ff1e3d46086ae))
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/io.h>
|
||||
|
@ -56,7 +56,6 @@ CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NO_HZ_FULL=n
|
||||
CONFIG_HZ_PERIODIC=n
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_COMPAT_32BIT_TIME=y
|
||||
CONFIG_ARCH_RANDOM=y
|
||||
CONFIG_FILE_LOCKING=y
|
||||
CONFIG_POSIX_TIMERS=y
|
||||
|
Loading…
Reference in New Issue
Block a user