trim: Added is_called_via_syscall() function.
* And use it in get_trim_data_from_user(), formerly known as copy_*(). * This fixes differentiating between user and kernel buffers.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2011, Haiku Inc. All rights reserved.
|
||||
* Copyright 2008-2013, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_SYSCALL_RESTART_H
|
||||
@@ -100,6 +100,20 @@ syscall_restart_is_restarted()
|
||||
}
|
||||
|
||||
|
||||
/*! Returns whether or not a function has been called via a syscall. The flag
|
||||
to determine this is currently only used where actually needed, such as
|
||||
ioctl().
|
||||
|
||||
TODO: this function is actually needed as part of the public API for ioctl()
|
||||
*/
|
||||
static inline bool
|
||||
is_called_via_syscall(void)
|
||||
{
|
||||
Thread* thread = thread_get_current_thread();
|
||||
return (thread->flags & THREAD_FLAGS_SYSCALL) != 0;
|
||||
}
|
||||
|
||||
|
||||
struct SyscallFlagUnsetter {
|
||||
SyscallFlagUnsetter()
|
||||
{
|
||||
|
||||
@@ -6,14 +6,23 @@
|
||||
#define _FS_TRIM_SUPPORT_H
|
||||
|
||||
|
||||
#include <Drivers.h>
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <kernel.h>
|
||||
#include <syscall_restart.h>
|
||||
|
||||
|
||||
static inline status_t
|
||||
copy_trim_data_from_user(void* buffer, size_t size, fs_trim_data*& _trimData)
|
||||
get_trim_data_from_user(void* buffer, size_t size, MemoryDeleter& deleter,
|
||||
fs_trim_data*& _trimData)
|
||||
{
|
||||
if (!is_called_via_syscall() && !IS_USER_ADDRESS(buffer)) {
|
||||
// Called from kernel
|
||||
_trimData = (fs_trim_data*)buffer;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// Called from userland
|
||||
if (!IS_USER_ADDRESS(buffer))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
@@ -29,8 +38,10 @@ copy_trim_data_from_user(void* buffer, size_t size, fs_trim_data*& _trimData)
|
||||
if (trimBuffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
if (user_memcpy(trimBuffer, buffer, bytes) != B_OK)
|
||||
if (user_memcpy(trimBuffer, buffer, bytes) != B_OK) {
|
||||
free(trimBuffer);
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
_trimData = (fs_trim_data*)trimBuffer;
|
||||
return B_OK;
|
||||
@@ -40,6 +51,12 @@ copy_trim_data_from_user(void* buffer, size_t size, fs_trim_data*& _trimData)
|
||||
static inline status_t
|
||||
copy_trim_data_to_user(void* buffer, fs_trim_data* trimData)
|
||||
{
|
||||
if (!is_called_via_syscall() && !IS_USER_ADDRESS(buffer))
|
||||
return B_OK;
|
||||
|
||||
if (!IS_USER_ADDRESS(buffer))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
// Do not copy any ranges
|
||||
return user_memcpy(buffer, trimData, sizeof(uint64) * 2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user