CVE-2021-47275

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
21/05/2024
Last modified:
30/04/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> bcache: avoid oversized read request in cache missing code path<br /> <br /> In the cache missing code path of cached device, if a proper location<br /> from the internal B+ tree is matched for a cache miss range, function<br /> cached_dev_cache_miss() will be called in cache_lookup_fn() in the<br /> following code block,<br /> [code block 1]<br /> 526 unsigned int sectors = KEY_INODE(k) == s-&gt;iop.inode<br /> 527 ? min_t(uint64_t, INT_MAX,<br /> 528 KEY_START(k) - bio-&gt;bi_iter.bi_sector)<br /> 529 : INT_MAX;<br /> 530 int ret = s-&gt;d-&gt;cache_miss(b, s, bio, sectors);<br /> <br /> Here s-&gt;d-&gt;cache_miss() is the call backfunction pointer initialized as<br /> cached_dev_cache_miss(), the last parameter &amp;#39;sectors&amp;#39; is an important<br /> hint to calculate the size of read request to backing device of the<br /> missing cache data.<br /> <br /> Current calculation in above code block may generate oversized value of<br /> &amp;#39;sectors&amp;#39;, which consequently may trigger 2 different potential kernel<br /> panics by BUG() or BUG_ON() as listed below,<br /> <br /> 1) BUG_ON() inside bch_btree_insert_key(),<br /> [code block 2]<br /> 886 BUG_ON(b-&gt;ops-&gt;is_extents &amp;&amp; !KEY_SIZE(k));<br /> 2) BUG() inside biovec_slab(),<br /> [code block 3]<br /> 51 default:<br /> 52 BUG();<br /> 53 return NULL;<br /> <br /> All the above panics are original from cached_dev_cache_miss() by the<br /> oversized parameter &amp;#39;sectors&amp;#39;.<br /> <br /> Inside cached_dev_cache_miss(), parameter &amp;#39;sectors&amp;#39; is used to calculate<br /> the size of data read from backing device for the cache missing. This<br /> size is stored in s-&gt;insert_bio_sectors by the following lines of code,<br /> [code block 4]<br /> 909 s-&gt;insert_bio_sectors = min(sectors, bio_sectors(bio) + reada);<br /> <br /> Then the actual key inserting to the internal B+ tree is generated and<br /> stored in s-&gt;iop.replace_key by the following lines of code,<br /> [code block 5]<br /> 911 s-&gt;iop.replace_key = KEY(s-&gt;iop.inode,<br /> 912 bio-&gt;bi_iter.bi_sector + s-&gt;insert_bio_sectors,<br /> 913 s-&gt;insert_bio_sectors);<br /> The oversized parameter &amp;#39;sectors&amp;#39; may trigger panic 1) by BUG_ON() from<br /> the above code block.<br /> <br /> And the bio sending to backing device for the missing data is allocated<br /> with hint from s-&gt;insert_bio_sectors by the following lines of code,<br /> [code block 6]<br /> 926 cache_bio = bio_alloc_bioset(GFP_NOWAIT,<br /> 927 DIV_ROUND_UP(s-&gt;insert_bio_sectors, PAGE_SECTORS),<br /> 928 &amp;dc-&gt;disk.bio_split);<br /> The oversized parameter &amp;#39;sectors&amp;#39; may trigger panic 2) by BUG() from the<br /> agove code block.<br /> <br /> Now let me explain how the panics happen with the oversized &amp;#39;sectors&amp;#39;.<br /> In code block 5, replace_key is generated by macro KEY(). From the<br /> definition of macro KEY(),<br /> [code block 7]<br /> 71 #define KEY(inode, offset, size) \<br /> 72 ((struct bkey) { \<br /> 73 .high = (1ULL

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.12.11 (excluding)
cpe:2.3:o:linux:linux_kernel:5.13:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc3:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc4:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:5.13:rc5:*:*:*:*:*:*