PR/53103: Timo Buhrmester: linux emulation of sendto(2) broken

The sockargs refactoring broke it, because sockargs only works with a user
address. Added an argument to sockargs to indicate where the address is
coming from. Welcome to 8.99.14.
This commit is contained in:
christos 2018-03-16 17:25:04 +00:00
parent 870d92dc2a
commit 8cb1b0010b
8 changed files with 47 additions and 33 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: uipc_syscalls_43.c,v 1.47 2016/09/13 07:01:07 martin Exp $ */
/* $NetBSD: uipc_syscalls_43.c,v 1.48 2018/03/16 17:25:04 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1990, 1993
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls_43.c,v 1.47 2016/09/13 07:01:07 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls_43.c,v 1.48 2018/03/16 17:25:04 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -343,7 +343,8 @@ compat_43_sys_sendmsg(struct lwp *l, const struct compat_43_sys_sendmsg_args *ua
msg.msg_iovlen = omsg.msg_iovlen;
msg.msg_iov = omsg.msg_iov;
error = sockargs(&nam, omsg.msg_name, omsg.msg_namelen, MT_SONAME);
error = sockargs(&nam, omsg.msg_name, omsg.msg_namelen,
UIO_USERSPACE, MT_SONAME);
if (error != 0)
return (error);

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_socket.c,v 1.139 2017/11/22 10:19:14 ozaki-r Exp $ */
/* $NetBSD: linux_socket.c,v 1.140 2018/03/16 17:25:04 christos Exp $ */
/*-
* Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.139 2017/11/22 10:19:14 ozaki-r Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.140 2018/03/16 17:25:04 christos Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@ -401,6 +401,7 @@ linux_sys_sendto(struct lwp *l, const struct linux_sys_sendto_args *uap, registe
struct msghdr msg;
struct iovec aiov;
struct sockaddr_big nam;
struct mbuf *m;
int bflags;
int error;
@ -419,9 +420,13 @@ linux_sys_sendto(struct lwp *l, const struct linux_sys_sendto_args *uap, registe
error = linux_get_sa(l, SCARG(uap, s), &nam, SCARG(uap, to),
SCARG(uap, tolen));
if (error)
return (error);
msg.msg_name = &nam;
msg.msg_namelen = SCARG(uap, tolen);
return error;
error = sockargs(&m, &nam, nam.sb_len, UIO_SYSSPACE, MT_SONAME);
if (error)
return error;
msg.msg_flags |= MSG_NAMEMBUF;
msg.msg_name = m;
msg.msg_namelen = nam.sb_len;
}
msg.msg_iov = &aiov;

View File

@ -1,4 +1,4 @@
/* $NetBSD: netbsd32_compat_43.c,v 1.54 2016/09/13 07:01:07 martin Exp $ */
/* $NetBSD: netbsd32_compat_43.c,v 1.55 2018/03/16 17:25:04 christos Exp $ */
/*
* Copyright (c) 1998, 2001 Matthew R. Green
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_43.c,v 1.54 2016/09/13 07:01:07 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_43.c,v 1.55 2018/03/16 17:25:04 christos Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_43.h"
@ -529,7 +529,7 @@ compat_43_netbsd32_osendmsg(struct lwp *l, const struct compat_43_netbsd32_osend
msg.msg_flags = MSG_NAMEMBUF;
error = sockargs(&nam, NETBSD32PTR64(omsg.msg_name), omsg.msg_namelen,
MT_SONAME);
UIO_USERSPACE, MT_SONAME);
if (error != 0)
goto out;

View File

@ -1,4 +1,4 @@
/* $NetBSD: uipc_syscalls.c,v 1.191 2018/02/12 16:01:35 maxv Exp $ */
/* $NetBSD: uipc_syscalls.c,v 1.192 2018/03/16 17:25:04 christos Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.191 2018/02/12 16:01:35 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.192 2018/03/16 17:25:04 christos Exp $");
#ifdef _KERNEL_OPT
#include "opt_pipe.h"
@ -593,7 +593,7 @@ do_sys_sendmsg_so(struct lwp *l, int s, struct socket *so, file_t *fp,
if (mp->msg_name && to == NULL) {
error = sockargs(&to, mp->msg_name, mp->msg_namelen,
MT_SONAME);
UIO_USERSPACE, MT_SONAME);
if (error)
goto bad;
}
@ -605,7 +605,7 @@ do_sys_sendmsg_so(struct lwp *l, int s, struct socket *so, file_t *fp,
}
if (control == NULL) {
error = sockargs(&control, mp->msg_control,
mp->msg_controllen, MT_CONTROL);
mp->msg_controllen, UIO_USERSPACE, MT_CONTROL);
if (error)
goto bad;
}
@ -1529,7 +1529,8 @@ sockargs_sb(struct sockaddr_big *sb, const void *name, socklen_t buflen)
* XXX arguments in mbufs, and this could go away.
*/
int
sockargs(struct mbuf **mp, const void *bf, size_t buflen, int type)
sockargs(struct mbuf **mp, const void *bf, size_t buflen, enum uio_seg seg,
int type)
{
struct sockaddr *sa;
struct mbuf *m;
@ -1560,12 +1561,16 @@ sockargs(struct mbuf **mp, const void *bf, size_t buflen, int type)
MEXTMALLOC(m, buflen, M_WAITOK);
}
m->m_len = buflen;
error = copyin(bf, mtod(m, void *), buflen);
if (error) {
(void)m_free(m);
return error;
if (seg == UIO_USERSPACE) {
error = copyin(bf, mtod(m, void *), buflen);
if (error) {
(void)m_free(m);
return error;
}
ktrkuser(mbuftypes[type], mtod(m, void *), buflen);
} else {
memcpy(mtod(m, void *), bf, buflen);
}
ktrkuser(mbuftypes[type], mtod(m, void *), buflen);
*mp = m;
if (type == MT_SONAME) {
sa = mtod(m, struct sockaddr *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_syscalls.c,v 1.159 2018/01/25 17:14:36 riastradh Exp $ */
/* $NetBSD: nfs_syscalls.c,v 1.160 2018/03/16 17:25:04 christos Exp $ */
/*
* Copyright (c) 1989, 1993
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.159 2018/01/25 17:14:36 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.160 2018/03/16 17:25:04 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -332,7 +332,7 @@ do_nfssvc(struct nfssvc_copy_ops *ops, struct lwp *l, int flag, void *argp, regi
nam = (struct mbuf *)0;
else {
error = sockargs(&nam, nfsdarg.name, nfsdarg.namelen,
MT_SONAME);
UIO_USERSPACE, MT_SONAME);
if (error) {
fd_putfile(nfsdarg.sock);
return (error);

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_vfsops.c,v 1.235 2017/04/17 08:32:01 hannken Exp $ */
/* $NetBSD: nfs_vfsops.c,v 1.236 2018/03/16 17:25:04 christos Exp $ */
/*
* Copyright (c) 1989, 1993, 1995
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_vfsops.c,v 1.235 2017/04/17 08:32:01 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_vfsops.c,v 1.236 2018/03/16 17:25:04 christos Exp $");
#if defined(_KERNEL_OPT)
#include "opt_nfs.h"
@ -670,7 +670,8 @@ nfs_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
goto free_hst;
memset(&hst[len], 0, MNAMELEN - len);
/* sockargs() call must be after above copyin() calls */
error = sockargs(&nam, args->addr, args->addrlen, MT_SONAME);
error = sockargs(&nam, args->addr, args->addrlen, UIO_USERSPACE,
MT_SONAME);
if (error)
goto free_hst;
MCLAIM(nam, &nfs_mowner);

View File

@ -1,4 +1,4 @@
/* $NetBSD: param.h,v 1.558 2018/03/15 00:48:13 christos Exp $ */
/* $NetBSD: param.h,v 1.559 2018/03/16 17:25:04 christos Exp $ */
/*-
* Copyright (c) 1982, 1986, 1989, 1993
@ -67,7 +67,7 @@
* 2.99.9 (299000900)
*/
#define __NetBSD_Version__ 899001300 /* NetBSD 8.99.13 */
#define __NetBSD_Version__ 899001400 /* NetBSD 8.99.14 */
#define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
(m) * 1000000) + (p) * 100) <= __NetBSD_Version__)

