mirror of https://github.com/OpenIPC/firmware.git
160 lines
5.2 KiB
Diff
160 lines
5.2 KiB
Diff
diff -drupN a/net/ipv4/route.c b/net/ipv4/route.c
|
|
--- a/net/ipv4/route.c 2018-08-06 17:23:04.000000000 +0300
|
|
+++ b/net/ipv4/route.c 2022-06-12 05:28:14.000000000 +0300
|
|
@@ -510,7 +510,8 @@ void __ip_select_ident(struct net *net,
|
|
}
|
|
EXPORT_SYMBOL(__ip_select_ident);
|
|
|
|
-static void __build_flow_key(struct flowi4 *fl4, const struct sock *sk,
|
|
+static void __build_flow_key(const struct net *net, struct flowi4 *fl4,
|
|
+ const struct sock *sk,
|
|
const struct iphdr *iph,
|
|
int oif, u8 tos,
|
|
u8 prot, u32 mark, int flow_flags)
|
|
@@ -526,19 +527,21 @@ static void __build_flow_key(struct flow
|
|
flowi4_init_output(fl4, oif, mark, tos,
|
|
RT_SCOPE_UNIVERSE, prot,
|
|
flow_flags,
|
|
- iph->daddr, iph->saddr, 0, 0);
|
|
+ iph->daddr, iph->saddr, 0, 0,
|
|
+ sock_net_uid(net, sk));
|
|
}
|
|
|
|
static void build_skb_flow_key(struct flowi4 *fl4, const struct sk_buff *skb,
|
|
const struct sock *sk)
|
|
{
|
|
+ const struct net *net = dev_net(skb->dev);
|
|
const struct iphdr *iph = ip_hdr(skb);
|
|
int oif = skb->dev->ifindex;
|
|
u8 tos = RT_TOS(iph->tos);
|
|
u8 prot = iph->protocol;
|
|
u32 mark = skb->mark;
|
|
|
|
- __build_flow_key(fl4, sk, iph, oif, tos, prot, mark, 0);
|
|
+ __build_flow_key(net, fl4, sk, iph, oif, tos, prot, mark, 0);
|
|
}
|
|
|
|
static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk)
|
|
@@ -555,7 +558,7 @@ static void build_sk_flow_key(struct flo
|
|
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
|
|
inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
|
|
inet_sk_flowi_flags(sk),
|
|
- daddr, inet->inet_saddr, 0, 0);
|
|
+ daddr, inet->inet_saddr, 0, 0, sk->sk_uid);
|
|
rcu_read_unlock();
|
|
}
|
|
|
|
@@ -807,6 +810,7 @@ static void ip_do_redirect(struct dst_en
|
|
struct rtable *rt;
|
|
struct flowi4 fl4;
|
|
const struct iphdr *iph = (const struct iphdr *) skb->data;
|
|
+ struct net *net = dev_net(skb->dev);
|
|
int oif = skb->dev->ifindex;
|
|
u8 tos = RT_TOS(iph->tos);
|
|
u8 prot = iph->protocol;
|
|
@@ -814,7 +818,7 @@ static void ip_do_redirect(struct dst_en
|
|
|
|
rt = (struct rtable *) dst;
|
|
|
|
- __build_flow_key(&fl4, sk, iph, oif, tos, prot, mark, 0);
|
|
+ __build_flow_key(net, &fl4, sk, iph, oif, tos, prot, mark, 0);
|
|
__ip_do_redirect(rt, skb, &fl4, true);
|
|
}
|
|
|
|
@@ -1035,7 +1039,7 @@ void ipv4_update_pmtu(struct sk_buff *sk
|
|
if (!mark)
|
|
mark = IP4_REPLY_MARK(net, skb->mark);
|
|
|
|
- __build_flow_key(&fl4, NULL, iph, oif,
|
|
+ __build_flow_key(net, &fl4, NULL, iph, oif,
|
|
RT_TOS(iph->tos), protocol, mark, flow_flags);
|
|
rt = __ip_route_output_key(net, &fl4);
|
|
if (!IS_ERR(rt)) {
|
|
@@ -1051,7 +1055,7 @@ static void __ipv4_sk_update_pmtu(struct
|
|
struct flowi4 fl4;
|
|
struct rtable *rt;
|
|
|
|
- __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
|
|
+ __build_flow_key(sock_net(sk), &fl4, sk, iph, 0, 0, 0, 0, 0);
|
|
|
|
if (!fl4.flowi4_mark)
|
|
fl4.flowi4_mark = IP4_REPLY_MARK(sock_net(sk), skb->mark);
|
|
@@ -1070,6 +1074,7 @@ void ipv4_sk_update_pmtu(struct sk_buff
|
|
struct rtable *rt;
|
|
struct dst_entry *odst = NULL;
|
|
bool new = false;
|
|
+ struct net *net = sock_net(sk);
|
|
|
|
bh_lock_sock(sk);
|
|
|
|
@@ -1083,7 +1088,7 @@ void ipv4_sk_update_pmtu(struct sk_buff
|
|
goto out;
|
|
}
|
|
|
|
- __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
|
|
+ __build_flow_key(net, &fl4, sk, iph, 0, 0, 0, 0, 0);
|
|
|
|
rt = (struct rtable *)odst;
|
|
if (odst->obsolete && !odst->ops->check(odst, 0)) {
|
|
@@ -1123,7 +1128,7 @@ void ipv4_redirect(struct sk_buff *skb,
|
|
struct flowi4 fl4;
|
|
struct rtable *rt;
|
|
|
|
- __build_flow_key(&fl4, NULL, iph, oif,
|
|
+ __build_flow_key(net, &fl4, NULL, iph, oif,
|
|
RT_TOS(iph->tos), protocol, mark, flow_flags);
|
|
rt = __ip_route_output_key(net, &fl4);
|
|
if (!IS_ERR(rt)) {
|
|
@@ -1138,9 +1143,10 @@ void ipv4_sk_redirect(struct sk_buff *sk
|
|
const struct iphdr *iph = (const struct iphdr *) skb->data;
|
|
struct flowi4 fl4;
|
|
struct rtable *rt;
|
|
+ struct net *net = sock_net(sk);
|
|
|
|
- __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
|
|
- rt = __ip_route_output_key(sock_net(sk), &fl4);
|
|
+ __build_flow_key(net, &fl4, sk, iph, 0, 0, 0, 0, 0);
|
|
+ rt = __ip_route_output_key(net, &fl4);
|
|
if (!IS_ERR(rt)) {
|
|
__ip_do_redirect(rt, skb, &fl4, false);
|
|
ip_rt_put(rt);
|
|
@@ -2524,6 +2530,11 @@ static int rt_fill_info(struct net *net,
|
|
nla_put_u32(skb, RTA_MARK, fl4->flowi4_mark))
|
|
goto nla_put_failure;
|
|
|
|
+ if (!uid_eq(fl4->flowi4_uid, INVALID_UID) &&
|
|
+ nla_put_u32(skb, RTA_UID,
|
|
+ from_kuid_munged(current_user_ns(), fl4->flowi4_uid)))
|
|
+ goto nla_put_failure;
|
|
+
|
|
error = rt->dst.error;
|
|
|
|
if (rt_is_input_route(rt)) {
|
|
@@ -2576,6 +2587,7 @@ static int inet_rtm_getroute(struct sk_b
|
|
int mark;
|
|
struct sk_buff *skb;
|
|
u32 table_id = RT_TABLE_MAIN;
|
|
+ kuid_t uid;
|
|
|
|
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv4_policy);
|
|
if (err < 0)
|
|
@@ -2603,6 +2615,10 @@ static int inet_rtm_getroute(struct sk_b
|
|
dst = tb[RTA_DST] ? nla_get_in_addr(tb[RTA_DST]) : 0;
|
|
iif = tb[RTA_IIF] ? nla_get_u32(tb[RTA_IIF]) : 0;
|
|
mark = tb[RTA_MARK] ? nla_get_u32(tb[RTA_MARK]) : 0;
|
|
+ if (tb[RTA_UID])
|
|
+ uid = make_kuid(current_user_ns(), nla_get_u32(tb[RTA_UID]));
|
|
+ else
|
|
+ uid = (iif ? INVALID_UID : current_uid());
|
|
|
|
memset(&fl4, 0, sizeof(fl4));
|
|
fl4.daddr = dst;
|
|
@@ -2610,6 +2626,7 @@ static int inet_rtm_getroute(struct sk_b
|
|
fl4.flowi4_tos = rtm->rtm_tos;
|
|
fl4.flowi4_oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0;
|
|
fl4.flowi4_mark = mark;
|
|
+ fl4.flowi4_uid = uid;
|
|
|
|
if (iif) {
|
|
struct net_device *dev;
|