Fixed a bug in the VFS that could cause BFS to corrupt an inode:
dir_remove() did not normalize the path, and thus, could forward a "." as name for the removed directory - which BFS didn't catch because it assumed our VFS would work correctly... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17165 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -836,10 +836,9 @@ restart:
|
||||
mutex_unlock(&sVnodeMutex);
|
||||
|
||||
status = FS_CALL(vnode, get_vnode)(vnode->mount->cookie, vnodeID, &vnode->private_node, reenter);
|
||||
if (status < B_OK || vnode->private_node == NULL) {
|
||||
if (status == B_NO_ERROR)
|
||||
status = B_BAD_VALUE;
|
||||
}
|
||||
if (status == B_OK && vnode->private_node == NULL)
|
||||
status = B_BAD_VALUE;
|
||||
|
||||
mutex_lock(&sVnodeMutex);
|
||||
|
||||
if (status < B_OK)
|
||||
@@ -3992,8 +3991,30 @@ dir_remove(int fd, char *path, bool kernel)
|
||||
struct vnode *directory;
|
||||
status_t status;
|
||||
|
||||
if (path != NULL) {
|
||||
// we need to make sure our path name doesn't stop with "/", ".", or ".."
|
||||
char *lastSlash = strrchr(path, '/');
|
||||
if (lastSlash != NULL) {
|
||||
char *leaf = lastSlash + 1;
|
||||
if (!strcmp(leaf, ".."))
|
||||
return B_NOT_ALLOWED;
|
||||
|
||||
// omit multiple slashes
|
||||
while (lastSlash > path && lastSlash[-1] == '/') {
|
||||
lastSlash--;
|
||||
}
|
||||
|
||||
if (!leaf[0]
|
||||
|| !strcmp(leaf, ".")) {
|
||||
// "name/" -> "name", or "name/." -> "name"
|
||||
lastSlash[0] = '\0';
|
||||
}
|
||||
} else if (!strcmp(path, ".."))
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
status = fd_and_path_to_dir_vnode(fd, path, &directory, name, kernel);
|
||||
if (status < 0)
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
if (FS_CALL(directory, remove_dir)) {
|
||||
|
||||
Reference in New Issue
Block a user