CVE-2025-68359
Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
24/12/2025
Last modified:
29/12/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
btrfs: fix double free of qgroup record after failure to add delayed ref head<br />
<br />
In the previous code it was possible to incur into a double kfree()<br />
scenario when calling add_delayed_ref_head(). This could happen if the<br />
record was reported to already exist in the<br />
btrfs_qgroup_trace_extent_nolock() call, but then there was an error<br />
later on add_delayed_ref_head(). In this case, since<br />
add_delayed_ref_head() returned an error, the caller went to free the<br />
record. Since add_delayed_ref_head() couldn&#39;t set this kfree&#39;d pointer<br />
to NULL, then kfree() would have acted on a non-NULL &#39;record&#39; object<br />
which was pointing to memory already freed by the callee.<br />
<br />
The problem comes from the fact that the responsibility to kfree the<br />
object is on both the caller and the callee at the same time. Hence, the<br />
fix for this is to shift the ownership of the &#39;qrecord&#39; object out of<br />
the add_delayed_ref_head(). That is, we will never attempt to kfree()<br />
the given object inside of this function, and will expect the caller to<br />
act on the &#39;qrecord&#39; object on its own. The only exception where the<br />
&#39;qrecord&#39; object cannot be kfree&#39;d is if it was inserted into the<br />
tracing logic, for which we already have the &#39;qrecord_inserted_ret&#39;<br />
boolean to account for this. Hence, the caller has to kfree the object<br />
only if add_delayed_ref_head() reports not to have inserted it on the<br />
tracing logic.<br />
<br />
As a side-effect of the above, we must guarantee that<br />
&#39;qrecord_inserted_ret&#39; is properly initialized at the start of the<br />
function, not at the end, and then set when an actual insert<br />
happens. This way we avoid &#39;qrecord_inserted_ret&#39; having an invalid<br />
value on an early exit.<br />
<br />
The documentation from the add_delayed_ref_head() has also been updated<br />
to reflect on the exact ownership of the &#39;qrecord&#39; object.



