CVE-2022-49771

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
01/05/2025
Last modified:
02/05/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> dm ioctl: fix misbehavior if list_versions races with module loading<br /> <br /> __list_versions will first estimate the required space using the<br /> "dm_target_iterate(list_version_get_needed, &amp;needed)" call and then will<br /> fill the space using the "dm_target_iterate(list_version_get_info,<br /> &amp;iter_info)" call. Each of these calls locks the targets using the<br /> "down_read(&amp;_lock)" and "up_read(&amp;_lock)" calls, however between the first<br /> and second "dm_target_iterate" there is no lock held and the target<br /> modules can be loaded at this point, so the second "dm_target_iterate"<br /> call may need more space than what was the first "dm_target_iterate"<br /> returned.<br /> <br /> The code tries to handle this overflow (see the beginning of<br /> list_version_get_info), however this handling is incorrect.<br /> <br /> The code sets "param-&gt;data_size = param-&gt;data_start + needed" and<br /> "iter_info.end = (char *)vers+len" - "needed" is the size returned by the<br /> first dm_target_iterate call; "len" is the size of the buffer allocated by<br /> userspace.<br /> <br /> "len" may be greater than "needed"; in this case, the code will write up<br /> to "len" bytes into the buffer, however param-&gt;data_size is set to<br /> "needed", so it may write data past the param-&gt;data_size value. The ioctl<br /> interface copies only up to param-&gt;data_size into userspace, thus part of<br /> the result will be truncated.<br /> <br /> Fix this bug by setting "iter_info.end = (char *)vers + needed;" - this<br /> guarantees that the second "dm_target_iterate" call will write only up to<br /> the "needed" buffer and it will exit with "DM_BUFFER_FULL_FLAG" if it<br /> overflows the "needed" space - in this case, userspace will allocate a<br /> larger buffer and retry.<br /> <br /> Note that there is also a bug in list_version_get_needed - we need to add<br /> "strlen(tt-&gt;name) + 1" to the needed size, not "strlen(tt-&gt;name)".

Impact