Skip site navigation (1)Skip section navigation (2)
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>