Date: Tue, 19 May 2009 16:19:56 -0400 From: Ben Kaduk <minimarmot@gmail.com> To: Dmitry Chagin <dchagin@freebsd.org> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r192373 - head/sys/compat/linux Message-ID: <47d0403c0905191319w77c8849t5dca0b297b292a34@mail.gmail.com> In-Reply-To: <200905190910.n4J9Arvs090603@svn.freebsd.org>
index | next in thread | previous in thread | raw e-mail
On Tue, May 19, 2009 at 5:10 AM, Dmitry Chagin <dchagin@freebsd.org> wrote: > Author: dchagin > Date: Tue May 19 09:10:53 2009 > New Revision: 192373 > URL: http://svn.freebsd.org/changeset/base/192373 > > Log: > 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 > > Modified: > head/sys/compat/linux/linux_socket.c > > Modified: head/sys/compat/linux/linux_socket.c > ============================================================================== > --- head/sys/compat/linux/linux_socket.c Tue May 19 05:36:10 2009 (r192372) > +++ head/sys/compat/linux/linux_socket.c Tue May 19 09:10:53 2009 (r192373) > @@ -1467,11 +1467,38 @@ linux_getsockopt(struct thread *td, stru > 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)); What factors go into deciding to do bounds-checking before the copyin versus after the copyin? Naively, I would be worried about the userland data changing out from under the kernel, but I'm not terribly familiar with this area. Thanks, Ben Kadukhome | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?47d0403c0905191319w77c8849t5dca0b297b292a34>
