Re: v4.20-rc6: Sporadic use-after-free in bt_iter()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2018-12-20 at 06:07 -0700, Jens Axboe wrote:
+AD4 On 12/20/18 6:02 AM, Jens Axboe wrote:
+AD4 +AD4 +AD4 I'm afraid this cannot work.
+AD4 +AD4 +AD4 
+AD4 +AD4 +AD4 The 'tags' here could be the hctx-+AD4-sched+AF8-tags, but what we need to
+AD4 +AD4 +AD4 clear is hctx-+AD4-tags-+AD4-rqs+AFsAXQ.
+AD4 +AD4 
+AD4 +AD4 You are right, of course, a bit too quick on the trigger. This one
+AD4 +AD4 should work better, and also avoids that silly quadratic loop. I don't
+AD4 +AD4 think we need the tag +AD0APQ -1 check, but probably best to be safe.
+AD4 
+AD4 Sent out the wrong one, here it is. Bart, if you can reproduce, can you
+AD4 give it a whirl?
+AD4 
+AD4 
+AD4 diff --git a/block/blk-mq.c b/block/blk-mq.c
+AD4 index 2de972857496..fc04bb648f18 100644
+AD4 --- a/block/blk-mq.c
+AD4 +-+-+- b/block/blk-mq.c
+AD4 +AEAAQA -2025,7 +-2025,7 +AEAAQA void blk+AF8-mq+AF8-free+AF8-rqs(struct blk+AF8-mq+AF8-tag+AF8-set +ACo-set, struct blk+AF8-mq+AF8-tags +ACo-tags,
+AD4  +AHs
+AD4  	struct page +ACo-page+ADs
+AD4  
+AD4 -	if (tags-+AD4-rqs +ACYAJg set-+AD4-ops-+AD4-exit+AF8-request) +AHs
+AD4 +-	if (tags-+AD4-rqs) +AHs
+AD4  		int i+ADs
+AD4  
+AD4  		for (i +AD0 0+ADs i +ADw tags-+AD4-nr+AF8-tags+ADs i+-+-) +AHs
+AD4 +AEAAQA -2033,8 +-2033,14 +AEAAQA void blk+AF8-mq+AF8-free+AF8-rqs(struct blk+AF8-mq+AF8-tag+AF8-set +ACo-set, struct blk+AF8-mq+AF8-tags +ACo-tags,
+AD4  
+AD4  			if (+ACE-rq)
+AD4  				continue+ADs
+AD4 -			set-+AD4-ops-+AD4-exit+AF8-request(set, rq, hctx+AF8-idx)+ADs
+AD4 +-			if (set-+AD4-ops-+AD4-exit+AF8-request)
+AD4 +-				set-+AD4-ops-+AD4-exit+AF8-request(set, rq, hctx+AF8-idx)+ADs
+AD4  			tags-+AD4-static+AF8-rqs+AFs-i+AF0 +AD0 NULL+ADs
+AD4 +-
+AD4 +-			if (rq-+AD4-tag +AD0APQ -1)
+AD4 +-				continue+ADs
+AD4 +-			if (set-+AD4-tags+AFs-hctx+AF8-idx+AF0--+AD4-rqs+AFs-rq-+AD4-tag+AF0 +AD0APQ rq)
+AD4 +-				set-+AD4-tags+AFs-hctx+AF8-idx+AF0--+AD4-rqs+AFs-rq-+AD4-tag+AF0 +AD0 NULL+ADs
+AD4  		+AH0
+AD4  	+AH0
+AD4  
+AD4 +AEAAQA -2113,6 +-2119,7 +AEAAQA static int blk+AF8-mq+AF8-init+AF8-request(struct blk+AF8-mq+AF8-tag+AF8-set +ACo-set, struct request +ACo-rq,
+AD4  			return ret+ADs
+AD4  	+AH0
+AD4  
+AD4 +-	rq-+AD4-tag +AD0 -1+ADs
+AD4  	WRITE+AF8-ONCE(rq-+AD4-state, MQ+AF8-RQ+AF8-IDLE)+ADs
+AD4  	return 0+ADs
+AD4  +AH0

Hi Jens,

Are you sure this is sufficient? My understanding is that
blk+AF8-mq+AF8-queue+AF8-tag+AF8-busy+AF8-iter() iterates over all tags in the tag set. So if the
request queue on which part+AF8-in+AF8-flight() is called and the request queue for
which blk+AF8-mq+AF8-free+AF8-rqs() is called share their tag set then part+AF8-in+AF8-flight()
and blk+AF8-mq+AF8-free+AF8-rqs() can run concurrently. That can cause ugly race
conditions. Do you think it would be a good idea to modify the inflight
accounting code such that it only considers the requests of a single request
queue instead of all requests for a given tag set?

Thanks,

Bart.



[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux