Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19f98150 authored by Ashwanth Goli's avatar Ashwanth Goli Committed by Subash Abhinov Kasiviswanathan
Browse files

net: rmnet_data: Unset logical end points in bridge mode



We clean up the logical end points only for the un-registering device
in bridge mode. However, the other physical end point's local end
point still points to the the un-registered device.

This may lead up to a crash if one of the physical devices in bridge
mode is un-registered. Fix this by unsetting the local endpoint.

It is still possible that packets in a different context across cores
might try to access this data. This usually manifests as packets
requesting a very large headroom. Handle this by dropping these stale
skb's.

CRs-Fixed: 1098513
Change-Id: I1ba4d877a6ed3eca66946fe056938f0927bcd9a5
Signed-off-by: default avatarAshwanth Goli <ashwanth@codeaurora.org>
Signed-off-by: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
parent c0aed240
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -1123,6 +1123,7 @@ static void rmnet_force_unassociate_device(struct net_device *dev)
{
	int i, j;
	struct net_device *vndev;
	struct rmnet_phys_ep_conf_s *config;
	struct rmnet_logical_ep_conf_s *cfg;
	struct rmnet_free_vnd_work *vnd_work;
	ASSERT_RTNL();
@@ -1178,6 +1179,16 @@ static void rmnet_force_unassociate_device(struct net_device *dev)
		kfree(vnd_work);
	}

	config = _rmnet_get_phys_ep_config(dev);

	if (config) {
		cfg = &config->local_ep;

		if (cfg && cfg->refcount)
			rmnet_unset_logical_endpoint_config
			(cfg->egress_dev, RMNET_LOCAL_LOGICAL_ENDPOINT);
	}

	/* Clear the mappings on the phys ep */
	trace_rmnet_unregister_cb_clear_lepcs(dev);
	rmnet_unset_logical_endpoint_config(dev, RMNET_LOCAL_LOGICAL_ENDPOINT);
+4 −7
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -501,13 +501,10 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
	LOGD("headroom of %d bytes", required_headroom);

	if (skb_headroom(skb) < required_headroom) {
		if (pskb_expand_head(skb, required_headroom, 0, GFP_KERNEL)) {
			LOGD("Failed to add headroom of %d bytes",
			     required_headroom);
		LOGE("Not enough headroom for %d bytes", required_headroom);
		kfree_skb(skb);
		return 1;
	}
	}

	if ((config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV3) ||
	    (config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4)) {