mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 19:49:43 +00:00
linux-user: fix conversion of flock/flock64 l_type field
As l_type values (F_RDLCK, F_WRLCK, F_UNLCK, F_EXLCK, F_SHLCK) are not bitmasks, we can't use target_to_host_bitmask() and host_to_target_bitmask() to convert them. Introduce target_to_host_flock() and host_to_target_flock() to convert values between host and target. Signed-off-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Max Filippov <jcmvbkbc@gmail.com> Message-Id: <20180509231123.20864-5-laurent@vivier.eu>
This commit is contained in:
parent
534cdbf56c
commit
ae68ad9fee
@ -6546,28 +6546,50 @@ static int target_to_host_fcntl_cmd(int cmd)
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
|
||||
#define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
|
||||
static const bitmask_transtbl flock_tbl[] = {
|
||||
TRANSTBL_CONVERT(F_RDLCK),
|
||||
TRANSTBL_CONVERT(F_WRLCK),
|
||||
TRANSTBL_CONVERT(F_UNLCK),
|
||||
TRANSTBL_CONVERT(F_EXLCK),
|
||||
TRANSTBL_CONVERT(F_SHLCK),
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
#define FLOCK_TRANSTBL \
|
||||
switch (type) { \
|
||||
TRANSTBL_CONVERT(F_RDLCK); \
|
||||
TRANSTBL_CONVERT(F_WRLCK); \
|
||||
TRANSTBL_CONVERT(F_UNLCK); \
|
||||
TRANSTBL_CONVERT(F_EXLCK); \
|
||||
TRANSTBL_CONVERT(F_SHLCK); \
|
||||
}
|
||||
|
||||
static int target_to_host_flock(int type)
|
||||
{
|
||||
#define TRANSTBL_CONVERT(a) case TARGET_##a: return a
|
||||
FLOCK_TRANSTBL
|
||||
#undef TRANSTBL_CONVERT
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
|
||||
static int host_to_target_flock(int type)
|
||||
{
|
||||
#define TRANSTBL_CONVERT(a) case a: return TARGET_##a
|
||||
FLOCK_TRANSTBL
|
||||
#undef TRANSTBL_CONVERT
|
||||
/* if we don't know how to convert the value coming
|
||||
* from the host we copy to the target field as-is
|
||||
*/
|
||||
return type;
|
||||
}
|
||||
|
||||
static inline abi_long copy_from_user_flock(struct flock64 *fl,
|
||||
abi_ulong target_flock_addr)
|
||||
{
|
||||
struct target_flock *target_fl;
|
||||
short l_type;
|
||||
int l_type;
|
||||
|
||||
if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
|
||||
__get_user(l_type, &target_fl->l_type);
|
||||
fl->l_type = target_to_host_bitmask(l_type, flock_tbl);
|
||||
l_type = target_to_host_flock(l_type);
|
||||
if (l_type < 0) {
|
||||
return l_type;
|
||||
}
|
||||
fl->l_type = l_type;
|
||||
__get_user(fl->l_whence, &target_fl->l_whence);
|
||||
__get_user(fl->l_start, &target_fl->l_start);
|
||||
__get_user(fl->l_len, &target_fl->l_len);
|
||||
@ -6586,7 +6608,7 @@ static inline abi_long copy_to_user_flock(abi_ulong target_flock_addr,
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
|
||||
l_type = host_to_target_bitmask(fl->l_type, flock_tbl);
|
||||
l_type = host_to_target_flock(fl->l_type);
|
||||
__put_user(l_type, &target_fl->l_type);
|
||||
__put_user(fl->l_whence, &target_fl->l_whence);
|
||||
__put_user(fl->l_start, &target_fl->l_start);
|
||||
@ -6604,14 +6626,18 @@ static inline abi_long copy_from_user_oabi_flock64(struct flock64 *fl,
|
||||
abi_ulong target_flock_addr)
|
||||
{
|
||||
struct target_oabi_flock64 *target_fl;
|
||||
short l_type;
|
||||
int l_type;
|
||||
|
||||
if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
|
||||
__get_user(l_type, &target_fl->l_type);
|
||||
fl->l_type = target_to_host_bitmask(l_type, flock_tbl);
|
||||
l_type = target_to_host_flock(l_type);
|
||||
if (l_type < 0) {
|
||||
return l_type;
|
||||
}
|
||||
fl->l_type = l_type;
|
||||
__get_user(fl->l_whence, &target_fl->l_whence);
|
||||
__get_user(fl->l_start, &target_fl->l_start);
|
||||
__get_user(fl->l_len, &target_fl->l_len);
|
||||
@ -6630,7 +6656,7 @@ static inline abi_long copy_to_user_oabi_flock64(abi_ulong target_flock_addr,
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
|
||||
l_type = host_to_target_bitmask(fl->l_type, flock_tbl);
|
||||
l_type = host_to_target_flock(fl->l_type);
|
||||
__put_user(l_type, &target_fl->l_type);
|
||||
__put_user(fl->l_whence, &target_fl->l_whence);
|
||||
__put_user(fl->l_start, &target_fl->l_start);
|
||||
@ -6645,14 +6671,18 @@ static inline abi_long copy_from_user_flock64(struct flock64 *fl,
|
||||
abi_ulong target_flock_addr)
|
||||
{
|
||||
struct target_flock64 *target_fl;
|
||||
short l_type;
|
||||
int l_type;
|
||||
|
||||
if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
|
||||
__get_user(l_type, &target_fl->l_type);
|
||||
fl->l_type = target_to_host_bitmask(l_type, flock_tbl);
|
||||
l_type = target_to_host_flock(l_type);
|
||||
if (l_type < 0) {
|
||||
return l_type;
|
||||
}
|
||||
fl->l_type = l_type;
|
||||
__get_user(fl->l_whence, &target_fl->l_whence);
|
||||
__get_user(fl->l_start, &target_fl->l_start);
|
||||
__get_user(fl->l_len, &target_fl->l_len);
|
||||
@ -6671,7 +6701,7 @@ static inline abi_long copy_to_user_flock64(abi_ulong target_flock_addr,
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
|
||||
l_type = host_to_target_bitmask(fl->l_type, flock_tbl);
|
||||
l_type = host_to_target_flock(fl->l_type);
|
||||
__put_user(l_type, &target_fl->l_type);
|
||||
__put_user(fl->l_whence, &target_fl->l_whence);
|
||||
__put_user(fl->l_start, &target_fl->l_start);
|
||||
|
Loading…
Reference in New Issue
Block a user