From c85bfbe2e8e2ffdf76d40a30fdfdb8860db01b23 Mon Sep 17 00:00:00 2001 From: Ashwanth Goli Date: Fri, 24 Feb 2017 11:03:03 -0700 Subject: [PATCH] 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: Ashwanth Goli Signed-off-by: Subash Abhinov Kasiviswanathan --- net/rmnet_data/rmnet_data_config.c | 11 +++++++++++ net/rmnet_data/rmnet_data_handlers.c | 9 +++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/net/rmnet_data/rmnet_data_config.c b/net/rmnet_data/rmnet_data_config.c index 2a30d55cb121..50d9b51000b9 100644 --- a/net/rmnet_data/rmnet_data_config.c +++ b/net/rmnet_data/rmnet_data_config.c @@ -1173,6 +1173,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; @@ -1228,6 +1229,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); diff --git a/net/rmnet_data/rmnet_data_handlers.c b/net/rmnet_data/rmnet_data_handlers.c index 46fdf5a1de26..35be79ef30e0 100644 --- a/net/rmnet_data/rmnet_data_handlers.c +++ b/net/rmnet_data/rmnet_data_handlers.c @@ -552,12 +552,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) ||