Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: libfc: convert fc_fcp_pkt.ref_cnt from atomic_t to refcount_t

refcount_t type and corresponding API should be used instead of atomic_t
when the variable is used as a reference counter. This allows to avoid
accidental refcounter overflows that might lead to use-after-free
situations.

Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
Acked-by: Johannes Thumshirn <jth@kernel.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Elena Reshetova and committed by
Martin K. Petersen
22c70d1a fb5fe0fd

+5 -4
+3 -3
drivers/scsi/libfc/fc_fcp.c
··· 154 154 memset(fsp, 0, sizeof(*fsp)); 155 155 fsp->lp = lport; 156 156 fsp->xfer_ddp = FC_XID_UNKNOWN; 157 - atomic_set(&fsp->ref_cnt, 1); 157 + refcount_set(&fsp->ref_cnt, 1); 158 158 init_timer(&fsp->timer); 159 159 fsp->timer.data = (unsigned long)fsp; 160 160 INIT_LIST_HEAD(&fsp->list); ··· 175 175 */ 176 176 static void fc_fcp_pkt_release(struct fc_fcp_pkt *fsp) 177 177 { 178 - if (atomic_dec_and_test(&fsp->ref_cnt)) { 178 + if (refcount_dec_and_test(&fsp->ref_cnt)) { 179 179 struct fc_fcp_internal *si = fc_get_scsi_internal(fsp->lp); 180 180 181 181 mempool_free(fsp, si->scsi_pkt_pool); ··· 188 188 */ 189 189 static void fc_fcp_pkt_hold(struct fc_fcp_pkt *fsp) 190 190 { 191 - atomic_inc(&fsp->ref_cnt); 191 + refcount_inc(&fsp->ref_cnt); 192 192 } 193 193 194 194 /**
+2 -1
include/scsi/libfc.h
··· 23 23 #include <linux/timer.h> 24 24 #include <linux/if.h> 25 25 #include <linux/percpu.h> 26 + #include <linux/refcount.h> 26 27 27 28 #include <scsi/scsi_transport.h> 28 29 #include <scsi/scsi_transport_fc.h> ··· 322 321 */ 323 322 struct fc_fcp_pkt { 324 323 spinlock_t scsi_pkt_lock; 325 - atomic_t ref_cnt; 324 + refcount_t ref_cnt; 326 325 327 326 /* SCSI command and data transfer information */ 328 327 u32 data_len;