Commit d6d9fc1d authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-smc-fixes-2022-04-08'

Karsten Graul says:

====================
net/smc: fixes 2022-04-08

Patch 1 fixes two usages of snprintf() with non null-terminated
string which results into an out-of-bounds read.
Pach 2 fixes a syzbot finding where a pointer check was missed
before the call to dev_name().
Patch 3 fixes a crash when already released memory is used as
a function pointer.
====================

Link: https://lore.kernel.org/r/20220408151035.1044701-1-kgraul@linux.ibm.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 5ad7f18c 49b7d376
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ static struct sock *smc_tcp_syn_recv_sock(const struct sock *sk,
					  bool *own_req)
{
	struct smc_sock *smc;
	struct sock *child;

	smc = smc_clcsock_user_data(sk);

@@ -134,8 +135,17 @@ static struct sock *smc_tcp_syn_recv_sock(const struct sock *sk,
	}

	/* passthrough to original syn recv sock fct */
	return smc->ori_af_ops->syn_recv_sock(sk, skb, req, dst, req_unhash,
	child = smc->ori_af_ops->syn_recv_sock(sk, skb, req, dst, req_unhash,
					       own_req);
	/* child must not inherit smc or its ops */
	if (child) {
		rcu_assign_sk_user_data(child, NULL);

		/* v4-mapped sockets don't inherit parent ops. Don't restore. */
		if (inet_csk(child)->icsk_af_ops == inet_csk(sk)->icsk_af_ops)
			inet_csk(child)->icsk_af_ops = smc->ori_af_ops;
	}
	return child;

drop:
	dst_release(dst);
+4 −2
Original line number Diff line number Diff line
@@ -191,7 +191,8 @@ static int smc_nl_ueid_dumpinfo(struct sk_buff *skb, u32 portid, u32 seq,
			  flags, SMC_NETLINK_DUMP_UEID);
	if (!hdr)
		return -ENOMEM;
	snprintf(ueid_str, sizeof(ueid_str), "%s", ueid);
	memcpy(ueid_str, ueid, SMC_MAX_EID_LEN);
	ueid_str[SMC_MAX_EID_LEN] = 0;
	if (nla_put_string(skb, SMC_NLA_EID_TABLE_ENTRY, ueid_str)) {
		genlmsg_cancel(skb, hdr);
		return -EMSGSIZE;
@@ -252,7 +253,8 @@ int smc_nl_dump_seid(struct sk_buff *skb, struct netlink_callback *cb)
		goto end;

	smc_ism_get_system_eid(&seid);
	snprintf(seid_str, sizeof(seid_str), "%s", seid);
	memcpy(seid_str, seid, SMC_MAX_EID_LEN);
	seid_str[SMC_MAX_EID_LEN] = 0;
	if (nla_put_string(skb, SMC_NLA_SEID_ENTRY, seid_str))
		goto err;
	read_lock(&smc_clc_eid_table.lock);
+3 −2
Original line number Diff line number Diff line
@@ -311,8 +311,9 @@ static struct smc_ib_device *smc_pnet_find_ib(char *ib_name)
	list_for_each_entry(ibdev, &smc_ib_devices.list, list) {
		if (!strncmp(ibdev->ibdev->name, ib_name,
			     sizeof(ibdev->ibdev->name)) ||
		    (ibdev->ibdev->dev.parent &&
		     !strncmp(dev_name(ibdev->ibdev->dev.parent), ib_name,
			     IB_DEVICE_NAME_MAX - 1)) {
			     IB_DEVICE_NAME_MAX - 1))) {
			goto out;
		}
	}