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:
Axel Dörfler
2006-04-18 17:40:27 +00:00
parent cbdbfd3a80
commit 4827dbe47a
+26 -5
View File
@@ -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)) {