hrev52783 adds 1 changeset to branch 'master'
old head: a4f5124fcc523b6551d15edf0d149c23a26484cb
new head: cb0d3bd34190c1a23890827d07e5080a6971fb1b
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=cb0d3bd34190+%5Ea4f5124fcc52
----------------------------------------------------------------------------
cb0d3bd34190: kernel/fs/vfs: add truncation check for user_strlcpy calls
**Lots** of syscalls here don't check if strlcpy truncated the user
supplied argument. This commit adds them where appropriate.
Closes #2642
Change-Id: Iff89055aeb3a1870c8baf327b60873ce85815cd7
Reviewed-on: https://review.haiku-os.org/c/890
Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>
[ Leorize <leorize+oss@xxxxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev52783
Commit: cb0d3bd34190c1a23890827d07e5080a6971fb1b
URL: https://git.haiku-os.org/haiku/commit/?id=cb0d3bd34190
Author: Leorize <leorize+oss@xxxxxxxxxxx>
Date: Tue Jan 22 10:33:44 2019 UTC
Committer: Adrien Destugues <pulkomandy@xxxxxxxxx>
Commit-Date: Tue Jan 22 17:00:05 2019 UTC
Ticket: https://dev.haiku-os.org/ticket/2642
----------------------------------------------------------------------------
1 file changed, 165 insertions(+), 98 deletions(-)
src/system/kernel/fs/vfs.cpp | 263 ++++++++++++++++++++++++---------------
----------------------------------------------------------------------------
diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp
index c28608847f..081db510cd 100644
--- a/src/system/kernel/fs/vfs.cpp
+++ b/src/system/kernel/fs/vfs.cpp
@@ -8104,6 +8104,18 @@ err:
}
+static status_t
+user_copy_name(char* to, const char* from, size_t length)
+{
+ ssize_t len = user_strlcpy(to, from, length);
+ if (len < 0)
+ return len;
+ if (len >= (ssize_t)length)
+ return B_NAME_TOO_LONG;
+ return B_OK;
+}
+
+
// #pragma mark - kernel mirrored syscalls
@@ -8744,17 +8756,23 @@ _user_mount(const char* userPath, const char*
userDevice,
if (path.InitCheck() != B_OK || device.InitCheck() != B_OK)
return B_NO_MEMORY;
- if (user_strlcpy(path.LockBuffer(), userPath, B_PATH_NAME_LENGTH) <
B_OK)
- return B_BAD_ADDRESS;
+ status = user_copy_name(path.LockBuffer(), userPath,
+ B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
- if (userFileSystem != NULL
- && user_strlcpy(fileSystem, userFileSystem, sizeof(fileSystem))
< B_OK)
- return B_BAD_ADDRESS;
+ if (userFileSystem != NULL) {
+ status = user_copy_name(fileSystem, userFileSystem,
sizeof(fileSystem));
+ if (status != B_OK)
+ return status;
+ }
- if (userDevice != NULL
- && user_strlcpy(device.LockBuffer(), userDevice,
B_PATH_NAME_LENGTH)
- < B_OK)
- return B_BAD_ADDRESS;
+ if (userDevice != NULL) {
+ status = user_copy_name(device.LockBuffer(), userDevice,
+ B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
+ }
if (userArgs != NULL && argsLength > 0) {
if (!IS_USER_ADDRESS(userArgs))
@@ -8768,9 +8786,10 @@ _user_mount(const char* userPath, const char* userDevice,
if (args == NULL)
return B_NO_MEMORY;
- if (user_strlcpy(args, userArgs, argsLength + 1) < B_OK) {
+ status = user_copy_name(args, userArgs, argsLength + 1);
+ if (status != B_OK) {
free(args);
- return B_BAD_ADDRESS;
+ return status;
}
}
path.UnlockBuffer();
@@ -8798,8 +8817,9 @@ _user_unmount(const char* userPath, uint32 flags)
char* path = pathBuffer.LockBuffer();
- if (user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
- return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
return fs_unmount(path, -1, flags & ~B_UNMOUNT_BUSY_PARTITION, false);
}
@@ -8920,11 +8940,9 @@ _user_entry_ref_to_path(dev_t device, ino_t inode, const
char* leaf,
if (!IS_USER_ADDRESS(leaf))
return B_BAD_ADDRESS;
- int length = user_strlcpy(stackLeaf, leaf, B_FILE_NAME_LENGTH);
- if (length < 0)
- return length;
- if (length >= B_FILE_NAME_LENGTH)
- return B_NAME_TOO_LONG;
+ int status = user_copy_name(stackLeaf, leaf,
B_FILE_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
leaf = stackLeaf;
}
@@ -8960,8 +8978,9 @@ _user_normalize_path(const char* userPath, bool
traverseLink, char* buffer)
return B_NO_MEMORY;
char* path = pathBuffer.LockBuffer();
- if (user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
- return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
status_t error = normalize_path(path, pathBuffer.BufferSize(),
traverseLink,
false);
@@ -8987,9 +9006,11 @@ _user_open_entry_ref(dev_t device, ino_t inode, const
char* userName,
if (userName == NULL || device < 0 || inode < 0)
return B_BAD_VALUE;
- if (!IS_USER_ADDRESS(userName)
- || user_strlcpy(name, userName, sizeof(name)) < B_OK)
+ if (!IS_USER_ADDRESS(userName))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(name, userName, sizeof(name));
+ if (status != B_OK)
+ return status;
if ((openMode & O_CREAT) != 0) {
return file_create_entry_ref(device, inode, name, openMode,
perms,
@@ -9009,9 +9030,11 @@ _user_open(int fd, const char* userPath, int openMode,
int perms)
char* buffer = path.LockBuffer();
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(buffer, userPath, B_PATH_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(buffer, userPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
if ((openMode & O_CREAT) != 0)
return file_create(fd, buffer, openMode, perms, false);
@@ -9026,9 +9049,11 @@ _user_open_dir_entry_ref(dev_t device, ino_t inode,
const char* userName)
if (userName != NULL) {
char name[B_FILE_NAME_LENGTH];
- if (!IS_USER_ADDRESS(userName)
- || user_strlcpy(name, userName, sizeof(name)) < B_OK)
+ if (!IS_USER_ADDRESS(userName))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(name, userName, sizeof(name));
+ if (status != B_OK)
+ return status;
return dir_open_entry_ref(device, inode, name, false);
}
@@ -9048,9 +9073,11 @@ _user_open_dir(int fd, const char* userPath)
char* buffer = path.LockBuffer();
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(buffer, userPath, B_PATH_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(buffer, userPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
return dir_open(fd, buffer, false);
}
@@ -9214,8 +9241,8 @@ _user_create_dir_entry_ref(dev_t device, ino_t inode,
const char* userName,
if (!IS_USER_ADDRESS(userName))
return B_BAD_ADDRESS;
- status = user_strlcpy(name, userName, sizeof(name));
- if (status < 0)
+ status = user_copy_name(name, userName, sizeof(name));
+ if (status != B_OK)
return status;
return dir_create_entry_ref(device, inode, name, perms, false);
@@ -9231,9 +9258,11 @@ _user_create_dir(int fd, const char* userPath, int perms)
char* path = pathBuffer.LockBuffer();
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
return dir_create(fd, path, perms, false);
}
@@ -9249,9 +9278,11 @@ _user_remove_dir(int fd, const char* userPath)
char* path = pathBuffer.LockBuffer();
if (userPath != NULL) {
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) <
B_OK)
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath,
B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
}
return dir_remove(fd, userPath ? path : NULL, false);
@@ -9276,9 +9307,11 @@ _user_read_link(int fd, const char* userPath, char*
userBuffer,
char* buffer = linkBuffer.LockBuffer();
if (userPath) {
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) <
B_OK)
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath,
B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
if (bufferSize > B_PATH_NAME_LENGTH)
bufferSize = B_PATH_NAME_LENGTH;
@@ -9314,11 +9347,14 @@ _user_create_symlink(int fd, const char* userPath,
const char* userToPath,
char* path = pathBuffer.LockBuffer();
char* toPath = toPathBuffer.LockBuffer();
- if (!IS_USER_ADDRESS(userPath)
- || !IS_USER_ADDRESS(userToPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK
- || user_strlcpy(toPath, userToPath, B_PATH_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userPath) || !IS_USER_ADDRESS(userToPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
+ status = user_copy_name(toPath, userToPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
return common_create_symlink(fd, path, toPath, mode, false);
}
@@ -9336,13 +9372,16 @@ _user_create_link(int pathFD, const char* userPath, int
toFD,
char* path = pathBuffer.LockBuffer();
char* toPath = toPathBuffer.LockBuffer();
- if (!IS_USER_ADDRESS(userPath)
- || !IS_USER_ADDRESS(userToPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK
- || user_strlcpy(toPath, userToPath, B_PATH_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userPath) || !IS_USER_ADDRESS(userToPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
+ status = user_copy_name(toPath, userToPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
- status_t status = check_path(toPath);
+ status = check_path(toPath);
if (status != B_OK)
return status;
@@ -9360,9 +9399,11 @@ _user_unlink(int fd, const char* userPath)
char* path = pathBuffer.LockBuffer();
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
return common_unlink(fd, path, false);
}
@@ -9380,10 +9421,14 @@ _user_rename(int oldFD, const char* userOldPath, int
newFD,
char* oldPath = oldPathBuffer.LockBuffer();
char* newPath = newPathBuffer.LockBuffer();
- if (!IS_USER_ADDRESS(userOldPath) || !IS_USER_ADDRESS(userNewPath)
- || user_strlcpy(oldPath, userOldPath, B_PATH_NAME_LENGTH) < B_OK
- || user_strlcpy(newPath, userNewPath, B_PATH_NAME_LENGTH) <
B_OK)
+ if (!IS_USER_ADDRESS(userOldPath) || !IS_USER_ADDRESS(userNewPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(oldPath, userOldPath,
B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
+ status = user_copy_name(newPath, userNewPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
return common_rename(oldFD, oldPath, newFD, newPath, false);
}
@@ -9398,15 +9443,16 @@ _user_create_fifo(int fd, const char* userPath, mode_t
perms)
char* path = pathBuffer.LockBuffer();
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK) {
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
- }
+ status_t status = user_copy_name(path, userPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
// split into directory vnode and filename path
char filename[B_FILE_NAME_LENGTH];
struct vnode* dir;
- status_t status = fd_and_path_to_dir_vnode(fd, path, &dir, filename,
false);
+ status = fd_and_path_to_dir_vnode(fd, path, &dir, filename, false);
if (status != B_OK)
return status;
@@ -9493,9 +9539,11 @@ _user_access(int fd, const char* userPath, int mode,
bool effectiveUserGroup)
char* path = pathBuffer.LockBuffer();
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
return common_access(fd, path, mode, effectiveUserGroup, false);
}
@@ -9525,11 +9573,9 @@ _user_read_stat(int fd, const char* userPath, bool
traverseLink,
char* path = pathBuffer.LockBuffer();
- ssize_t length = user_strlcpy(path, userPath,
B_PATH_NAME_LENGTH);
- if (length < B_OK)
- return length;
- if (length >= B_PATH_NAME_LENGTH)
- return B_NAME_TOO_LONG;
+ status_t status = user_copy_name(path, userPath,
B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
status = common_path_read_stat(fd, path, traverseLink, &stat,
false);
} else {
@@ -9584,11 +9630,9 @@ _user_write_stat(int fd, const char* userPath, bool
traverseLeafLink,
char* path = pathBuffer.LockBuffer();
- ssize_t length = user_strlcpy(path, userPath,
B_PATH_NAME_LENGTH);
- if (length < B_OK)
- return length;
- if (length >= B_PATH_NAME_LENGTH)
- return B_NAME_TOO_LONG;
+ status_t status = user_copy_name(path, userPath,
B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
status = common_path_write_stat(fd, path, traverseLeafLink,
&stat,
statMask, false);
@@ -9622,9 +9666,11 @@ _user_open_attr_dir(int fd, const char* userPath, bool
traverseLeafLink)
char* path = pathBuffer.LockBuffer();
if (userPath != NULL) {
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) <
B_OK)
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath,
B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
}
return attr_dir_open(fd, userPath ? path : NULL, traverseLeafLink,
false);
@@ -9639,10 +9685,11 @@ _user_read_attr(int fd, const char* userAttribute,
off_t pos, void* userBuffer,
if (userAttribute == NULL)
return B_BAD_VALUE;
- if (!IS_USER_ADDRESS(userAttribute)
- || user_strlcpy(attribute, userAttribute, sizeof(attribute)) <
B_OK) {
+ if (!IS_USER_ADDRESS(userAttribute))
return B_BAD_ADDRESS;
- }
+ status_t status = user_copy_name(attribute, userAttribute,
sizeof(attribute));
+ if (status != B_OK)
+ return status;
int attr = attr_open(fd, NULL, attribute, O_RDONLY, false);
if (attr < 0)
@@ -9663,10 +9710,11 @@ _user_write_attr(int fd, const char* userAttribute,
uint32 type, off_t pos,
if (userAttribute == NULL)
return B_BAD_VALUE;
- if (!IS_USER_ADDRESS(userAttribute)
- || user_strlcpy(attribute, userAttribute, sizeof(attribute)) <
B_OK) {
+ if (!IS_USER_ADDRESS(userAttribute))
return B_BAD_ADDRESS;
- }
+ status_t status = user_copy_name(attribute, userAttribute,
sizeof(attribute));
+ if (status != B_OK)
+ return status;
// Try to support the BeOS typical truncation as well as the position
// argument
@@ -9690,10 +9738,12 @@ _user_stat_attr(int fd, const char* userAttribute,
if (userAttribute == NULL || userAttrInfo == NULL)
return B_BAD_VALUE;
- if (!IS_USER_ADDRESS(userAttribute) || !IS_USER_ADDRESS(userAttrInfo)
- || user_strlcpy(attribute, userAttribute, sizeof(attribute)) <
B_OK) {
+ if (!IS_USER_ADDRESS(userAttribute) || !IS_USER_ADDRESS(userAttrInfo))
return B_BAD_ADDRESS;
- }
+ status_t status = user_copy_name(attribute, userAttribute,
+ sizeof(attribute));
+ if (status != B_OK)
+ return status;
int attr = attr_open(fd, NULL, attribute, O_RDONLY, false);
if (attr < 0)
@@ -9707,7 +9757,6 @@ _user_stat_attr(int fd, const char* userAttribute,
}
struct stat stat;
- status_t status;
if (descriptor->ops->fd_read_stat)
status = descriptor->ops->fd_read_stat(descriptor, &stat);
else
@@ -9735,9 +9784,11 @@ _user_open_attr(int fd, const char* userPath, const
char* userName,
{
char name[B_FILE_NAME_LENGTH];
- if (!IS_USER_ADDRESS(userName)
- || user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userName))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(name, userName, B_FILE_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
if (pathBuffer.InitCheck() != B_OK)
@@ -9746,9 +9797,11 @@ _user_open_attr(int fd, const char* userPath, const
char* userName,
char* path = pathBuffer.LockBuffer();
if (userPath != NULL) {
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) <
B_OK)
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
+ status = user_copy_name(path, userPath, B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
}
if ((openMode & O_CREAT) != 0) {
@@ -9765,9 +9818,11 @@ _user_remove_attr(int fd, const char* userName)
{
char name[B_FILE_NAME_LENGTH];
- if (!IS_USER_ADDRESS(userName)
- || user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userName))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(name, userName, B_FILE_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
return attr_remove(fd, name, false);
}
@@ -9789,9 +9844,12 @@ _user_rename_attr(int fromFile, const char*
userFromName, int toFile,
char* fromName = fromNameBuffer.LockBuffer();
char* toName = toNameBuffer.LockBuffer();
- if (user_strlcpy(fromName, userFromName, B_FILE_NAME_LENGTH) < B_OK
- || user_strlcpy(toName, userToName, B_FILE_NAME_LENGTH) < B_OK)
- return B_BAD_ADDRESS;
+ status_t status = user_copy_name(fromName, userFromName,
B_FILE_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
+ status = user_copy_name(toName, userToName, B_FILE_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
return attr_rename(fromFile, fromName, toFile, toName, false);
}
@@ -9810,9 +9868,11 @@ _user_create_index(dev_t device, const char* userName,
uint32 type,
{
char name[B_FILE_NAME_LENGTH];
- if (!IS_USER_ADDRESS(userName)
- || user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userName))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(name, userName, B_FILE_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
return index_create(device, name, type, flags, false);
}
@@ -9825,10 +9885,11 @@ _user_read_index_stat(dev_t device, const char*
userName, struct stat* userStat)
struct stat stat;
status_t status;
- if (!IS_USER_ADDRESS(userName)
- || !IS_USER_ADDRESS(userStat)
- || user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userName) || !IS_USER_ADDRESS(userStat))
return B_BAD_ADDRESS;
+ status = user_copy_name(name, userName, B_FILE_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
status = index_name_read_stat(device, name, &stat, false);
if (status == B_OK) {
@@ -9845,9 +9906,11 @@ _user_remove_index(dev_t device, const char* userName)
{
char name[B_FILE_NAME_LENGTH];
- if (!IS_USER_ADDRESS(userName)
- || user_strlcpy(name, userName, B_FILE_NAME_LENGTH) < B_OK)
+ if (!IS_USER_ADDRESS(userName))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(name, userName, B_FILE_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
return index_remove(device, name, false);
}
@@ -9896,9 +9959,11 @@ _user_setcwd(int fd, const char* userPath)
char* path = pathBuffer.LockBuffer();
if (userPath != NULL) {
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) <
B_OK)
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath,
B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
}
return set_cwd(fd, userPath != NULL ? path : NULL, false);
@@ -9920,9 +9985,11 @@ _user_change_root(const char* userPath)
// copy userland path to kernel
char* path = pathBuffer.LockBuffer();
if (userPath != NULL) {
- if (!IS_USER_ADDRESS(userPath)
- || user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) <
B_OK)
+ if (!IS_USER_ADDRESS(userPath))
return B_BAD_ADDRESS;
+ status_t status = user_copy_name(path, userPath,
B_PATH_NAME_LENGTH);
+ if (status != B_OK)
+ return status;
}
// get the vnode