scsi: libcxgbi: fix skb use after free

skb->data is assigned to task->hdr in cxgbi_conn_alloc_pdu(),
skb gets freed after tx but task->hdr is still dereferenced in
iscsi_tcp_task_xmit() to avoid this call skb_get() after allocating skb
and free the skb in cxgbi_cleanup_task() or before allocating new skb in
cxgbi_conn_alloc_pdu().

Signed-off-by: Varun Prakash <varun@chelsio.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Varun Prakash
2017-05-16 19:23:44 +05:30
committed by Martin K. Petersen
vanhempi b19775e478
commit 75b61250bf
2 muutettua tiedostoa jossa 26 lisäystä ja 15 poistoa

Näytä tiedosto

@@ -195,7 +195,8 @@ struct cxgbi_skb_rx_cb {
};
struct cxgbi_skb_tx_cb {
void *l2t;
void *handle;
void *arp_err_handler;
struct sk_buff *wr_next;
};
@@ -203,6 +204,7 @@ enum cxgbi_skcb_flags {
SKCBF_TX_NEED_HDR, /* packet needs a header */
SKCBF_TX_MEM_WRITE, /* memory write */
SKCBF_TX_FLAG_COMPL, /* wr completion flag */
SKCBF_TX_DONE, /* skb tx done */
SKCBF_RX_COALESCED, /* received whole pdu */
SKCBF_RX_HDR, /* received pdu header */
SKCBF_RX_DATA, /* received pdu payload */
@@ -215,13 +217,13 @@ enum cxgbi_skcb_flags {
};
struct cxgbi_skb_cb {
unsigned char ulp_mode;
unsigned long flags;
unsigned int seq;
union {
struct cxgbi_skb_rx_cb rx;
struct cxgbi_skb_tx_cb tx;
};
unsigned char ulp_mode;
unsigned long flags;
unsigned int seq;
};
#define CXGBI_SKB_CB(skb) ((struct cxgbi_skb_cb *)&((skb)->cb[0]))
@@ -374,11 +376,9 @@ static inline void cxgbi_sock_enqueue_wr(struct cxgbi_sock *csk,
cxgbi_skcb_tx_wr_next(skb) = NULL;
/*
* We want to take an extra reference since both us and the driver
* need to free the packet before it's really freed. We know there's
* just one user currently so we use atomic_set rather than skb_get
* to avoid the atomic op.
* need to free the packet before it's really freed.
*/
atomic_set(&skb->users, 2);
skb_get(skb);
if (!csk->wr_pending_head)
csk->wr_pending_head = skb;