Ticket #13131: 0001-VFS-Fix-CID-702320-1397511-USE_AFTER_FREE.patch

File 0001-VFS-Fix-CID-702320-1397511-USE_AFTER_FREE.patch, 2.1 KB (added by jscipione, 4 years ago)

Patch which increments vnode ref_count before calling vnode_path_to_vnode()

  • src/tools/fs_shell/vfs.cpp

    From 97e3db1f8ddd9317c7ca75e5a1bdb71054555772 Mon Sep 17 00:00:00 2001
    From: John Scipione <jscipione@gmail.com>
    Date: Wed, 28 Dec 2016 14:30:24 -0800
    Subject: [PATCH] VFS: Fix CID 702320 & 1397511 USE_AFTER_FREE
    
    Make sure to incriment the node's ref_count before calling
    vnode_path_to_vnode() which always decriments the nodes
    ref_count. This prevents the node from being freed until
    after it has been used.
    
    Check vnode_path_to_vnode() error only in isDir condition.
    ---
     src/tools/fs_shell/vfs.cpp | 22 ++++++++++++++++------
     1 file changed, 16 insertions(+), 6 deletions(-)
    
    diff --git a/src/tools/fs_shell/vfs.cpp b/src/tools/fs_shell/vfs.cpp
    index 5137ddd..22e9642 100644
    a b entry_ref_to_vnode(fssh_mount_id mountID, fssh_vnode_id directoryID, const char  
    10541054    if (status < 0)
    10551055        return status;
    10561056
    1057     return vnode_path_to_vnode(directory, clonedName, false, 0, _vnode, NULL);
     1057    inc_vnode_ref_count(directory);
     1058        // increment directory ref_count before calling vnode_path_to_vnode()
     1059    status = vnode_path_to_vnode(directory, clonedName, false, 0, _vnode, NULL);
     1060        // vnode_path_to_vnode() decrements directory ref_count
     1061    put_vnode(directory);
     1062        // decrement directory ref_count again, freeing it but not _vnode
     1063
     1064    return status;
    10581065}
    10591066
    10601067
    vfs_normalize_path(const char *path, char *buffer, fssh_size_t bufferSize,  
    26312638    // if the leaf is "." or "..", we directly get the correct directory
    26322639    // vnode and ignore the leaf later
    26332640    bool isDir = (fssh_strcmp(leaf, ".") == 0 || fssh_strcmp(leaf, "..") == 0);
    2634     if (isDir)
     2641    if (isDir) {
     2642        inc_vnode_ref_count(dirNode);
    26352643        error = vnode_path_to_vnode(dirNode, leaf, false, 0, &dirNode, NULL);
    2636     if (error != FSSH_B_OK) {
    2637         TRACE(("vfs_normalize_path(): failed to get dir vnode for \".\" or \"..\": %s\n",
    2638             strerror(error)));
    2639         return error;
     2644            // vnode_path_to_vnode() decrements dirNode ref_count
     2645        if (error != FSSH_B_OK) {
     2646            TRACE(("vfs_normalize_path(): failed to get dir vnode for \".\" or "
     2647                "\"..\": %s\n", strerror(error)));
     2648            return error;
     2649        }
    26402650    }
    26412651
    26422652    // get the directory path