diff options
| author | Ashwanth Goli <ashwanth@codeaurora.org> | 2017-02-24 11:03:03 -0700 |
|---|---|---|
| committer | Ashwanth Goli <ashwanth@codeaurora.org> | 2017-05-19 21:08:49 +0530 |
| commit | d4ee8914bf11380cda657e5bb3e8b8b23e599f01 (patch) | |
| tree | d9c296ecec1bb4cc8292f5805eebf41a7543c8b0 /net/rmnet_data | |
| parent | 5404e35069576a8cd8203065f60975e34a5f727b (diff) | |
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: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
Signed-off-by: Ashwanth Goli <ashwanth@codeaurora.org>
Diffstat (limited to 'net/rmnet_data')
| -rw-r--r-- | net/rmnet_data/rmnet_data_config.c | 10 | ||||
| -rw-r--r-- | net/rmnet_data/rmnet_data_handlers.c | 9 |
2 files changed, 13 insertions, 6 deletions
diff --git a/net/rmnet_data/rmnet_data_config.c b/net/rmnet_data/rmnet_data_config.c index fad084d03854..6fc9b86204de 100644 --- a/net/rmnet_data/rmnet_data_config.c +++ b/net/rmnet_data/rmnet_data_config.c @@ -1165,6 +1165,7 @@ static void rmnet_force_unassociate_device(struct net_device *dev) { int i, j; struct net_device *vndev; + struct rmnet_phys_ep_config *config; struct rmnet_logical_ep_conf_s *cfg; struct rmnet_free_vnd_work *vnd_work; ASSERT_RTNL(); @@ -1220,6 +1221,15 @@ 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); diff --git a/net/rmnet_data/rmnet_data_handlers.c b/net/rmnet_data/rmnet_data_handlers.c index cef9369eace5..ae60f35b363d 100644 --- a/net/rmnet_data/rmnet_data_handlers.c +++ b/net/rmnet_data/rmnet_data_handlers.c @@ -569,12 +569,9 @@ 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); - kfree_skb(skb); - return 1; - } + LOGE("Not enough headroom for %d bytes", required_headroom); + kfree_skb(skb); + return 1; } if ((config->egress_data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV3) || |
