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