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

Merge tag 'linux-can-fixes-for-5.13-20210619' of...

Merge tag 'linux-can-fixes-for-5.13-20210619' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can



Marc Kleine-Budde says:

====================
pull-request: can 2021-06-19

this is a pull request of 5 patches for net/master.

The first patch is by Thadeu Lima de Souza Cascardo and fixes a
potential use-after-free in the CAN broadcast manager socket, by
delaying the release of struct bcm_op after synchronize_rcu().

Oliver Hartkopp's patch fixes a similar potential user-after-free in
the CAN gateway socket by synchronizing RCU operations before removing
gw job entry.

Another patch by Oliver Hartkopp fixes a potential use-after-free in
the ISOTP socket by omitting unintended hrtimer restarts on socket
release.

Oleksij Rempel's patch for the j1939 socket fixes a potential
use-after-free by setting the SOCK_RCU_FREE flag on the socket.

The last patch is by Pavel Skripkin and fixes a use-after-free in the
ems_usb CAN driver.

All patches are intended for stable and have stable@v.k.o on Cc.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0d98ec87 ab4a0b8f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1053,7 +1053,6 @@ static void ems_usb_disconnect(struct usb_interface *intf)

	if (dev) {
		unregister_netdev(dev->netdev);
		free_candev(dev->netdev);

		unlink_all_urbs(dev);

@@ -1061,6 +1060,8 @@ static void ems_usb_disconnect(struct usb_interface *intf)

		kfree(dev->intr_in_buffer);
		kfree(dev->tx_msg_buffer);

		free_candev(dev->netdev);
	}
}

+6 −1
Original line number Diff line number Diff line
@@ -785,6 +785,7 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
						  bcm_rx_handler, op);

			list_del(&op->list);
			synchronize_rcu();
			bcm_remove_op(op);
			return 1; /* done */
		}
@@ -1533,9 +1534,13 @@ static int bcm_release(struct socket *sock)
					  REGMASK(op->can_id),
					  bcm_rx_handler, op);

		bcm_remove_op(op);
	}

	synchronize_rcu();

	list_for_each_entry_safe(op, next, &bo->rx_ops, list)
		bcm_remove_op(op);

#if IS_ENABLED(CONFIG_PROC_FS)
	/* remove procfs entry */
	if (net->can.bcmproc_dir && bo->bcm_proc_read)
+3 −0
Original line number Diff line number Diff line
@@ -596,6 +596,7 @@ static int cgw_notifier(struct notifier_block *nb,
			if (gwj->src.dev == dev || gwj->dst.dev == dev) {
				hlist_del(&gwj->list);
				cgw_unregister_filter(net, gwj);
				synchronize_rcu();
				kmem_cache_free(cgw_cache, gwj);
			}
		}
@@ -1154,6 +1155,7 @@ static void cgw_remove_all_jobs(struct net *net)
	hlist_for_each_entry_safe(gwj, nx, &net->can.cgw_list, list) {
		hlist_del(&gwj->list);
		cgw_unregister_filter(net, gwj);
		synchronize_rcu();
		kmem_cache_free(cgw_cache, gwj);
	}
}
@@ -1222,6 +1224,7 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh,

		hlist_del(&gwj->list);
		cgw_unregister_filter(net, gwj);
		synchronize_rcu();
		kmem_cache_free(cgw_cache, gwj);
		err = 0;
		break;
+4 −3
Original line number Diff line number Diff line
@@ -1028,9 +1028,6 @@ static int isotp_release(struct socket *sock)

	lock_sock(sk);

	hrtimer_cancel(&so->txtimer);
	hrtimer_cancel(&so->rxtimer);

	/* remove current filters & unregister */
	if (so->bound && (!(so->opt.flags & CAN_ISOTP_SF_BROADCAST))) {
		if (so->ifindex) {
@@ -1042,10 +1039,14 @@ static int isotp_release(struct socket *sock)
						  SINGLE_MASK(so->rxid),
						  isotp_rcv, sk);
				dev_put(dev);
				synchronize_rcu();
			}
		}
	}

	hrtimer_cancel(&so->txtimer);
	hrtimer_cancel(&so->rxtimer);

	so->ifindex = 0;
	so->bound = 0;

+4 −0
Original line number Diff line number Diff line
@@ -193,6 +193,10 @@ static void j1939_can_rx_unregister(struct j1939_priv *priv)
	can_rx_unregister(dev_net(ndev), ndev, J1939_CAN_ID, J1939_CAN_MASK,
			  j1939_can_recv, priv);

	/* The last reference of priv is dropped by the RCU deferred
	 * j1939_sk_sock_destruct() of the last socket, so we can
	 * safely drop this reference here.
	 */
	j1939_priv_put(priv);
}

Loading