Commit ec4040ae authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-sk_err-lockless-annotate'



Eric Dumazet says:

====================
net: annotate lockless accesses to sk_err[_soft]

This patch series is inspired by yet another syzbot report.

Most poll() handlers are lockless and read sk->sk_err
while other cpus can change it.

Add READ_ONCE/WRITE_ONCE() to major/usual offenders.

More to come later.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 731b73db cc04410a
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -601,7 +601,7 @@ static void lowcomms_error_report(struct sock *sk)
				   "sk_err=%d/%d\n", dlm_our_nodeid(),
				   con->nodeid, &inet->inet_daddr,
				   ntohs(inet->inet_dport), sk->sk_err,
				   sk->sk_err_soft);
				   READ_ONCE(sk->sk_err_soft));
		break;
#if IS_ENABLED(CONFIG_IPV6)
	case AF_INET6:
@@ -610,14 +610,15 @@ static void lowcomms_error_report(struct sock *sk)
				   "dport %d, sk_err=%d/%d\n", dlm_our_nodeid(),
				   con->nodeid, &sk->sk_v6_daddr,
				   ntohs(inet->inet_dport), sk->sk_err,
				   sk->sk_err_soft);
				   READ_ONCE(sk->sk_err_soft));
		break;
#endif
	default:
		printk_ratelimited(KERN_ERR "dlm: node %d: socket error "
				   "invalid socket family %d set, "
				   "sk_err=%d/%d\n", dlm_our_nodeid(),
				   sk->sk_family, sk->sk_err, sk->sk_err_soft);
				   sk->sk_family, sk->sk_err,
				   READ_ONCE(sk->sk_err_soft));
		break;
	}

+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ static int sigd_send(struct atm_vcc *vcc, struct sk_buff *skb)
		break;
	case as_addparty:
	case as_dropparty:
		sk->sk_err_soft = -msg->reply;
		WRITE_ONCE(sk->sk_err_soft, -msg->reply);
					/* < 0 failure, otherwise ep_ref */
		clear_bit(ATM_VF_WAITING, &vcc->flags);
		break;
+7 −5
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk,
	 * for the case, if this connection will not able to recover.
	 */
	if (mtu < dst_mtu(dst) && ip_dont_fragment(sk, dst))
		sk->sk_err_soft = EMSGSIZE;
		WRITE_ONCE(sk->sk_err_soft, EMSGSIZE);

	mtu = dst_mtu(dst);

@@ -339,8 +339,9 @@ static int dccp_v4_err(struct sk_buff *skb, u32 info)
			sk_error_report(sk);

			dccp_done(sk);
		} else
			sk->sk_err_soft = err;
		} else {
			WRITE_ONCE(sk->sk_err_soft, err);
		}
		goto out;
	}

@@ -364,8 +365,9 @@ static int dccp_v4_err(struct sk_buff *skb, u32 info)
	if (!sock_owned_by_user(sk) && inet->recverr) {
		sk->sk_err = err;
		sk_error_report(sk);
	} else /* Only an error on timeout */
		sk->sk_err_soft = err;
	} else { /* Only an error on timeout */
		WRITE_ONCE(sk->sk_err_soft, err);
	}
out:
	bh_unlock_sock(sk);
	sock_put(sk);
+6 −5
Original line number Diff line number Diff line
@@ -174,17 +174,18 @@ static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
			 */
			sk_error_report(sk);
			dccp_done(sk);
		} else
			sk->sk_err_soft = err;
		} else {
			WRITE_ONCE(sk->sk_err_soft, err);
		}
		goto out;
	}

	if (!sock_owned_by_user(sk) && np->recverr) {
		sk->sk_err = err;
		sk_error_report(sk);
	} else
		sk->sk_err_soft = err;

	} else {
		WRITE_ONCE(sk->sk_err_soft, err);
	}
out:
	bh_unlock_sock(sk);
	sock_put(sk);
+1 −1
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ int sysctl_dccp_retries2 __read_mostly = TCP_RETR2;

static void dccp_write_err(struct sock *sk)
{
	sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT;
	sk->sk_err = READ_ONCE(sk->sk_err_soft) ? : ETIMEDOUT;
	sk_error_report(sk);

	dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
Loading