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
|
1054 | 1054 | if (status < 0) |
1055 | 1055 | return status; |
1056 | 1056 | |
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; |
1058 | 1065 | } |
1059 | 1066 | |
1060 | 1067 | |
… |
… |
vfs_normalize_path(const char *path, char *buffer, fssh_size_t bufferSize,
|
2631 | 2638 | // if the leaf is "." or "..", we directly get the correct directory |
2632 | 2639 | // vnode and ignore the leaf later |
2633 | 2640 | bool isDir = (fssh_strcmp(leaf, ".") == 0 || fssh_strcmp(leaf, "..") == 0); |
2634 | | if (isDir) |
| 2641 | if (isDir) { |
| 2642 | inc_vnode_ref_count(dirNode); |
2635 | 2643 | 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 | } |
2640 | 2650 | } |
2641 | 2651 | |
2642 | 2652 | // get the directory path |