4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /* Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. */
27 /*
28 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
29 */
30
31 #include <sys/types.h>
32 #include <sys/t_lock.h>
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/buf.h>
36 #include <sys/conf.h>
37 #include <sys/cred.h>
38 #include <sys/kmem.h>
39 #include <sys/sysmacros.h>
40 #include <sys/vfs.h>
41 #include <sys/vnode.h>
42 #include <sys/debug.h>
43 #include <sys/errno.h>
44 #include <sys/time.h>
45 #include <sys/file.h>
46 #include <sys/user.h>
47 #include <sys/stream.h>
48 #include <sys/strsubr.h>
49 #include <sys/strsun.h>
50 #include <sys/sunddi.h>
51 #include <sys/esunddi.h>
52 #include <sys/flock.h>
53 #include <sys/modctl.h>
54 #include <sys/cmn_err.h>
55 #include <sys/vmsystm.h>
56 #include <sys/policy.h>
57
58 #include <sys/socket.h>
59 #include <sys/socketvar.h>
60
61 #include <sys/isa_defs.h>
62 #include <sys/inttypes.h>
63 #include <sys/systm.h>
64 #include <sys/cpuvar.h>
65 #include <sys/filio.h>
66 #include <sys/sendfile.h>
67 #include <sys/ddi.h>
68 #include <vm/seg.h>
69 #include <vm/seg_map.h>
70 #include <vm/seg_kpm.h>
71
72 #include <fs/sockfs/nl7c.h>
73 #include <fs/sockfs/sockcommon.h>
74 #include <fs/sockfs/sockfilter_impl.h>
75 #include <fs/sockfs/socktpi.h>
76
77 #ifdef SOCK_TEST
78 int do_useracc = 1; /* Controlled by setting SO_DEBUG to 4 */
79 #else
80 #define do_useracc 1
81 #endif /* SOCK_TEST */
82
83 extern int xnet_truncate_print;
84
85 extern void nl7c_init(void);
86 extern int sockfs_defer_nl7c_init;
87
88 /*
89 * Note: DEF_IOV_MAX is defined and used as it is in "fs/vncalls.c"
90 * as there isn't a formal definition of IOV_MAX ???
91 */
92 #define MSG_MAXIOVLEN 16
93
94 /*
95 * Kernel component of socket creation.
96 *
97 * The socket library determines which version number to use.
98 * First the library calls this with a NULL devpath. If this fails
99 * to find a transport (using solookup) the library will look in /etc/netconfig
100 * for the appropriate transport. If one is found it will pass in the
101 * devpath for the kernel to use.
102 */
103 int
104 so_socket(int family, int type_w_flags, int protocol, char *devpath,
105 int version)
106 {
107 struct sonode *so;
108 vnode_t *vp;
109 struct file *fp;
110 int fd;
111 int error;
112 int type;
113
114 type = type_w_flags & SOCK_TYPE_MASK;
1004 } else {
1005 lmsg.msg_namelen = 0;
1006 }
1007 lmsg.msg_controllen = 0;
1008 lmsg.msg_flags = 0;
1009
1010 return (recvit(sock, &lmsg, &auio, flags, namelenp, NULL, NULL));
1011 }
1012
1013 /*
1014 * Uses the MSG_XPG4_2 flag to determine if the caller is using
1015 * struct omsghdr or struct nmsghdr.
1016 */
1017 ssize_t
1018 recvmsg(int sock, struct nmsghdr *msg, int flags)
1019 {
1020 STRUCT_DECL(nmsghdr, u_lmsg);
1021 STRUCT_HANDLE(nmsghdr, umsgptr);
1022 struct nmsghdr lmsg;
1023 struct uio auio;
1024 struct iovec aiov[MSG_MAXIOVLEN];
1025 int iovcnt;
1026 ssize_t len;
1027 int i;
1028 int *flagsp;
1029 model_t model;
1030
1031 dprint(1, ("recvmsg(%d, %p, %d)\n",
1032 sock, (void *)msg, flags));
1033
1034 model = get_udatamodel();
1035 STRUCT_INIT(u_lmsg, model);
1036 STRUCT_SET_HANDLE(umsgptr, model, msg);
1037
1038 if (flags & MSG_XPG4_2) {
1039 if (copyin(msg, STRUCT_BUF(u_lmsg), STRUCT_SIZE(u_lmsg)))
1040 return (set_errno(EFAULT));
1041 flagsp = STRUCT_FADDR(umsgptr, msg_flags);
1042 } else {
1043 /*
1044 * Assumes that nmsghdr and omsghdr are identically shaped
1045 * except for the added msg_flags field.
1046 */
1049 return (set_errno(EFAULT));
1050 STRUCT_FSET(u_lmsg, msg_flags, 0);
1051 flagsp = NULL;
1052 }
1053
1054 /*
1055 * Code below us will kmem_alloc memory and hang it
1056 * off msg_control and msg_name fields. This forces
1057 * us to copy the structure to its native form.
1058 */
1059 lmsg.msg_name = STRUCT_FGETP(u_lmsg, msg_name);
1060 lmsg.msg_namelen = STRUCT_FGET(u_lmsg, msg_namelen);
1061 lmsg.msg_iov = STRUCT_FGETP(u_lmsg, msg_iov);
1062 lmsg.msg_iovlen = STRUCT_FGET(u_lmsg, msg_iovlen);
1063 lmsg.msg_control = STRUCT_FGETP(u_lmsg, msg_control);
1064 lmsg.msg_controllen = STRUCT_FGET(u_lmsg, msg_controllen);
1065 lmsg.msg_flags = STRUCT_FGET(u_lmsg, msg_flags);
1066
1067 iovcnt = lmsg.msg_iovlen;
1068
1069 if (iovcnt <= 0 || iovcnt > MSG_MAXIOVLEN) {
1070 return (set_errno(EMSGSIZE));
1071 }
1072
1073 #ifdef _SYSCALL32_IMPL
1074 /*
1075 * 32-bit callers need to have their iovec expanded, while ensuring
1076 * that they can't move more than 2Gbytes of data in a single call.
1077 */
1078 if (model == DATAMODEL_ILP32) {
1079 struct iovec32 aiov32[MSG_MAXIOVLEN];
1080 ssize32_t count32;
1081
1082 if (copyin((struct iovec32 *)lmsg.msg_iov, aiov32,
1083 iovcnt * sizeof (struct iovec32)))
1084 return (set_errno(EFAULT));
1085
1086 count32 = 0;
1087 for (i = 0; i < iovcnt; i++) {
1088 ssize32_t iovlen32;
1089
1090 iovlen32 = aiov32[i].iov_len;
1091 count32 += iovlen32;
1092 if (iovlen32 < 0 || count32 < 0)
1093 return (set_errno(EINVAL));
1094 aiov[i].iov_len = iovlen32;
1095 aiov[i].iov_base =
1096 (caddr_t)(uintptr_t)aiov32[i].iov_base;
1097 }
1098 } else
1099 #endif /* _SYSCALL32_IMPL */
1100 if (copyin(lmsg.msg_iov, aiov, iovcnt * sizeof (struct iovec))) {
1101 return (set_errno(EFAULT));
1102 }
1103 len = 0;
1104 for (i = 0; i < iovcnt; i++) {
1105 ssize_t iovlen = aiov[i].iov_len;
1106 len += iovlen;
1107 if (iovlen < 0 || len < 0) {
1108 return (set_errno(EINVAL));
1109 }
1110 }
1111 auio.uio_loffset = 0;
1112 auio.uio_iov = aiov;
1113 auio.uio_iovcnt = iovcnt;
1114 auio.uio_resid = len;
1115 auio.uio_segflg = UIO_USERSPACE;
1116 auio.uio_limit = 0;
1117
1118 if (lmsg.msg_control != NULL &&
1119 (do_useracc == 0 ||
1120 useracc(lmsg.msg_control, lmsg.msg_controllen,
1121 B_WRITE) != 0)) {
1122 return (set_errno(EFAULT));
1123 }
1124
1125 return (recvit(sock, &lmsg, &auio, flags,
1126 STRUCT_FADDR(umsgptr, msg_namelen),
1127 STRUCT_FADDR(umsgptr, msg_controllen), flagsp));
1128 }
1129
1130 /*
1131 * Common send function.
1132 */
1133 static ssize_t
1134 sendit(int sock, struct nmsghdr *msg, struct uio *uiop, int flags)
1135 {
1136 struct sonode *so;
1137 file_t *fp;
1138 void *name;
1139 socklen_t namelen;
1140 void *control;
1141 socklen_t controllen;
1142 ssize_t len;
1143 int error;
1144
1145 if ((so = getsonode(sock, &error, &fp)) == NULL)
1146 return (set_errno(error));
1147
1245 if (!(flags & MSG_XPG4_2)) {
1246 /*
1247 * In order to be compatible with the libsocket/sockmod
1248 * implementation we set EOR for all send* calls.
1249 */
1250 flags |= MSG_EOR;
1251 }
1252 return (sendit(sock, &lmsg, &auio, flags));
1253 }
1254
1255 /*
1256 * Uses the MSG_XPG4_2 flag to determine if the caller is using
1257 * struct omsghdr or struct nmsghdr.
1258 */
1259 ssize_t
1260 sendmsg(int sock, struct nmsghdr *msg, int flags)
1261 {
1262 struct nmsghdr lmsg;
1263 STRUCT_DECL(nmsghdr, u_lmsg);
1264 struct uio auio;
1265 struct iovec aiov[MSG_MAXIOVLEN];
1266 int iovcnt;
1267 ssize_t len;
1268 int i;
1269 model_t model;
1270
1271 dprint(1, ("sendmsg(%d, %p, %d)\n", sock, (void *)msg, flags));
1272
1273 model = get_udatamodel();
1274 STRUCT_INIT(u_lmsg, model);
1275
1276 if (flags & MSG_XPG4_2) {
1277 if (copyin(msg, (char *)STRUCT_BUF(u_lmsg),
1278 STRUCT_SIZE(u_lmsg)))
1279 return (set_errno(EFAULT));
1280 } else {
1281 /*
1282 * Assumes that nmsghdr and omsghdr are identically shaped
1283 * except for the added msg_flags field.
1284 */
1285 if (copyin(msg, (char *)STRUCT_BUF(u_lmsg),
1286 SIZEOF_STRUCT(omsghdr, model)))
1287 return (set_errno(EFAULT));
1290 * implementation we set EOR for all send* calls.
1291 */
1292 flags |= MSG_EOR;
1293 }
1294
1295 /*
1296 * Code below us will kmem_alloc memory and hang it
1297 * off msg_control and msg_name fields. This forces
1298 * us to copy the structure to its native form.
1299 */
1300 lmsg.msg_name = STRUCT_FGETP(u_lmsg, msg_name);
1301 lmsg.msg_namelen = STRUCT_FGET(u_lmsg, msg_namelen);
1302 lmsg.msg_iov = STRUCT_FGETP(u_lmsg, msg_iov);
1303 lmsg.msg_iovlen = STRUCT_FGET(u_lmsg, msg_iovlen);
1304 lmsg.msg_control = STRUCT_FGETP(u_lmsg, msg_control);
1305 lmsg.msg_controllen = STRUCT_FGET(u_lmsg, msg_controllen);
1306 lmsg.msg_flags = STRUCT_FGET(u_lmsg, msg_flags);
1307
1308 iovcnt = lmsg.msg_iovlen;
1309
1310 if (iovcnt <= 0 || iovcnt > MSG_MAXIOVLEN) {
1311 /*
1312 * Unless this is XPG 4.2 we allow iovcnt == 0 to
1313 * be compatible with SunOS 4.X and 4.4BSD.
1314 */
1315 if (iovcnt != 0 || (flags & MSG_XPG4_2))
1316 return (set_errno(EMSGSIZE));
1317 }
1318
1319 #ifdef _SYSCALL32_IMPL
1320 /*
1321 * 32-bit callers need to have their iovec expanded, while ensuring
1322 * that they can't move more than 2Gbytes of data in a single call.
1323 */
1324 if (model == DATAMODEL_ILP32) {
1325 struct iovec32 aiov32[MSG_MAXIOVLEN];
1326 ssize32_t count32;
1327
1328 if (iovcnt != 0 &&
1329 copyin((struct iovec32 *)lmsg.msg_iov, aiov32,
1330 iovcnt * sizeof (struct iovec32)))
1331 return (set_errno(EFAULT));
1332
1333 count32 = 0;
1334 for (i = 0; i < iovcnt; i++) {
1335 ssize32_t iovlen32;
1336
1337 iovlen32 = aiov32[i].iov_len;
1338 count32 += iovlen32;
1339 if (iovlen32 < 0 || count32 < 0)
1340 return (set_errno(EINVAL));
1341 aiov[i].iov_len = iovlen32;
1342 aiov[i].iov_base =
1343 (caddr_t)(uintptr_t)aiov32[i].iov_base;
1344 }
1345 } else
1346 #endif /* _SYSCALL32_IMPL */
1347 if (iovcnt != 0 &&
1348 copyin(lmsg.msg_iov, aiov,
1349 (unsigned)iovcnt * sizeof (struct iovec))) {
1350 return (set_errno(EFAULT));
1351 }
1352 len = 0;
1353 for (i = 0; i < iovcnt; i++) {
1354 ssize_t iovlen = aiov[i].iov_len;
1355 len += iovlen;
1356 if (iovlen < 0 || len < 0) {
1357 return (set_errno(EINVAL));
1358 }
1359 }
1360 auio.uio_loffset = 0;
1361 auio.uio_iov = aiov;
1362 auio.uio_iovcnt = iovcnt;
1363 auio.uio_resid = len;
1364 auio.uio_segflg = UIO_USERSPACE;
1365 auio.uio_limit = 0;
1366
1367 return (sendit(sock, &lmsg, &auio, flags));
1368 }
1369
1370 ssize_t
1371 sendto(int sock, void *buffer, size_t len, int flags,
1372 struct sockaddr *name, socklen_t namelen)
1373 {
1374 struct nmsghdr lmsg;
1375 struct uio auio;
1376 struct iovec aiov[1];
1377
1378 dprint(1, ("sendto(%d, %p, %ld, %d, %p, %d)\n",
1379 sock, buffer, len, flags, (void *)name, namelen));
1380
1381 if ((ssize_t)len < 0) {
1382 return (set_errno(EINVAL));
1383 }
1384
1385 aiov[0].iov_base = buffer;
1386 aiov[0].iov_len = len;
1387 auio.uio_loffset = 0;
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015, Joyent, Inc. All rights reserved.
25 * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
26 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
27 */
28
29 #include <sys/types.h>
30 #include <sys/t_lock.h>
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/buf.h>
34 #include <sys/conf.h>
35 #include <sys/cred.h>
36 #include <sys/kmem.h>
37 #include <sys/sysmacros.h>
38 #include <sys/vfs.h>
39 #include <sys/vnode.h>
40 #include <sys/debug.h>
41 #include <sys/errno.h>
42 #include <sys/time.h>
43 #include <sys/file.h>
44 #include <sys/user.h>
45 #include <sys/stream.h>
46 #include <sys/strsubr.h>
47 #include <sys/strsun.h>
48 #include <sys/sunddi.h>
49 #include <sys/esunddi.h>
50 #include <sys/flock.h>
51 #include <sys/modctl.h>
52 #include <sys/cmn_err.h>
53 #include <sys/vmsystm.h>
54 #include <sys/policy.h>
55 #include <sys/limits.h>
56
57 #include <sys/socket.h>
58 #include <sys/socketvar.h>
59
60 #include <sys/isa_defs.h>
61 #include <sys/inttypes.h>
62 #include <sys/systm.h>
63 #include <sys/cpuvar.h>
64 #include <sys/filio.h>
65 #include <sys/sendfile.h>
66 #include <sys/ddi.h>
67 #include <vm/seg.h>
68 #include <vm/seg_map.h>
69 #include <vm/seg_kpm.h>
70
71 #include <fs/sockfs/nl7c.h>
72 #include <fs/sockfs/sockcommon.h>
73 #include <fs/sockfs/sockfilter_impl.h>
74 #include <fs/sockfs/socktpi.h>
75
76 #ifdef SOCK_TEST
77 int do_useracc = 1; /* Controlled by setting SO_DEBUG to 4 */
78 #else
79 #define do_useracc 1
80 #endif /* SOCK_TEST */
81
82 extern int xnet_truncate_print;
83
84 extern void nl7c_init(void);
85 extern int sockfs_defer_nl7c_init;
86
87 /*
88 * Kernel component of socket creation.
89 *
90 * The socket library determines which version number to use.
91 * First the library calls this with a NULL devpath. If this fails
92 * to find a transport (using solookup) the library will look in /etc/netconfig
93 * for the appropriate transport. If one is found it will pass in the
94 * devpath for the kernel to use.
95 */
96 int
97 so_socket(int family, int type_w_flags, int protocol, char *devpath,
98 int version)
99 {
100 struct sonode *so;
101 vnode_t *vp;
102 struct file *fp;
103 int fd;
104 int error;
105 int type;
106
107 type = type_w_flags & SOCK_TYPE_MASK;
997 } else {
998 lmsg.msg_namelen = 0;
999 }
1000 lmsg.msg_controllen = 0;
1001 lmsg.msg_flags = 0;
1002
1003 return (recvit(sock, &lmsg, &auio, flags, namelenp, NULL, NULL));
1004 }
1005
1006 /*
1007 * Uses the MSG_XPG4_2 flag to determine if the caller is using
1008 * struct omsghdr or struct nmsghdr.
1009 */
1010 ssize_t
1011 recvmsg(int sock, struct nmsghdr *msg, int flags)
1012 {
1013 STRUCT_DECL(nmsghdr, u_lmsg);
1014 STRUCT_HANDLE(nmsghdr, umsgptr);
1015 struct nmsghdr lmsg;
1016 struct uio auio;
1017 struct iovec buf[IOV_MAX_STACK], *aiov = buf;
1018 ssize_t iovsize = 0;
1019 int iovcnt;
1020 ssize_t len, rval;
1021 int i;
1022 int *flagsp;
1023 model_t model;
1024
1025 dprint(1, ("recvmsg(%d, %p, %d)\n",
1026 sock, (void *)msg, flags));
1027
1028 model = get_udatamodel();
1029 STRUCT_INIT(u_lmsg, model);
1030 STRUCT_SET_HANDLE(umsgptr, model, msg);
1031
1032 if (flags & MSG_XPG4_2) {
1033 if (copyin(msg, STRUCT_BUF(u_lmsg), STRUCT_SIZE(u_lmsg)))
1034 return (set_errno(EFAULT));
1035 flagsp = STRUCT_FADDR(umsgptr, msg_flags);
1036 } else {
1037 /*
1038 * Assumes that nmsghdr and omsghdr are identically shaped
1039 * except for the added msg_flags field.
1040 */
1043 return (set_errno(EFAULT));
1044 STRUCT_FSET(u_lmsg, msg_flags, 0);
1045 flagsp = NULL;
1046 }
1047
1048 /*
1049 * Code below us will kmem_alloc memory and hang it
1050 * off msg_control and msg_name fields. This forces
1051 * us to copy the structure to its native form.
1052 */
1053 lmsg.msg_name = STRUCT_FGETP(u_lmsg, msg_name);
1054 lmsg.msg_namelen = STRUCT_FGET(u_lmsg, msg_namelen);
1055 lmsg.msg_iov = STRUCT_FGETP(u_lmsg, msg_iov);
1056 lmsg.msg_iovlen = STRUCT_FGET(u_lmsg, msg_iovlen);
1057 lmsg.msg_control = STRUCT_FGETP(u_lmsg, msg_control);
1058 lmsg.msg_controllen = STRUCT_FGET(u_lmsg, msg_controllen);
1059 lmsg.msg_flags = STRUCT_FGET(u_lmsg, msg_flags);
1060
1061 iovcnt = lmsg.msg_iovlen;
1062
1063 if (iovcnt <= 0 || iovcnt > IOV_MAX) {
1064 return (set_errno(EMSGSIZE));
1065 }
1066
1067 if (iovcnt > IOV_MAX_STACK) {
1068 iovsize = iovcnt * sizeof (struct iovec);
1069 aiov = kmem_alloc(iovsize, KM_SLEEP);
1070 }
1071
1072 #ifdef _SYSCALL32_IMPL
1073 /*
1074 * 32-bit callers need to have their iovec expanded, while ensuring
1075 * that they can't move more than 2Gbytes of data in a single call.
1076 */
1077 if (model == DATAMODEL_ILP32) {
1078 struct iovec32 buf32[IOV_MAX_STACK], *aiov32 = buf32;
1079 ssize_t iov32size;
1080 ssize32_t count32;
1081
1082 iov32size = iovcnt * sizeof (struct iovec32);
1083 if (iovsize != 0)
1084 aiov32 = kmem_alloc(iov32size, KM_SLEEP);
1085
1086 if (copyin((struct iovec32 *)lmsg.msg_iov, aiov32, iov32size)) {
1087 if (iovsize != 0) {
1088 kmem_free(aiov32, iov32size);
1089 kmem_free(aiov, iovsize);
1090 }
1091
1092 return (set_errno(EFAULT));
1093 }
1094
1095 count32 = 0;
1096 for (i = 0; i < iovcnt; i++) {
1097 ssize32_t iovlen32;
1098
1099 iovlen32 = aiov32[i].iov_len;
1100 count32 += iovlen32;
1101 if (iovlen32 < 0 || count32 < 0) {
1102 if (iovsize != 0) {
1103 kmem_free(aiov32, iov32size);
1104 kmem_free(aiov, iovsize);
1105 }
1106
1107 return (set_errno(EINVAL));
1108 }
1109
1110 aiov[i].iov_len = iovlen32;
1111 aiov[i].iov_base =
1112 (caddr_t)(uintptr_t)aiov32[i].iov_base;
1113 }
1114
1115 if (iovsize != 0)
1116 kmem_free(aiov32, iov32size);
1117 } else
1118 #endif /* _SYSCALL32_IMPL */
1119 if (copyin(lmsg.msg_iov, aiov, iovcnt * sizeof (struct iovec))) {
1120 if (iovsize != 0)
1121 kmem_free(aiov, iovsize);
1122
1123 return (set_errno(EFAULT));
1124 }
1125 len = 0;
1126 for (i = 0; i < iovcnt; i++) {
1127 ssize_t iovlen = aiov[i].iov_len;
1128 len += iovlen;
1129 if (iovlen < 0 || len < 0) {
1130 if (iovsize != 0)
1131 kmem_free(aiov, iovsize);
1132
1133 return (set_errno(EINVAL));
1134 }
1135 }
1136 auio.uio_loffset = 0;
1137 auio.uio_iov = aiov;
1138 auio.uio_iovcnt = iovcnt;
1139 auio.uio_resid = len;
1140 auio.uio_segflg = UIO_USERSPACE;
1141 auio.uio_limit = 0;
1142
1143 if (lmsg.msg_control != NULL &&
1144 (do_useracc == 0 ||
1145 useracc(lmsg.msg_control, lmsg.msg_controllen,
1146 B_WRITE) != 0)) {
1147 if (iovsize != 0)
1148 kmem_free(aiov, iovsize);
1149
1150 return (set_errno(EFAULT));
1151 }
1152
1153 rval = recvit(sock, &lmsg, &auio, flags,
1154 STRUCT_FADDR(umsgptr, msg_namelen),
1155 STRUCT_FADDR(umsgptr, msg_controllen), flagsp);
1156
1157 if (iovsize != 0)
1158 kmem_free(aiov, iovsize);
1159
1160 return (rval);
1161 }
1162
1163 /*
1164 * Common send function.
1165 */
1166 static ssize_t
1167 sendit(int sock, struct nmsghdr *msg, struct uio *uiop, int flags)
1168 {
1169 struct sonode *so;
1170 file_t *fp;
1171 void *name;
1172 socklen_t namelen;
1173 void *control;
1174 socklen_t controllen;
1175 ssize_t len;
1176 int error;
1177
1178 if ((so = getsonode(sock, &error, &fp)) == NULL)
1179 return (set_errno(error));
1180
1278 if (!(flags & MSG_XPG4_2)) {
1279 /*
1280 * In order to be compatible with the libsocket/sockmod
1281 * implementation we set EOR for all send* calls.
1282 */
1283 flags |= MSG_EOR;
1284 }
1285 return (sendit(sock, &lmsg, &auio, flags));
1286 }
1287
1288 /*
1289 * Uses the MSG_XPG4_2 flag to determine if the caller is using
1290 * struct omsghdr or struct nmsghdr.
1291 */
1292 ssize_t
1293 sendmsg(int sock, struct nmsghdr *msg, int flags)
1294 {
1295 struct nmsghdr lmsg;
1296 STRUCT_DECL(nmsghdr, u_lmsg);
1297 struct uio auio;
1298 struct iovec buf[IOV_MAX_STACK], *aiov = buf;
1299 ssize_t iovsize = 0;
1300 int iovcnt;
1301 ssize_t len, rval;
1302 int i;
1303 model_t model;
1304
1305 dprint(1, ("sendmsg(%d, %p, %d)\n", sock, (void *)msg, flags));
1306
1307 model = get_udatamodel();
1308 STRUCT_INIT(u_lmsg, model);
1309
1310 if (flags & MSG_XPG4_2) {
1311 if (copyin(msg, (char *)STRUCT_BUF(u_lmsg),
1312 STRUCT_SIZE(u_lmsg)))
1313 return (set_errno(EFAULT));
1314 } else {
1315 /*
1316 * Assumes that nmsghdr and omsghdr are identically shaped
1317 * except for the added msg_flags field.
1318 */
1319 if (copyin(msg, (char *)STRUCT_BUF(u_lmsg),
1320 SIZEOF_STRUCT(omsghdr, model)))
1321 return (set_errno(EFAULT));
1324 * implementation we set EOR for all send* calls.
1325 */
1326 flags |= MSG_EOR;
1327 }
1328
1329 /*
1330 * Code below us will kmem_alloc memory and hang it
1331 * off msg_control and msg_name fields. This forces
1332 * us to copy the structure to its native form.
1333 */
1334 lmsg.msg_name = STRUCT_FGETP(u_lmsg, msg_name);
1335 lmsg.msg_namelen = STRUCT_FGET(u_lmsg, msg_namelen);
1336 lmsg.msg_iov = STRUCT_FGETP(u_lmsg, msg_iov);
1337 lmsg.msg_iovlen = STRUCT_FGET(u_lmsg, msg_iovlen);
1338 lmsg.msg_control = STRUCT_FGETP(u_lmsg, msg_control);
1339 lmsg.msg_controllen = STRUCT_FGET(u_lmsg, msg_controllen);
1340 lmsg.msg_flags = STRUCT_FGET(u_lmsg, msg_flags);
1341
1342 iovcnt = lmsg.msg_iovlen;
1343
1344 if (iovcnt <= 0 || iovcnt > IOV_MAX) {
1345 /*
1346 * Unless this is XPG 4.2 we allow iovcnt == 0 to
1347 * be compatible with SunOS 4.X and 4.4BSD.
1348 */
1349 if (iovcnt != 0 || (flags & MSG_XPG4_2))
1350 return (set_errno(EMSGSIZE));
1351 }
1352
1353 if (iovcnt > IOV_MAX_STACK) {
1354 iovsize = iovcnt * sizeof (struct iovec);
1355 aiov = kmem_alloc(iovsize, KM_SLEEP);
1356 }
1357
1358 #ifdef _SYSCALL32_IMPL
1359 /*
1360 * 32-bit callers need to have their iovec expanded, while ensuring
1361 * that they can't move more than 2Gbytes of data in a single call.
1362 */
1363 if (model == DATAMODEL_ILP32) {
1364 struct iovec32 buf32[IOV_MAX_STACK], *aiov32 = buf32;
1365 ssize_t iov32size;
1366 ssize32_t count32;
1367
1368 iov32size = iovcnt * sizeof (struct iovec32);
1369 if (iovsize != 0)
1370 aiov32 = kmem_alloc(iov32size, KM_SLEEP);
1371
1372 if (iovcnt != 0 &&
1373 copyin((struct iovec32 *)lmsg.msg_iov, aiov32, iov32size)) {
1374 if (iovsize != 0) {
1375 kmem_free(aiov32, iov32size);
1376 kmem_free(aiov, iovsize);
1377 }
1378
1379 return (set_errno(EFAULT));
1380 }
1381
1382 count32 = 0;
1383 for (i = 0; i < iovcnt; i++) {
1384 ssize32_t iovlen32;
1385
1386 iovlen32 = aiov32[i].iov_len;
1387 count32 += iovlen32;
1388 if (iovlen32 < 0 || count32 < 0) {
1389 if (iovsize != 0) {
1390 kmem_free(aiov32, iov32size);
1391 kmem_free(aiov, iovsize);
1392 }
1393
1394 return (set_errno(EINVAL));
1395 }
1396
1397 aiov[i].iov_len = iovlen32;
1398 aiov[i].iov_base =
1399 (caddr_t)(uintptr_t)aiov32[i].iov_base;
1400 }
1401
1402 if (iovsize != 0)
1403 kmem_free(aiov32, iov32size);
1404 } else
1405 #endif /* _SYSCALL32_IMPL */
1406 if (iovcnt != 0 &&
1407 copyin(lmsg.msg_iov, aiov,
1408 (unsigned)iovcnt * sizeof (struct iovec))) {
1409 if (iovsize != 0)
1410 kmem_free(aiov, iovsize);
1411
1412 return (set_errno(EFAULT));
1413 }
1414 len = 0;
1415 for (i = 0; i < iovcnt; i++) {
1416 ssize_t iovlen = aiov[i].iov_len;
1417 len += iovlen;
1418 if (iovlen < 0 || len < 0) {
1419 if (iovsize != 0)
1420 kmem_free(aiov, iovsize);
1421
1422 return (set_errno(EINVAL));
1423 }
1424 }
1425 auio.uio_loffset = 0;
1426 auio.uio_iov = aiov;
1427 auio.uio_iovcnt = iovcnt;
1428 auio.uio_resid = len;
1429 auio.uio_segflg = UIO_USERSPACE;
1430 auio.uio_limit = 0;
1431
1432 rval = sendit(sock, &lmsg, &auio, flags);
1433
1434 if (iovsize != 0)
1435 kmem_free(aiov, iovsize);
1436
1437 return (rval);
1438 }
1439
1440 ssize_t
1441 sendto(int sock, void *buffer, size_t len, int flags,
1442 struct sockaddr *name, socklen_t namelen)
1443 {
1444 struct nmsghdr lmsg;
1445 struct uio auio;
1446 struct iovec aiov[1];
1447
1448 dprint(1, ("sendto(%d, %p, %ld, %d, %p, %d)\n",
1449 sock, buffer, len, flags, (void *)name, namelen));
1450
1451 if ((ssize_t)len < 0) {
1452 return (set_errno(EINVAL));
1453 }
1454
1455 aiov[0].iov_base = buffer;
1456 aiov[0].iov_len = len;
1457 auio.uio_loffset = 0;
|