Fix fchownat(2) system call ABI on x86.

This system call has five arguments, of which one is a 64-bit uid_t, and
another is a 64-bit gid_t, which means that 7 registers are needed. However,
x86 only has 5 registers available for system calls. Wrap the system call
with a structure like with mmap(2).
This commit is contained in:
Jonas 'Sortie' Termansen 2016-03-26 12:36:07 +01:00
parent 1083e67d45
commit 05282c86d7
4 changed files with 59 additions and 3 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, 2013, 2014, 2015 Jonas 'Sortie' Termansen.
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -46,6 +46,9 @@
namespace Sortix {
#if defined(__i386__)
struct fchownat_request;
#endif
struct mmap_request;
int sys_accept4(int, void*, size_t*, int);
@ -71,6 +74,9 @@ int sys_fchmod(int, mode_t);
int sys_fchmodat(int, const char*, mode_t, int);
int sys_fchown(int, uid_t, gid_t);
int sys_fchownat(int, const char*, uid_t, gid_t, int);
#if defined(__i386__)
int sys_fchownat_wrapper(const struct fchownat_request*);
#endif
int sys_fchroot(int);
int sys_fchrootat(int, const char*);
int sys_fcntl(int, int, uintptr_t);

View File

@ -472,6 +472,26 @@ int sys_fchownat(int dirfd, const char* path, uid_t owner, gid_t group, int flag
return desc->chown(&ctx, owner, group);
}
#if defined(__i386__)
struct fchownat_request /* duplicated in libc/unistd/fchownat.c */
{
int dirfd;
const char* path;
uid_t owner;
gid_t group;
int flags;
};
int sys_fchownat_wrapper(const struct fchownat_request* user_request)
{
struct fchownat_request request;
if ( !CopyFromUser(&request, user_request, sizeof(request)) )
return -1;
return sys_fchownat(request.dirfd, request.path, request.owner,
request.group, request.flags);
}
#endif
int sys_fchmod(int fd, mode_t mode)
{
Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, 2013, 2014, 2015 Jonas 'Sortie' Termansen.
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -96,7 +96,11 @@ void* syscall_list[SYSCALL_MAX_NUM + 1] =
[SYSCALL_MKDIRAT] = (void*) sys_mkdirat,
[SYSCALL_FCHDIR] = (void*) sys_fchdir,
[SYSCALL_TRUNCATEAT] = (void*) sys_truncateat,
#if !defined(__i386__)
[SYSCALL_FCHOWNAT] = (void*) sys_fchownat,
#else
[SYSCALL_FCHOWNAT] = (void*) sys_fchownat_wrapper,
#endif
[SYSCALL_FCHOWN] = (void*) sys_fchown,
[SYSCALL_FCHMOD] = (void*) sys_fchmod,
[SYSCALL_FCHMODAT] = (void*) sys_fchmodat,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012 Jonas 'Sortie' Termansen.
* Copyright (c) 2012, 2016 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -23,9 +23,35 @@
#include <fcntl.h>
#include <unistd.h>
#if !defined(__i386__)
DEFN_SYSCALL5(int, sys_fchownat, SYSCALL_FCHOWNAT, int, const char*, uid_t, gid_t, int);
int fchownat(int dirfd, const char* path, uid_t owner, gid_t group, int flags)
{
return sys_fchownat(dirfd, path, owner, group, flags);
}
#else
// TODO: The i386 system call ABI doesn't have enough registers to do this with
// 64-bit uid_t and gid_t.
struct fchownat_request /* duplicated in kernel/io.cpp */
{
int dirfd;
const char* path;
uid_t owner;
gid_t group;
int flags;
};
DEFN_SYSCALL1(int, sys_fchownat_wrapper, SYSCALL_FCHOWNAT, const struct fchownat_request*);
int fchownat(int dirfd, const char* path, uid_t owner, gid_t group, int flags)
{
struct fchownat_request request = { dirfd, path, owner, group, flags };
return sys_fchownat_wrapper(&request);
}
#endif