View File

@ -1,4 +1,4 @@
/* $NetBSD: socketvar.h,v 1.146 2018/01/04 01:42:25 christos Exp $ */
/* $NetBSD: socketvar.h,v 1.147 2018/03/16 17:25:04 christos Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -249,11 +249,13 @@ struct msghdr;
struct stat;
struct knote;
struct sockaddr_big;
enum uio_seg;
struct mbuf *getsombuf(struct socket *, int);
/* 0x400 is SO_OTIMESTAMP */
#define SOOPT_TIMESTAMP(o) ((o) & (SO_TIMESTAMP | 0x400))
#define SOOPT_TIMESTAMP(o) \
((o) & (SO_TIMESTAMP | 0x400 /*SO_OTIMESTAMP*/ | \
SO_TIMESTAMPNS | SO_TIMESTAMPING))
/*
* File operations on sockets.
@ -330,7 +332,7 @@ int so_setsockopt(struct lwp *, struct socket *, int, int, const void *, size_t)
int soshutdown(struct socket *, int);
void sorestart(struct socket *);
void sowakeup(struct socket *, struct sockbuf *, int);
int sockargs(struct mbuf **, const void *, size_t, int);
int sockargs(struct mbuf **, const void *, size_t, enum uio_seg, int);
int sopoll(struct socket *, int);
struct socket *soget(bool);
void soput(struct socket *);