In the Linux kernel, the following vulnerability has been resolved:
bcache: fix NULL pointer in cachesetflush()
registercacheset() will call bchcacheset_alloc() in LINE#2098.
1794 struct cacheset *bchcachesetalloc(struct cachesb *sb) 1795 { ... 1860 if (!(c->devices = kcalloc(c->nruuids, sizeof(void *), GFPKERNEL)) || 1861 mempoolinitslabpool(&c->search, 32, bchsearchcache) || 1862 mempoolinitkmallocpool(&c->biometa, 2, 1863 sizeof(struct bbio) + sizeof(struct biovec) * 1864 bucketpages(c)) || 1865 mempoolinitkmallocpool(&c->filliter, 1, itersize) || 1866 biosetinit(&c->biosplit, 4, offsetof(struct bbio, bio), 1867 BIOSETNEEDBVECS|BIOSETNEEDRESCUER) || 1868 !(c->uuids = allocbucketpages(GFPKERNEL, c)) || 1869 !(c->movinggcwq = allocworkqueue("bcachegc", 1870 WQMEMRECLAIM, 0)) || 1871 bchjournalalloc(c) || 1872 bchbtreecachealloc(c) || 1873 bchopenbucketsalloc(c) || 1874 bchbsetsortstateinit(&c->sort, ilog2(c->btreepages))) 1875 goto err; ^^^^^^^^ 1876 ... 1883 return c; 1884 err: 1885 bchcachesetunregister(c); ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1886 return NULL; 1887 } ... 2078 static const char *registercacheset(struct cache *ca) 2079 { ... 2098 c = bchcachesetalloc(&ca->sb); 2099 if (!c) 2100 return err; ^^^^^^^^^^ ... 2128 ca->set = c; 2129 ca->set->cache[ca->sb.nrthisdev] = ca; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... 2138 return NULL; 2139 err: 2140 bchcachesetunregister(c); 2141 return err; 2142 }
(1) If LINE#1860 - LINE#1874 is true, then do 'goto err'(LINE#1875) and call bchcacheset_unregister()(LINE#1885). (2) As (1) return NULL(LINE#1886), LINE#2098 - LINE#2100 would return. (3) As (2) has returned, LINE#2128 - LINE#2129 would do not give the value to c->cache[], it means that c->cache[] is NULL.
LINE#1624 - LINE#1665 is some codes about function of cachesetflush(). As (1), in LINE#1885 call bchcachesetunregister() ---> bchcachesetstop() ---> closurequeue() -.-> cacheset_flush() (as below LINE#1624)
1624 static void cachesetflush(struct closure *cl) 1625 { ... 1654 foreachcache(ca, c, i) 1655 if (ca->allocthread) ^^ 1656 kthreadstop(ca->alloc_thread); ... 1665 }
(4) In LINE#1655 ca is NULL(see (3)) in cachesetflush() then the kernel crash occurred as below: [ 846.712887] bcache: registercache() error drbd6: cannot allocate memory [ 846.713242] bcache: registerbcache() error : failed to register device [ 846.713336] bcache: cachesetfree() Cache set 2f84bdc1-498a-4f2f-98a7-01946bf54287 unregistered [ 846.713768] BUG: unable to handle kernel NULL pointer dereference at 00000000000009f8 [ 846.714790] PGD 0 P4D 0 [ 846.715129] Oops: 0000 [#1] SMP PTI [ 846.715472] CPU: 19 PID: 5057 Comm: kworker/19:16 Kdump: loaded Tainted: G OE --------- - - 4.18.0-147.5.1.el81.5es.3.x8664 #1 [ 846.716082] Hardware name: ESPAN GI-25212/X11DPL-i, BIOS 2.1 06/15/2018 [ 846.716451] Workqueue: events cachesetflush [bcache] [ 846.716808] RIP: 0010:cachesetflush+0xc9/0x1b0 [bcache] [ 846.717155] Code: 00 4c 89 a5 b0 03 00 00 48 8b 85 68 f6 ff ff a8 08 0f 84 88 00 00 00 31 db 66 83 bd 3c f7 ff ff 00 48 8b 85 48 ff ff ff 74 28 <48> 8b b8 f8 09 00 0 ---truncated---