kernel/x86_64: compatibility syscalls for vfs.cpp.
* define compat_flock, compat_timespec, compat_stat, compat_attr_info, compat_fs_info, compat_fd_info to be used for respective 32-bit types of syscalls in compatibility mode. * handle 32-bit types in common_fcntl(), _user_read_stat(), _user_stat_attr(), _user_read_index_stat, _user_read_fs_info, _user_write_fs_info, _user_get_next_fd_info, other syscalls are compatible as is. Change-Id: I5b372169fe142f67b81fd6c27e0627d5119ba687
This commit is contained in:
parent
c6e120e2d2
commit
2ffbe7aaca
74
headers/private/kernel/compat/fcntl_compat.h
Normal file
74
headers/private/kernel/compat/fcntl_compat.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_COMPAT_FCNTL_H
|
||||
#define _KERNEL_COMPAT_FCNTL_H
|
||||
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
struct compat_flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
off_t l_start;
|
||||
off_t l_len;
|
||||
pid_t l_pid;
|
||||
} _PACKED;
|
||||
|
||||
|
||||
static_assert(sizeof(struct compat_flock) == 24,
|
||||
"size of compat_flock mismatch");
|
||||
|
||||
|
||||
inline status_t
|
||||
copy_ref_var_from_user(struct flock* userFlock, struct flock &flock)
|
||||
{
|
||||
if (!IS_USER_ADDRESS(userFlock))
|
||||
return B_BAD_ADDRESS;
|
||||
Thread* thread = thread_get_current_thread();
|
||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
||||
if (compatMode) {
|
||||
compat_flock compat_flock;
|
||||
if (user_memcpy(&compat_flock, userFlock, sizeof(compat_flock)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
flock.l_type = compat_flock.l_type;
|
||||
flock.l_whence = compat_flock.l_whence;
|
||||
flock.l_start = compat_flock.l_start;
|
||||
flock.l_len = compat_flock.l_len;
|
||||
flock.l_pid = compat_flock.l_pid;
|
||||
} else {
|
||||
if (user_memcpy(&flock, userFlock, sizeof(struct flock)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
inline status_t
|
||||
copy_ref_var_to_user(struct flock &flock, struct flock* userFlock)
|
||||
{
|
||||
if (!IS_USER_ADDRESS(userFlock))
|
||||
return B_BAD_ADDRESS;
|
||||
Thread* thread = thread_get_current_thread();
|
||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
||||
if (compatMode) {
|
||||
compat_flock compat_flock;
|
||||
compat_flock.l_type = flock.l_type;
|
||||
compat_flock.l_whence = flock.l_whence;
|
||||
compat_flock.l_start = flock.l_start;
|
||||
compat_flock.l_len = flock.l_len;
|
||||
compat_flock.l_pid = flock.l_pid;
|
||||
if (user_memcpy(userFlock, &compat_flock, sizeof(compat_flock)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
} else {
|
||||
if (user_memcpy(userFlock, &flock, sizeof(flock)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif // _KERNEL_COMPAT_FCNTL_H
|
44
headers/private/kernel/compat/fs_attr_compat.h
Normal file
44
headers/private/kernel/compat/fs_attr_compat.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_COMPAT_FS_ATTR_H
|
||||
#define _KERNEL_COMPAT_FS_ATTR_H
|
||||
|
||||
|
||||
#include <fs_attr.h>
|
||||
|
||||
|
||||
struct compat_attr_info {
|
||||
uint32 type;
|
||||
off_t size;
|
||||
} _PACKED;
|
||||
|
||||
|
||||
static_assert(sizeof(compat_attr_info) == 12,
|
||||
"size of compat_attr_info mismatch");
|
||||
|
||||
|
||||
inline status_t
|
||||
copy_ref_var_to_user(attr_info &info, attr_info* userInfo)
|
||||
{
|
||||
if (!IS_USER_ADDRESS(userInfo))
|
||||
return B_BAD_ADDRESS;
|
||||
Thread* thread = thread_get_current_thread();
|
||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
||||
if (compatMode) {
|
||||
compat_attr_info compat_info;
|
||||
compat_info.type = info.type;
|
||||
compat_info.size = info.size;
|
||||
if (user_memcpy(userInfo, &compat_info, sizeof(compat_info)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
} else {
|
||||
if (user_memcpy(userInfo, &info, sizeof(info)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif // _KERNEL_COMPAT_FS_ATTR_H
|
94
headers/private/kernel/compat/fs_info_compat.h
Normal file
94
headers/private/kernel/compat/fs_info_compat.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_COMPAT_FS_INFO_H
|
||||
#define _KERNEL_COMPAT_FS_INFO_H
|
||||
|
||||
|
||||
#include <fs_info.h>
|
||||
|
||||
|
||||
typedef struct compat_fs_info {
|
||||
dev_t dev; /* volume dev_t */
|
||||
ino_t root; /* root ino_t */
|
||||
uint32 flags; /* flags (see above) */
|
||||
off_t block_size; /* fundamental block size */
|
||||
off_t io_size; /* optimal i/o size */
|
||||
off_t total_blocks; /* total number of blocks */
|
||||
off_t free_blocks; /* number of free blocks */
|
||||
off_t total_nodes; /* total number of nodes */
|
||||
off_t free_nodes; /* number of free nodes */
|
||||
char device_name[128]; /* device holding fs */
|
||||
char volume_name[B_FILE_NAME_LENGTH]; /* volume name */
|
||||
char fsh_name[B_OS_NAME_LENGTH]; /* name of fs handler */
|
||||
} _PACKED compat_fs_info;
|
||||
|
||||
|
||||
static_assert(sizeof(compat_fs_info) == 480,
|
||||
"size of compat_fs_info mismatch");
|
||||
|
||||
|
||||
inline status_t
|
||||
copy_ref_var_to_user(fs_info &info, fs_info* userInfo)
|
||||
{
|
||||
if (!IS_USER_ADDRESS(userInfo))
|
||||
return B_BAD_ADDRESS;
|
||||
Thread* thread = thread_get_current_thread();
|
||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
||||
if (compatMode) {
|
||||
compat_fs_info compat_info;
|
||||
compat_info.dev = info.dev;
|
||||
compat_info.root = info.root;
|
||||
compat_info.flags = info.flags;
|
||||
compat_info.block_size = info.block_size;
|
||||
compat_info.io_size = info.io_size;
|
||||
compat_info.total_blocks = info.total_blocks;
|
||||
compat_info.free_blocks = info.free_blocks;
|
||||
compat_info.total_nodes = info.total_nodes;
|
||||
compat_info.free_nodes = info.free_nodes;
|
||||
strlcpy(compat_info.device_name, info.device_name, 128);
|
||||
strlcpy(compat_info.volume_name, info.volume_name, B_FILE_NAME_LENGTH);
|
||||
strlcpy(compat_info.fsh_name, info.fsh_name, B_OS_NAME_LENGTH);
|
||||
if (user_memcpy(userInfo, &compat_info, sizeof(compat_info)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
} else {
|
||||
if (user_memcpy(userInfo, &info, sizeof(info)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
inline status_t
|
||||
copy_ref_var_from_user(fs_info* userInfo, fs_info &info)
|
||||
{
|
||||
if (!IS_USER_ADDRESS(userInfo))
|
||||
return B_BAD_ADDRESS;
|
||||
Thread* thread = thread_get_current_thread();
|
||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
||||
if (compatMode) {
|
||||
compat_fs_info compat_info;
|
||||
if (user_memcpy(&compat_info, userInfo, sizeof(compat_info)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
info.dev = compat_info.dev;
|
||||
info.root = compat_info.root;
|
||||
info.flags = compat_info.flags;
|
||||
info.block_size = compat_info.block_size;
|
||||
info.io_size = compat_info.io_size;
|
||||
info.total_blocks = compat_info.total_blocks;
|
||||
info.free_blocks = compat_info.free_blocks;
|
||||
info.total_nodes = compat_info.total_nodes;
|
||||
info.free_nodes = compat_info.free_nodes;
|
||||
strlcpy(info.device_name, compat_info.device_name, 128);
|
||||
strlcpy(info.volume_name, compat_info.volume_name, B_FILE_NAME_LENGTH);
|
||||
strlcpy(info.fsh_name, compat_info.fsh_name, B_OS_NAME_LENGTH);
|
||||
} else if (user_memcpy(&info, userInfo, sizeof(info)) < B_OK) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif // _KERNEL_COMPAT_FS_INFO_H
|
117
headers/private/kernel/compat/stat_compat.h
Normal file
117
headers/private/kernel/compat/stat_compat.h
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_COMPAT_STAT_H
|
||||
#define _KERNEL_COMPAT_STAT_H
|
||||
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <time_compat.h>
|
||||
|
||||
|
||||
struct compat_stat {
|
||||
dev_t st_dev; /* device ID that this file resides on */
|
||||
ino_t st_ino; /* this file's serial inode ID */
|
||||
mode_t st_mode; /* file mode (rwx for user, group, etc) */
|
||||
nlink_t st_nlink; /* number of hard links to this file */
|
||||
uid_t st_uid; /* user ID of the owner of this file */
|
||||
gid_t st_gid; /* group ID of the owner of this file */
|
||||
off_t st_size; /* size in bytes of this file */
|
||||
dev_t st_rdev; /* device type (not used) */
|
||||
blksize_t st_blksize; /* preferred block size for I/O */
|
||||
struct compat_timespec st_atim; /* last access time */
|
||||
struct compat_timespec st_mtim; /* last modification time */
|
||||
struct compat_timespec st_ctim; /* last change time, not creation time */
|
||||
struct compat_timespec st_crtim; /* creation time */
|
||||
__haiku_uint32 st_type; /* attribute/index type */
|
||||
blkcnt_t st_blocks; /* number of blocks allocated for object */
|
||||
} _PACKED;
|
||||
|
||||
|
||||
static_assert(sizeof(struct compat_stat) == 88,
|
||||
"size of struct compat_stat mismatch");
|
||||
|
||||
|
||||
inline status_t
|
||||
copy_ref_var_to_user(struct stat &stat, struct stat* userStat, size_t size)
|
||||
{
|
||||
if (!IS_USER_ADDRESS(userStat))
|
||||
return B_BAD_ADDRESS;
|
||||
Thread* thread = thread_get_current_thread();
|
||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
||||
if (compatMode) {
|
||||
if (size > sizeof(compat_stat))
|
||||
return B_BAD_VALUE;
|
||||
struct compat_stat compat_stat;
|
||||
compat_stat.st_dev = stat.st_dev;
|
||||
compat_stat.st_ino = stat.st_ino;
|
||||
compat_stat.st_mode = stat.st_mode;
|
||||
compat_stat.st_nlink = stat.st_nlink;
|
||||
compat_stat.st_uid = stat.st_gid;
|
||||
compat_stat.st_size = stat.st_size;
|
||||
compat_stat.st_rdev = stat.st_rdev;
|
||||
compat_stat.st_blksize = stat.st_blksize;
|
||||
compat_stat.st_atim.tv_sec = stat.st_atim.tv_sec;
|
||||
compat_stat.st_atim.tv_nsec = stat.st_atim.tv_nsec;
|
||||
compat_stat.st_mtim.tv_sec = stat.st_mtim.tv_sec;
|
||||
compat_stat.st_mtim.tv_nsec = stat.st_mtim.tv_nsec;
|
||||
compat_stat.st_ctim.tv_sec = stat.st_ctim.tv_sec;
|
||||
compat_stat.st_ctim.tv_nsec = stat.st_ctim.tv_nsec;
|
||||
compat_stat.st_crtim.tv_sec = stat.st_crtim.tv_sec;
|
||||
compat_stat.st_crtim.tv_nsec = stat.st_crtim.tv_nsec;
|
||||
compat_stat.st_type = stat.st_type;
|
||||
compat_stat.st_blocks = stat.st_blocks;
|
||||
if (user_memcpy(userStat, &compat_stat, size) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
} else {
|
||||
if (size > sizeof(struct stat))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (user_memcpy(userStat, &stat, size) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
inline status_t
|
||||
copy_ref_var_to_user(struct stat &stat, struct stat* userStat)
|
||||
{
|
||||
if (!IS_USER_ADDRESS(userStat))
|
||||
return B_BAD_ADDRESS;
|
||||
Thread* thread = thread_get_current_thread();
|
||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
||||
if (compatMode) {
|
||||
struct compat_stat compat_stat;
|
||||
compat_stat.st_dev = stat.st_dev;
|
||||
compat_stat.st_ino = stat.st_ino;
|
||||
compat_stat.st_mode = stat.st_mode;
|
||||
compat_stat.st_nlink = stat.st_nlink;
|
||||
compat_stat.st_uid = stat.st_gid;
|
||||
compat_stat.st_size = stat.st_size;
|
||||
compat_stat.st_rdev = stat.st_rdev;
|
||||
compat_stat.st_blksize = stat.st_blksize;
|
||||
compat_stat.st_atim.tv_sec = stat.st_atim.tv_sec;
|
||||
compat_stat.st_atim.tv_nsec = stat.st_atim.tv_nsec;
|
||||
compat_stat.st_mtim.tv_sec = stat.st_mtim.tv_sec;
|
||||
compat_stat.st_mtim.tv_nsec = stat.st_mtim.tv_nsec;
|
||||
compat_stat.st_ctim.tv_sec = stat.st_ctim.tv_sec;
|
||||
compat_stat.st_ctim.tv_nsec = stat.st_ctim.tv_nsec;
|
||||
compat_stat.st_crtim.tv_sec = stat.st_crtim.tv_sec;
|
||||
compat_stat.st_crtim.tv_nsec = stat.st_crtim.tv_nsec;
|
||||
compat_stat.st_type = stat.st_type;
|
||||
compat_stat.st_blocks = stat.st_blocks;
|
||||
if (user_memcpy(userStat, &compat_stat, sizeof(compat_stat)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
} else {
|
||||
if (user_memcpy(userStat, &stat, sizeof(stat)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // _KERNEL_COMPAT_STAT_H
|
19
headers/private/kernel/compat/time_compat.h
Normal file
19
headers/private/kernel/compat/time_compat.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_COMPAT_TIME_H
|
||||
#define _KERNEL_COMPAT_TIME_H
|
||||
|
||||
|
||||
#include <time.h>
|
||||
|
||||
|
||||
struct compat_timespec {
|
||||
uint32 tv_sec; /* seconds */
|
||||
uint32 tv_nsec; /* and nanoseconds */
|
||||
};
|
||||
|
||||
|
||||
#endif // _KERNEL_COMPAT_TIME_H
|
79
headers/private/kernel/compat/vfs_defs_compat.h
Normal file
79
headers/private/kernel/compat/vfs_defs_compat.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_COMPAT_VFS_DEFS_H
|
||||
#define _KERNEL_COMPAT_VFS_DEFS_H
|
||||
|
||||
|
||||
#include <vfs_defs.h>
|
||||
|
||||
|
||||
struct compat_fd_info {
|
||||
int number;
|
||||
int32 open_mode;
|
||||
dev_t device;
|
||||
ino_t node;
|
||||
} _PACKED;
|
||||
|
||||
|
||||
static_assert(sizeof(compat_fd_info) == 20,
|
||||
"size of compat_fd_info mismatch");
|
||||
|
||||
|
||||
inline status_t
|
||||
copy_ref_var_to_user(attr_info &info, attr_info* userInfo, size_t size)
|
||||
{
|
||||
if (!IS_USER_ADDRESS(userInfo))
|
||||
return B_BAD_ADDRESS;
|
||||
Thread* thread = thread_get_current_thread();
|
||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
||||
if (compatMode) {
|
||||
if (size != sizeof(compat_fd_info))
|
||||
return B_BAD_VALUE;
|
||||
compat_fd_info compat_info;
|
||||
compat_info.number = info.number;
|
||||
compat_info.open_mode = info.open_mode;
|
||||
compat_info.device = info.device;
|
||||
compat_info.node = info.node;
|
||||
if (user_memcpy(userInfo, &compat_info, size) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
} else {
|
||||
if (size != sizeof(fd_info))
|
||||
return B_BAD_VALUE;
|
||||
if (user_memcpy(userInfo, &info, size) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
inline status_t
|
||||
copy_ref_var_from_user(fd_info* userInfo, fd_info &info, size_t size)
|
||||
{
|
||||
if (!IS_USER_ADDRESS(userInfo))
|
||||
return B_BAD_ADDRESS;
|
||||
Thread* thread = thread_get_current_thread();
|
||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
||||
if (compatMode) {
|
||||
if (size != sizeof(compat_fd_info))
|
||||
return B_BAD_VALUE;
|
||||
compat_fd_info compat_info;
|
||||
if (user_memcpy(&compat_info, userInfo, size) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
info.number = compat_info.number;
|
||||
info.open_mode = compat_info.open_mode;
|
||||
info.device = compat_info.device;
|
||||
info.node = compat_info.node;
|
||||
} else {
|
||||
if (size != sizeof(fd_info))
|
||||
return B_BAD_VALUE;
|
||||
if (user_memcpy(&info, userInfo, size) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif // _KERNEL_COMPAT_VFS_DEFS_H
|
@ -49,11 +49,19 @@
|
||||
#include <util/atomic.h>
|
||||
#include <util/AutoLock.h>
|
||||
#include <util/DoublyLinkedList.h>
|
||||
#include <util/syscall_args.h>
|
||||
#include <vfs.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/VMCache.h>
|
||||
#include <wait_for_objects.h>
|
||||
|
||||
#ifdef _COMPAT_MODE
|
||||
# include <fcntl_compat.h>
|
||||
# include <stat_compat.h>
|
||||
# include <fs_attr_compat.h>
|
||||
# include <fs_info_compat.h>
|
||||
#endif
|
||||
|
||||
#include "EntryCache.h"
|
||||
#include "fifo.h"
|
||||
#include "IORequest.h"
|
||||
@ -6116,10 +6124,8 @@ common_fcntl(int fd, int op, size_t argument, bool kernel)
|
||||
if (op == F_SETLK || op == F_SETLKW || op == F_GETLK) {
|
||||
if (descriptor->type != FDTYPE_FILE)
|
||||
status = B_BAD_VALUE;
|
||||
else if (user_memcpy(&flock, (struct flock*)argument,
|
||||
sizeof(struct flock)) != B_OK)
|
||||
status = B_BAD_ADDRESS;
|
||||
|
||||
else
|
||||
status = copy_ref_var_from_user((struct flock*)argument, flock);
|
||||
if (status != B_OK) {
|
||||
put_fd(descriptor);
|
||||
return status;
|
||||
@ -8798,10 +8804,7 @@ _user_read_fs_info(dev_t device, struct fs_info* userInfo)
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (user_memcpy(userInfo, &info, sizeof(struct fs_info)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
return B_OK;
|
||||
return copy_ref_var_to_user(info, userInfo);
|
||||
}
|
||||
|
||||
|
||||
@ -8813,9 +8816,9 @@ _user_write_fs_info(dev_t device, const struct fs_info* userInfo, int mask)
|
||||
if (userInfo == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (!IS_USER_ADDRESS(userInfo)
|
||||
|| user_memcpy(&info, userInfo, sizeof(struct fs_info)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
status_t status = copy_ref_var_from_user((struct fs_info*)userInfo, info);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return fs_write_info(device, &info, mask);
|
||||
}
|
||||
@ -8861,9 +8864,6 @@ _user_get_next_fd_info(team_id team, uint32* userCookie, fd_info* userInfo,
|
||||
if (geteuid() != 0)
|
||||
return B_NOT_ALLOWED;
|
||||
|
||||
if (infoSize != sizeof(fd_info))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (!IS_USER_ADDRESS(userCookie) || !IS_USER_ADDRESS(userInfo)
|
||||
|| user_memcpy(&cookie, userCookie, sizeof(uint32)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
@ -8872,11 +8872,9 @@ _user_get_next_fd_info(team_id team, uint32* userCookie, fd_info* userInfo,
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (user_memcpy(userCookie, &cookie, sizeof(uint32)) != B_OK
|
||||
|| user_memcpy(userInfo, &info, infoSize) != B_OK)
|
||||
if (user_memcpy(userCookie, &cookie, sizeof(uint32)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
return status;
|
||||
return copy_ref_var_to_user(info, userInfo);
|
||||
}
|
||||
|
||||
|
||||
@ -9527,7 +9525,7 @@ _user_read_stat(int fd, const char* userPath, bool traverseLink,
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return user_memcpy(userStat, &stat, statSize);
|
||||
return copy_ref_var_to_user(stat, userStat, statSize);
|
||||
}
|
||||
|
||||
|
||||
@ -9698,8 +9696,7 @@ _user_stat_attr(int fd, const char* userAttribute,
|
||||
info.type = stat.st_type;
|
||||
info.size = stat.st_size;
|
||||
|
||||
if (user_memcpy(userAttrInfo, &info, sizeof(struct attr_info)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
status = copy_ref_var_to_user(info, userAttrInfo);
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -9808,10 +9805,8 @@ _user_read_index_stat(dev_t device, const char* userName, struct stat* userStat)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
status = index_name_read_stat(device, name, &stat, false);
|
||||
if (status == B_OK) {
|
||||
if (user_memcpy(userStat, &stat, sizeof(stat)) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
if (status == B_OK)
|
||||
status = copy_ref_var_to_user(stat, userStat);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user