Validate user-supplied arguments values.

Args argument is a pointer to the structure located in user space in
which the socketcall arguments are packed. The structure must be
copied to the kernel instead of direct dereferencing.

Approved by:	kib (mentor)
MFC after:	1 week
This commit is contained in:
Dmitry Chagin 2009-05-19 09:10:53 +00:00
parent 7b6d3d4c7b
commit ea7b81d2bd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=192373

View File

@ -1467,11 +1467,38 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
return (error);
}
/* Argument list sizes for linux_socketcall */
#define LINUX_AL(x) ((x) * sizeof(l_ulong))
static const unsigned char lxs_args[] = {
LINUX_AL(0) /* unused*/, LINUX_AL(3) /* socket */,
LINUX_AL(3) /* bind */, LINUX_AL(3) /* connect */,
LINUX_AL(2) /* listen */, LINUX_AL(3) /* accept */,
LINUX_AL(3) /* getsockname */, LINUX_AL(3) /* getpeername */,
LINUX_AL(4) /* socketpair */, LINUX_AL(4) /* send */,
LINUX_AL(4) /* recv */, LINUX_AL(6) /* sendto */,
LINUX_AL(6) /* recvfrom */, LINUX_AL(2) /* shutdown */,
LINUX_AL(5) /* setsockopt */, LINUX_AL(5) /* getsockopt */,
LINUX_AL(3) /* sendmsg */, LINUX_AL(3) /* recvmsg */
};
#define LINUX_AL_SIZE sizeof(lxs_args) / sizeof(lxs_args[0]) - 1
int
linux_socketcall(struct thread *td, struct linux_socketcall_args *args)
{
void *arg = (void *)(intptr_t)args->args;
l_ulong a[6];
void *arg;
int error;
if (args->what < LINUX_SOCKET || args->what > LINUX_AL_SIZE)
return (EINVAL);
error = copyin(PTRIN(args->args), a, lxs_args[args->what]);
if (error)
return (error);
arg = a;
switch (args->what) {
case LINUX_SOCKET:
return (linux_socket(td, arg));