Skip to content

Commit 2dabe34

Browse files
plinga1anguy11
authored andcommitted
idpf: fix null-ptr-deref in idpf_features_check
idpf_features_check is used to validate the TX packet. skb header length is compared with the hardware supported value received from the device control plane. The value is stored in the adapter structure and to access it, vport pointer is used. During reset all the vports are released and the vport pointer that the netdev private structure points to is NULL. To avoid null-ptr-deref, store the max header length value in netdev private structure. This also helps to cache the value and avoid accessing adapter pointer in hot path. BUG: kernel NULL pointer dereference, address: 0000000000000068 ... RIP: 0010:idpf_features_check+0x6d/0xe0 [idpf] Call Trace: <TASK> ? __die+0x23/0x70 ? page_fault_oops+0x154/0x520 ? exc_page_fault+0x76/0x190 ? asm_exc_page_fault+0x26/0x30 ? idpf_features_check+0x6d/0xe0 [idpf] netif_skb_features+0x88/0x310 validate_xmit_skb+0x2a/0x2b0 validate_xmit_skb_list+0x4c/0x70 sch_direct_xmit+0x19d/0x3a0 __dev_queue_xmit+0xb74/0xe70 ... Fixes: a251eee ("idpf: add SRIOV support and other ndo_ops") Reviewed-by: Madhu Chititm <[email protected]> Signed-off-by: Pavan Kumar Linga <[email protected]> Reviewed-by: Simon Horman <[email protected]> Tested-by: Samuel Salin <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 6c778f1 commit 2dabe34

File tree

2 files changed

+8
-4
lines changed

2 files changed

+8
-4
lines changed

drivers/net/ethernet/intel/idpf/idpf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ enum idpf_vport_state {
143143
* @vport_id: Vport identifier
144144
* @link_speed_mbps: Link speed in mbps
145145
* @vport_idx: Relative vport index
146+
* @max_tx_hdr_size: Max header length hardware can support
146147
* @state: See enum idpf_vport_state
147148
* @netstats: Packet and byte stats
148149
* @stats_lock: Lock to protect stats update
@@ -153,6 +154,7 @@ struct idpf_netdev_priv {
153154
u32 vport_id;
154155
u32 link_speed_mbps;
155156
u16 vport_idx;
157+
u16 max_tx_hdr_size;
156158
enum idpf_vport_state state;
157159
struct rtnl_link_stats64 netstats;
158160
spinlock_t stats_lock;

drivers/net/ethernet/intel/idpf/idpf_lib.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ static int idpf_cfg_netdev(struct idpf_vport *vport)
723723
np->vport = vport;
724724
np->vport_idx = vport->idx;
725725
np->vport_id = vport->vport_id;
726+
np->max_tx_hdr_size = idpf_get_max_tx_hdr_size(adapter);
726727
vport->netdev = netdev;
727728

728729
return idpf_init_mac_addr(vport, netdev);
@@ -740,6 +741,7 @@ static int idpf_cfg_netdev(struct idpf_vport *vport)
740741
np->adapter = adapter;
741742
np->vport_idx = vport->idx;
742743
np->vport_id = vport->vport_id;
744+
np->max_tx_hdr_size = idpf_get_max_tx_hdr_size(adapter);
743745

744746
spin_lock_init(&np->stats_lock);
745747

@@ -2203,8 +2205,8 @@ static netdev_features_t idpf_features_check(struct sk_buff *skb,
22032205
struct net_device *netdev,
22042206
netdev_features_t features)
22052207
{
2206-
struct idpf_vport *vport = idpf_netdev_to_vport(netdev);
2207-
struct idpf_adapter *adapter = vport->adapter;
2208+
struct idpf_netdev_priv *np = netdev_priv(netdev);
2209+
u16 max_tx_hdr_size = np->max_tx_hdr_size;
22082210
size_t len;
22092211

22102212
/* No point in doing any of this if neither checksum nor GSO are
@@ -2227,7 +2229,7 @@ static netdev_features_t idpf_features_check(struct sk_buff *skb,
22272229
goto unsupported;
22282230

22292231
len = skb_network_header_len(skb);
2230-
if (unlikely(len > idpf_get_max_tx_hdr_size(adapter)))
2232+
if (unlikely(len > max_tx_hdr_size))
22312233
goto unsupported;
22322234

22332235
if (!skb->encapsulation)
@@ -2240,7 +2242,7 @@ static netdev_features_t idpf_features_check(struct sk_buff *skb,
22402242

22412243
/* IPLEN can support at most 127 dwords */
22422244
len = skb_inner_network_header_len(skb);
2243-
if (unlikely(len > idpf_get_max_tx_hdr_size(adapter)))
2245+
if (unlikely(len > max_tx_hdr_size))
22442246
goto unsupported;
22452247

22462248
/* No need to validate L4LEN as TCP is the only protocol with a

0 commit comments

Comments
 (0)