[haiku-commits] haiku: hrev52005 - headers/private/kernel/compat src/system/kernel/fs

  • From: Jérôme Duval <jerome.duval@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 12 Jun 2018 11:55:46 -0400 (EDT)

hrev52005 adds 1 changeset to branch 'master'
old head: c6e120e2d2f909d95f95839fa99fccf811fdb3c5
new head: 2ffbe7aaca8668c5a68ac7488459bace7a0700f2
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=2ffbe7aaca86+%5Ec6e120e2d2f9

----------------------------------------------------------------------------

2ffbe7aaca86: 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

                                   [ Jérôme Duval <jerome.duval@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev52005
Commit:      2ffbe7aaca8668c5a68ac7488459bace7a0700f2
URL:         https://git.haiku-os.org/haiku/commit/?id=2ffbe7aaca86
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Fri May 18 16:31:12 2018 UTC

----------------------------------------------------------------------------

7 files changed, 447 insertions(+), 25 deletions(-)
headers/private/kernel/compat/fcntl_compat.h    |  74 +++++++++++++
headers/private/kernel/compat/fs_attr_compat.h  |  44 ++++++++
headers/private/kernel/compat/fs_info_compat.h  |  94 ++++++++++++++++
headers/private/kernel/compat/stat_compat.h     | 117 ++++++++++++++++++++
headers/private/kernel/compat/time_compat.h     |  19 ++++
headers/private/kernel/compat/vfs_defs_compat.h |  79 +++++++++++++
src/system/kernel/fs/vfs.cpp                    |  45 ++++----

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/compat/fcntl_compat.h 
b/headers/private/kernel/compat/fcntl_compat.h
new file mode 100644
index 0000000000..25b38e79de
--- /dev/null
+++ b/headers/private/kernel/compat/fcntl_compat.h
@@ -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
diff --git a/headers/private/kernel/compat/fs_attr_compat.h 
b/headers/private/kernel/compat/fs_attr_compat.h
new file mode 100644
index 0000000000..b657fb9c2e
--- /dev/null
+++ b/headers/private/kernel/compat/fs_attr_compat.h
@@ -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
diff --git a/headers/private/kernel/compat/fs_info_compat.h 
b/headers/private/kernel/compat/fs_info_compat.h
new file mode 100644
index 0000000000..67934bcb29
--- /dev/null
+++ b/headers/private/kernel/compat/fs_info_compat.h
@@ -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
diff --git a/headers/private/kernel/compat/stat_compat.h 
b/headers/private/kernel/compat/stat_compat.h
new file mode 100644
index 0000000000..08f487a676
--- /dev/null
+++ b/headers/private/kernel/compat/stat_compat.h
@@ -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
diff --git a/headers/private/kernel/compat/time_compat.h 
b/headers/private/kernel/compat/time_compat.h
new file mode 100644
index 0000000000..819a79d074
--- /dev/null
+++ b/headers/private/kernel/compat/time_compat.h
@@ -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
diff --git a/headers/private/kernel/compat/vfs_defs_compat.h 
b/headers/private/kernel/compat/vfs_defs_compat.h
new file mode 100644
index 0000000000..05a79ba1cd
--- /dev/null
+++ b/headers/private/kernel/compat/vfs_defs_compat.h
@@ -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
diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp
index 4f1657a55c..192ecd1210 100644
--- a/src/system/kernel/fs/vfs.cpp
+++ b/src/system/kernel/fs/vfs.cpp
@@ -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;
 }


Other related posts:

  • » [haiku-commits] haiku: hrev52005 - headers/private/kernel/compat src/system/kernel/fs - Jérôme Duval