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:

committed by
Martin K. Petersen

vanhempi
b19775e478
commit
75b61250bf
@@ -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;
|
||||
|
Viittaa uudesa ongelmassa
Block a user