diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h index 88ff7bb2bb9b..382af5f36e7f 100644 --- a/include/net/dst_ops.h +++ b/include/net/dst_ops.h @@ -12,6 +12,16 @@ struct sk_buff; struct sock; struct net; +/* *** ANDROID FIXUP *** + * These typedefs are used to help fixup the ABI break caused by commit + * 92f1655aa2b2 ("net: fix __dst_negative_advice() race") where the + * negative_advice callback changed function signatures. + * See b/343727534 for more details. + * *** ANDROID FIXUP *** + */ +typedef void (*android_dst_ops_negative_advice_new_t)(struct sock *sk, struct dst_entry *); +typedef struct dst_entry * (*android_dst_ops_negative_advice_old_t)(struct dst_entry *); + struct dst_ops { unsigned short family; unsigned int gc_thresh; diff --git a/include/net/sock.h b/include/net/sock.h index e44d45781eef..7189de533bd4 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1955,18 +1955,19 @@ sk_dst_get(struct sock *sk) static inline void dst_negative_advice(struct sock *sk) { - struct dst_entry *ndst, *dst = __sk_dst_get(sk); + /* *** ANDROID FIXUP *** + * See b/343727534 for more details why this typedef is needed here. + * *** ANDROID FIXUP *** + */ + android_dst_ops_negative_advice_new_t negative_advice; + + struct dst_entry *dst = __sk_dst_get(sk); sk_rethink_txhash(sk); if (dst && dst->ops->negative_advice) { - ndst = dst->ops->negative_advice(dst); - - if (ndst != dst) { - rcu_assign_pointer(sk->sk_dst_cache, ndst); - sk_tx_queue_clear(sk); - WRITE_ONCE(sk->sk_dst_pending_confirm, 0); - } + negative_advice = (android_dst_ops_negative_advice_new_t)dst->ops->negative_advice; + negative_advice(sk, dst); } } diff --git a/mm/pgsize_migration.c b/mm/pgsize_migration.c index 9efadd1412a3..1c36fcc6fa63 100644 --- a/mm/pgsize_migration.c +++ b/mm/pgsize_migration.c @@ -19,6 +19,7 @@ #include #include #include +#include #include typedef void (*show_pad_maps_fn) (struct seq_file *m, struct vm_area_struct *vma); @@ -183,7 +184,15 @@ static inline bool linker_ctx(void) memset(buf, 0, bufsize); path = d_path(&file->f_path, buf, bufsize); - if (!strcmp(path, "/system/bin/linker64")) + /* + * Depending on interpreter requested, valid paths could be any of: + * 1. /system/bin/bootstrap/linker64 + * 2. /system/bin/linker64 + * 3. /apex/com.android.runtime/bin/linker64 + * + * Check the base name (linker64). + */ + if (!strcmp(kbasename(path), "linker64")) return true; } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 5b008d838e2b..f3fd630836e3 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -137,7 +137,8 @@ static int ip_rt_gc_timeout __read_mostly = RT_GC_TIMEOUT; static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie); static unsigned int ipv4_default_advmss(const struct dst_entry *dst); static unsigned int ipv4_mtu(const struct dst_entry *dst); -static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); +static void ipv4_negative_advice(struct sock *sk, + struct dst_entry *dst); static void ipv4_link_failure(struct sk_buff *skb); static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu, @@ -164,7 +165,7 @@ static struct dst_ops ipv4_dst_ops = { .mtu = ipv4_mtu, .cow_metrics = ipv4_cow_metrics, .destroy = ipv4_dst_destroy, - .negative_advice = ipv4_negative_advice, + .negative_advice = (android_dst_ops_negative_advice_old_t)ipv4_negative_advice, .link_failure = ipv4_link_failure, .update_pmtu = ip_rt_update_pmtu, .redirect = ip_do_redirect, @@ -856,22 +857,15 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf __ip_do_redirect(rt, skb, &fl4, true); } -static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) +static void ipv4_negative_advice(struct sock *sk, + struct dst_entry *dst) { struct rtable *rt = (struct rtable *)dst; - struct dst_entry *ret = dst; - if (rt) { - if (dst->obsolete > 0) { - ip_rt_put(rt); - ret = NULL; - } else if ((rt->rt_flags & RTCF_REDIRECTED) || - rt->dst.expires) { - ip_rt_put(rt); - ret = NULL; - } - } - return ret; + if ((dst->obsolete > 0) || + (rt->rt_flags & RTCF_REDIRECTED) || + rt->dst.expires) + sk_dst_reset(sk); } /* diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 4c51cabc866c..379b62d87bc1 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -84,7 +84,8 @@ enum rt6_nud_state { static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static unsigned int ip6_default_advmss(const struct dst_entry *dst); static unsigned int ip6_mtu(const struct dst_entry *dst); -static struct dst_entry *ip6_negative_advice(struct dst_entry *); +static void ip6_negative_advice(struct sock *sk, + struct dst_entry *dst); static void ip6_dst_destroy(struct dst_entry *); static void ip6_dst_ifdown(struct dst_entry *, struct net_device *dev, int how); @@ -249,7 +250,7 @@ static struct dst_ops ip6_dst_ops_template = { .cow_metrics = dst_cow_metrics_generic, .destroy = ip6_dst_destroy, .ifdown = ip6_dst_ifdown, - .negative_advice = ip6_negative_advice, + .negative_advice = (android_dst_ops_negative_advice_old_t)ip6_negative_advice, .link_failure = ip6_link_failure, .update_pmtu = ip6_rt_update_pmtu, .redirect = rt6_do_redirect, @@ -2658,24 +2659,24 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) return dst_ret; } -static struct dst_entry *ip6_negative_advice(struct dst_entry *dst) +static void ip6_negative_advice(struct sock *sk, + struct dst_entry *dst) { struct rt6_info *rt = (struct rt6_info *) dst; - if (rt) { - if (rt->rt6i_flags & RTF_CACHE) { - rcu_read_lock(); - if (rt6_check_expired(rt)) { - rt6_remove_exception_rt(rt); - dst = NULL; - } - rcu_read_unlock(); - } else { - dst_release(dst); - dst = NULL; + if (rt->rt6i_flags & RTF_CACHE) { + rcu_read_lock(); + if (rt6_check_expired(rt)) { + /* counteract the dst_release() in sk_dst_reset() */ + dst_hold(dst); + sk_dst_reset(sk); + + rt6_remove_exception_rt(rt); } + rcu_read_unlock(); + return; } - return dst; + sk_dst_reset(sk); } static void ip6_link_failure(struct sk_buff *skb) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8632776ae4da..0fe167dca7c2 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -3778,15 +3778,10 @@ static void xfrm_link_failure(struct sk_buff *skb) /* Impossible. Such dst must be popped before reaches point of failure. */ } -static struct dst_entry *xfrm_negative_advice(struct dst_entry *dst) +static void xfrm_negative_advice(struct sock *sk, struct dst_entry *dst) { - if (dst) { - if (dst->obsolete) { - dst_release(dst); - dst = NULL; - } - } - return dst; + if (dst->obsolete) + sk_dst_reset(sk); } static void xfrm_init_pmtu(struct xfrm_dst **bundle, int nr) @@ -3954,7 +3949,7 @@ int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int fam if (likely(dst_ops->mtu == NULL)) dst_ops->mtu = xfrm_mtu; if (likely(dst_ops->negative_advice == NULL)) - dst_ops->negative_advice = xfrm_negative_advice; + dst_ops->negative_advice = (android_dst_ops_negative_advice_old_t)xfrm_negative_advice; if (likely(dst_ops->link_failure == NULL)) dst_ops->link_failure = xfrm_link_failure; if (likely(dst_ops->neigh_lookup == NULL))