Skip to content
代码片段 群组 项目
提交 36fe0f3a 编辑于 作者: Jason A. Donenfeld's avatar Jason A. Donenfeld
浏览文件

socket: verify saddr belongs to interface


This helps "unstick" stuck source addresses, when changing routes
dynamically.

Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
上级 9eed02a3
未找到相关分支
未找到相关标签
无相关合并请求
......@@ -279,6 +279,11 @@ static inline u64 ktime_get_ns(void)
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
#include <linux/inetdevice.h>
#define inet_confirm_addr(a,b,c,d,e) inet_confirm_addr(b,c,d,e)
#endif
/* https://lkml.org/lkml/2015/6/12/415 */
#include <linux/netdevice.h>
static inline struct net_device *netdev_pub(void *dev)
......
......@@ -10,6 +10,7 @@
#include <linux/net.h>
#include <linux/if_vlan.h>
#include <linux/if_ether.h>
#include <linux/inetdevice.h>
#include <net/udp_tunnel.h>
#include <net/ipv6.h>
......@@ -44,10 +45,12 @@ static inline int send4(struct wireguard_device *wg, struct sk_buff *skb, struct
if (!rt) {
security_sk_classify_flow(sock, flowi4_to_flowi(&fl));
rt = ip_route_output_flow(sock_net(sock), &fl, sock);
if (unlikely(IS_ERR(rt) && PTR_ERR(rt) == -EINVAL && fl.saddr)) {
if (unlikely(endpoint->src4.s_addr && ((IS_ERR(rt) && PTR_ERR(rt) == -EINVAL) || (!IS_ERR(rt) && !inet_confirm_addr(sock_net(sock), __in_dev_get_rcu(rt->dst.dev), 0, fl.saddr, RT_SCOPE_HOST))))) {
endpoint->src4.s_addr = fl.saddr = 0;
if (cache)
dst_cache_reset(cache);
if (!IS_ERR(rt))
dst_release(&rt->dst);
rt = ip_route_output_flow(sock_net(sock), &fl, sock);
}
if (unlikely(IS_ERR(rt))) {
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
想要评论请 注册