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> References: <200905190910.n4J9Arvs090603@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
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: > =A0Validate user-supplied arguments values. > =A0Args argument is a pointer to the structure located in user space in > =A0which the socketcall arguments are packed. The structure must be > =A0copied to the kernel instead of direct dereferencing. > > =A0Approved by: =A0kib (mentor) > =A0MFC after: =A0 =A01 week > > Modified: > =A0head/sys/compat/linux/linux_socket.c > > Modified: head/sys/compat/linux/linux_socket.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- head/sys/compat/linux/linux_socket.c =A0 =A0 =A0 =A0Tue May 19 05:36:= 10 2009 =A0 =A0 =A0 =A0(r192372) > +++ head/sys/compat/linux/linux_socket.c =A0 =A0 =A0 =A0Tue May 19 09:10:= 53 2009 =A0 =A0 =A0 =A0(r192373) > @@ -1467,11 +1467,38 @@ linux_getsockopt(struct thread *td, stru > =A0 =A0 =A0 =A0return (error); > =A0} > > +/* Argument list sizes for linux_socketcall */ > + > +#define LINUX_AL(x) ((x) * sizeof(l_ulong)) > + > +static const unsigned char lxs_args[] =3D { > + =A0 =A0 =A0 LINUX_AL(0) /* unused*/, =A0 =A0 =A0 =A0LINUX_AL(3) /* sock= et */, > + =A0 =A0 =A0 LINUX_AL(3) /* bind */, =A0 =A0 =A0 =A0 LINUX_AL(3) /* conn= ect */, > + =A0 =A0 =A0 LINUX_AL(2) /* listen */, =A0 =A0 =A0 LINUX_AL(3) /* accept= */, > + =A0 =A0 =A0 LINUX_AL(3) /* getsockname */, =A0LINUX_AL(3) /* getpeernam= e */, > + =A0 =A0 =A0 LINUX_AL(4) /* socketpair */, =A0 LINUX_AL(4) /* send */, > + =A0 =A0 =A0 LINUX_AL(4) /* recv */, =A0 =A0 =A0 =A0 LINUX_AL(6) /* send= to */, > + =A0 =A0 =A0 LINUX_AL(6) /* recvfrom */, =A0 =A0 LINUX_AL(2) /* shutdown= */, > + =A0 =A0 =A0 LINUX_AL(5) /* setsockopt */, =A0 LINUX_AL(5) /* getsockopt= */, > + =A0 =A0 =A0 LINUX_AL(3) /* sendmsg */, =A0 =A0 =A0LINUX_AL(3) /* recvms= g */ > +}; > + > +#define =A0 =A0 =A0 =A0LINUX_AL_SIZE =A0 sizeof(lxs_args) / sizeof(lxs_a= rgs[0]) - 1 > + > =A0int > =A0linux_socketcall(struct thread *td, struct linux_socketcall_args *args= ) > =A0{ > - =A0 =A0 =A0 void *arg =3D (void *)(intptr_t)args->args; > + =A0 =A0 =A0 l_ulong a[6]; > + =A0 =A0 =A0 void *arg; > + =A0 =A0 =A0 int error; > + > + =A0 =A0 =A0 if (args->what < LINUX_SOCKET || args->what > LINUX_AL_SIZE= ) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (EINVAL); > + =A0 =A0 =A0 error =3D copyin(PTRIN(args->args), a, lxs_args[args->what]= ); > + =A0 =A0 =A0 if (error) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (error); > > + =A0 =A0 =A0 arg =3D a; > =A0 =A0 =A0 =A0switch (args->what) { > =A0 =A0 =A0 =A0case LINUX_SOCKET: > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return (linux_socket(td, arg)); What factors go into deciding to do bounds-checking before the copyin versu= s after the copyin? Naively, I would be worried about the userland data chan= ging out from under the kernel, but I'm not terribly familiar with this area. Thanks, Ben Kaduk
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?47d0403c0905191319w77c8849t5dca0b297b292a34>