CVE-2024-46781: Linux Kernel nilfs2 Mount-Time Recovery Vulnerability Resolved

,nilfs2: fix missing cleanup on rollforward recovery error"

This vulnerability was discovered during an error injection test of a routine for mount-time recovery. The Kernel Address Sanitizer (KASAN) detected a use-after-free bug which was caused by a missing cleanup when certain errors occurred in the rollforward recovery process. In this article, we will discuss the details of this vulnerability and how it has been fixed, along with code snippets and links to original references.

Exploit Details

The vulnerability was identified when using partial logs created by "dsync" writes to perform data recovery. If an error occurred before starting the log writer to create a recovered checkpoint, the inodes whose data had been recovered were left in the "ns_dirty_files" list of the nilfs object and were not freed. This results in a use-after-free bug that could be exploited by an attacker, potentially leading to crashes, data corruption, or even arbitrary code execution.

Here's a simplified code snippet demonstrating the issue

// recovery routine
void nilfs_recovery() {
    // Read and process recovery data from partial logs
    if (read_recovery_data() < ) {
        // Error occurred while reading recovery data
        return;
    }
    // Start log writer to create a recovered checkpoint
    if (start_log_writer() < ) {
        // Error occurred while starting log writer
        // ns_dirty_files list cleanup is missing here
        return;
    }
    // ...
}

In the snippet above, you can see that when an error occurs while starting the log writer, there is no cleanup of the "ns_dirty_files" list, causing the use-after-free bug.

Fix:
The fix for this vulnerability involves adding the missing cleanup in the recovery routine to ensure that inodes that have read the recovery data are properly cleaned up if the recovery fails midway before the log writer starts. Here's the updated code snippet with the fix:

`
// recovery routine
void nilfs_recovery() {
// Read and process recovery data from partial logs
if (read_recovery_data() < ) {
// Error occurred while reading recovery data
return;

Timeline

Published on: 09/18/2024 08:15:05 UTC
Last modified on: 11/05/2024 09:46:31 UTC