uipc_syscalls.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  1. /* $OpenBSD: uipc_syscalls.c,v 1.106 2015/07/28 05:50:41 guenther Exp $ */
  2. /* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
  3. /*
  4. * Copyright (c) 1982, 1986, 1989, 1990, 1993
  5. * The Regents of the University of California. All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the University nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  23. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. *
  31. * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
  32. */
  33. #include <sys/param.h>
  34. #include <sys/systm.h>
  35. #include <sys/filedesc.h>
  36. #include <sys/proc.h>
  37. #include <sys/file.h>
  38. #include <sys/ioctl.h>
  39. #include <sys/malloc.h>
  40. #include <sys/event.h>
  41. #include <sys/mbuf.h>
  42. #include <sys/protosw.h>
  43. #include <sys/socket.h>
  44. #include <sys/socketvar.h>
  45. #include <sys/signalvar.h>
  46. #include <sys/tame.h>
  47. #include <sys/unpcb.h>
  48. #include <sys/un.h>
  49. #ifdef KTRACE
  50. #include <sys/ktrace.h>
  51. #endif
  52. #include <sys/mount.h>
  53. #include <sys/syscallargs.h>
  54. #include <net/route.h>
  55. /*
  56. * System call interface to the socket abstraction.
  57. */
  58. extern struct fileops socketops;
  59. int copyaddrout(struct proc *, struct mbuf *, struct sockaddr *, socklen_t,
  60. socklen_t *);
  61. int
  62. sys_socket(struct proc *p, void *v, register_t *retval)
  63. {
  64. struct sys_socket_args /* {
  65. syscallarg(int) domain;
  66. syscallarg(int) type;
  67. syscallarg(int) protocol;
  68. } */ *uap = v;
  69. struct filedesc *fdp = p->p_fd;
  70. struct socket *so;
  71. struct file *fp;
  72. int type = SCARG(uap, type);
  73. int fd, error;
  74. if (tame_socket_check(p, SCARG(uap, domain)))
  75. return (tame_fail(p, EPERM, _TM_UNIX));
  76. fdplock(fdp);
  77. error = falloc(p, &fp, &fd);
  78. if (error == 0 && (type & SOCK_CLOEXEC))
  79. fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
  80. fdpunlock(fdp);
  81. if (error != 0)
  82. goto out;
  83. fp->f_flag = FREAD | FWRITE | (type & SOCK_NONBLOCK ? FNONBLOCK : 0);
  84. fp->f_type = DTYPE_SOCKET;
  85. fp->f_ops = &socketops;
  86. error = socreate(SCARG(uap, domain), &so,
  87. type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK), SCARG(uap, protocol));
  88. if (error) {
  89. fdplock(fdp);
  90. fdremove(fdp, fd);
  91. closef(fp, p);
  92. fdpunlock(fdp);
  93. } else {
  94. fp->f_data = so;
  95. if (type & SOCK_NONBLOCK)
  96. (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&type, p);
  97. FILE_SET_MATURE(fp, p);
  98. *retval = fd;
  99. }
  100. out:
  101. return (error);
  102. }
  103. /* ARGSUSED */
  104. int
  105. sys_bind(struct proc *p, void *v, register_t *retval)
  106. {
  107. struct sys_bind_args /* {
  108. syscallarg(int) s;
  109. syscallarg(const struct sockaddr *) name;
  110. syscallarg(socklen_t) namelen;
  111. } */ *uap = v;
  112. struct file *fp;
  113. struct mbuf *nam;
  114. int error;
  115. if (tame_bind_check(p, SCARG(uap, name)))
  116. return (tame_fail(p, EPERM, _TM_UNIX));
  117. if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
  118. return (error);
  119. error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
  120. MT_SONAME);
  121. if (error == 0) {
  122. #ifdef KTRACE
  123. if (KTRPOINT(p, KTR_STRUCT))
  124. ktrsockaddr(p, mtod(nam, caddr_t), SCARG(uap, namelen));
  125. #endif
  126. error = sobind(fp->f_data, nam, p);
  127. m_freem(nam);
  128. }
  129. FRELE(fp, p);
  130. return (error);
  131. }
  132. /* ARGSUSED */
  133. int
  134. sys_listen(struct proc *p, void *v, register_t *retval)
  135. {
  136. struct sys_listen_args /* {
  137. syscallarg(int) s;
  138. syscallarg(int) backlog;
  139. } */ *uap = v;
  140. struct file *fp;
  141. int error;
  142. if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
  143. return (error);
  144. error = solisten(fp->f_data, SCARG(uap, backlog));
  145. FRELE(fp, p);
  146. return (error);
  147. }
  148. int
  149. sys_accept(struct proc *p, void *v, register_t *retval)
  150. {
  151. struct sys_accept_args /* {
  152. syscallarg(int) s;
  153. syscallarg(struct sockaddr *) name;
  154. syscallarg(socklen_t *) anamelen;
  155. } */ *uap = v;
  156. return (doaccept(p, SCARG(uap, s), SCARG(uap, name),
  157. SCARG(uap, anamelen), SOCK_NONBLOCK_INHERIT, retval));
  158. }
  159. int
  160. sys_accept4(struct proc *p, void *v, register_t *retval)
  161. {
  162. struct sys_accept4_args /* {
  163. syscallarg(int) s;
  164. syscallarg(struct sockaddr *) name;
  165. syscallarg(socklen_t *) anamelen;
  166. syscallarg(socklen_t *) int flags;
  167. } */ *uap = v;
  168. if (SCARG(uap, flags) & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
  169. return (EINVAL);
  170. return (doaccept(p, SCARG(uap, s), SCARG(uap, name),
  171. SCARG(uap, anamelen), SCARG(uap, flags), retval));
  172. }
  173. int
  174. doaccept(struct proc *p, int sock, struct sockaddr *name, socklen_t *anamelen,
  175. int flags, register_t *retval)
  176. {
  177. struct filedesc *fdp = p->p_fd;
  178. struct file *fp, *headfp;
  179. struct mbuf *nam;
  180. socklen_t namelen;
  181. int error, s, tmpfd;
  182. struct socket *head, *so;
  183. int nflag;
  184. if (name && (error = copyin(anamelen, &namelen, sizeof (namelen))))
  185. return (error);
  186. if ((error = getsock(p, sock, &fp)) != 0)
  187. return (error);
  188. headfp = fp;
  189. s = splsoftnet();
  190. head = fp->f_data;
  191. redo:
  192. if ((head->so_options & SO_ACCEPTCONN) == 0) {
  193. error = EINVAL;
  194. goto bad;
  195. }
  196. if ((head->so_state & SS_NBIO) && head->so_qlen == 0) {
  197. if (head->so_state & SS_CANTRCVMORE)
  198. error = ECONNABORTED;
  199. else
  200. error = EWOULDBLOCK;
  201. goto bad;
  202. }
  203. while (head->so_qlen == 0 && head->so_error == 0) {
  204. if (head->so_state & SS_CANTRCVMORE) {
  205. head->so_error = ECONNABORTED;
  206. break;
  207. }
  208. error = tsleep(&head->so_timeo, PSOCK | PCATCH, "netcon", 0);
  209. if (error) {
  210. goto bad;
  211. }
  212. }
  213. if (head->so_error) {
  214. error = head->so_error;
  215. head->so_error = 0;
  216. goto bad;
  217. }
  218. /* Figure out whether the new socket should be non-blocking. */
  219. nflag = flags & SOCK_NONBLOCK_INHERIT ? (headfp->f_flag & FNONBLOCK)
  220. : (flags & SOCK_NONBLOCK ? FNONBLOCK : 0);
  221. fdplock(fdp);
  222. error = falloc(p, &fp, &tmpfd);
  223. if (error == 0 && (flags & SOCK_CLOEXEC))
  224. fdp->fd_ofileflags[tmpfd] |= UF_EXCLOSE;
  225. fdpunlock(fdp);
  226. if (error != 0) {
  227. /*
  228. * Probably ran out of file descriptors. Wakeup
  229. * so some other process might have a chance at it.
  230. */
  231. wakeup_one(&head->so_timeo);
  232. goto bad;
  233. }
  234. nam = m_get(M_WAIT, MT_SONAME);
  235. /*
  236. * Check whether the queue emptied while we slept: falloc() or
  237. * m_get() may have blocked, allowing the connection to be reset
  238. * or another thread or process to accept it. If so, start over.
  239. */
  240. if (head->so_qlen == 0) {
  241. m_freem(nam);
  242. fdplock(fdp);
  243. fdremove(fdp, tmpfd);
  244. closef(fp, p);
  245. fdpunlock(fdp);
  246. goto redo;
  247. }
  248. /*
  249. * Do not sleep after we have taken the socket out of the queue.
  250. */
  251. so = TAILQ_FIRST(&head->so_q);
  252. if (soqremque(so, 1) == 0)
  253. panic("accept");
  254. /* connection has been removed from the listen queue */
  255. KNOTE(&head->so_rcv.sb_sel.si_note, 0);
  256. fp->f_type = DTYPE_SOCKET;
  257. fp->f_flag = FREAD | FWRITE | nflag;
  258. fp->f_ops = &socketops;
  259. fp->f_data = so;
  260. error = soaccept(so, nam);
  261. if (!error && name != NULL)
  262. error = copyaddrout(p, nam, name, namelen, anamelen);
  263. if (error) {
  264. /* if an error occurred, free the file descriptor */
  265. fdplock(fdp);
  266. fdremove(fdp, tmpfd);
  267. closef(fp, p);
  268. fdpunlock(fdp);
  269. } else {
  270. (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&nflag, p);
  271. FILE_SET_MATURE(fp, p);
  272. *retval = tmpfd;
  273. }
  274. m_freem(nam);
  275. bad:
  276. splx(s);
  277. FRELE(headfp, p);
  278. return (error);
  279. }
  280. /* ARGSUSED */
  281. int
  282. sys_connect(struct proc *p, void *v, register_t *retval)
  283. {
  284. struct sys_connect_args /* {
  285. syscallarg(int) s;
  286. syscallarg(const struct sockaddr *) name;
  287. syscallarg(socklen_t) namelen;
  288. } */ *uap = v;
  289. struct file *fp;
  290. struct socket *so;
  291. struct mbuf *nam = NULL;
  292. int error, s;
  293. if (tame_connect_check(p))
  294. return (tame_fail(p, EPERM, _TM_UNIX));
  295. if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
  296. return (error);
  297. so = fp->f_data;
  298. if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
  299. FRELE(fp, p);
  300. return (EALREADY);
  301. }
  302. error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
  303. MT_SONAME);
  304. if (error)
  305. goto bad;
  306. #ifdef KTRACE
  307. if (KTRPOINT(p, KTR_STRUCT))
  308. ktrsockaddr(p, mtod(nam, caddr_t), SCARG(uap, namelen));
  309. #endif
  310. error = soconnect(so, nam);
  311. if (error)
  312. goto bad;
  313. if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
  314. FRELE(fp, p);
  315. m_freem(nam);
  316. return (EINPROGRESS);
  317. }
  318. s = splsoftnet();
  319. while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
  320. error = tsleep(&so->so_timeo, PSOCK | PCATCH, "netcon2", 0);
  321. if (error)
  322. break;
  323. }
  324. if (error == 0) {
  325. error = so->so_error;
  326. so->so_error = 0;
  327. }
  328. splx(s);
  329. bad:
  330. so->so_state &= ~SS_ISCONNECTING;
  331. FRELE(fp, p);
  332. if (nam)
  333. m_freem(nam);
  334. if (error == ERESTART)
  335. error = EINTR;
  336. return (error);
  337. }
  338. int
  339. sys_socketpair(struct proc *p, void *v, register_t *retval)
  340. {
  341. struct sys_socketpair_args /* {
  342. syscallarg(int) domain;
  343. syscallarg(int) type;
  344. syscallarg(int) protocol;
  345. syscallarg(int *) rsv;
  346. } */ *uap = v;
  347. struct filedesc *fdp = p->p_fd;
  348. struct file *fp1, *fp2;
  349. struct socket *so1, *so2;
  350. int type, flags, fflag, error, sv[2];
  351. type = SCARG(uap, type) & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
  352. flags = SCARG(uap, type) & (SOCK_CLOEXEC | SOCK_NONBLOCK);
  353. fflag = FREAD | FWRITE | (flags & SOCK_NONBLOCK ? FNONBLOCK : 0);
  354. error = socreate(SCARG(uap, domain), &so1, type, SCARG(uap, protocol));
  355. if (error)
  356. return (error);
  357. error = socreate(SCARG(uap, domain), &so2, type, SCARG(uap, protocol));
  358. if (error)
  359. goto free1;
  360. fdplock(fdp);
  361. if ((error = falloc(p, &fp1, &sv[0])) != 0)
  362. goto free2;
  363. fp1->f_flag = fflag;
  364. fp1->f_type = DTYPE_SOCKET;
  365. fp1->f_ops = &socketops;
  366. fp1->f_data = so1;
  367. if ((error = falloc(p, &fp2, &sv[1])) != 0)
  368. goto free3;
  369. fp2->f_flag = fflag;
  370. fp2->f_type = DTYPE_SOCKET;
  371. fp2->f_ops = &socketops;
  372. fp2->f_data = so2;
  373. if (flags & SOCK_CLOEXEC) {
  374. fdp->fd_ofileflags[sv[0]] |= UF_EXCLOSE;
  375. fdp->fd_ofileflags[sv[1]] |= UF_EXCLOSE;
  376. }
  377. if ((error = soconnect2(so1, so2)) != 0)
  378. goto free4;
  379. if ((SCARG(uap, type) & SOCK_TYPE_MASK) == SOCK_DGRAM) {
  380. /*
  381. * Datagram socket connection is asymmetric.
  382. */
  383. if ((error = soconnect2(so2, so1)) != 0)
  384. goto free4;
  385. }
  386. error = copyout(sv, SCARG(uap, rsv), 2 * sizeof (int));
  387. if (error == 0) {
  388. if (flags & SOCK_NONBLOCK) {
  389. (*fp1->f_ops->fo_ioctl)(fp1, FIONBIO, (caddr_t)&flags,
  390. p);
  391. (*fp2->f_ops->fo_ioctl)(fp2, FIONBIO, (caddr_t)&flags,
  392. p);
  393. }
  394. FILE_SET_MATURE(fp1, p);
  395. FILE_SET_MATURE(fp2, p);
  396. fdpunlock(fdp);
  397. return (0);
  398. }
  399. free4:
  400. fdremove(fdp, sv[1]);
  401. closef(fp2, p);
  402. so2 = NULL;
  403. free3:
  404. fdremove(fdp, sv[0]);
  405. closef(fp1, p);
  406. so1 = NULL;
  407. free2:
  408. if (so2 != NULL)
  409. (void)soclose(so2);
  410. fdpunlock(fdp);
  411. free1:
  412. if (so1 != NULL)
  413. (void)soclose(so1);
  414. return (error);
  415. }
  416. int
  417. sys_sendto(struct proc *p, void *v, register_t *retval)
  418. {
  419. struct sys_sendto_args /* {
  420. syscallarg(int) s;
  421. syscallarg(const void *) buf;
  422. syscallarg(size_t) len;
  423. syscallarg(int) flags;
  424. syscallarg(const struct sockaddr *) to;
  425. syscallarg(socklen_t) tolen;
  426. } */ *uap = v;
  427. struct msghdr msg;
  428. struct iovec aiov;
  429. if (tame_sendto_check(p, SCARG(uap, to)))
  430. return (tame_fail(p, EPERM, _TM_UNIX));
  431. msg.msg_name = (caddr_t)SCARG(uap, to);
  432. msg.msg_namelen = SCARG(uap, tolen);
  433. msg.msg_iov = &aiov;
  434. msg.msg_iovlen = 1;
  435. msg.msg_control = 0;
  436. msg.msg_flags = 0;
  437. aiov.iov_base = (char *)SCARG(uap, buf);
  438. aiov.iov_len = SCARG(uap, len);
  439. return (sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval));
  440. }
  441. int
  442. sys_sendmsg(struct proc *p, void *v, register_t *retval)
  443. {
  444. struct sys_sendmsg_args /* {
  445. syscallarg(int) s;
  446. syscallarg(const struct msghdr *) msg;
  447. syscallarg(int) flags;
  448. } */ *uap = v;
  449. struct msghdr msg;
  450. struct iovec aiov[UIO_SMALLIOV], *iov;
  451. int error;
  452. error = copyin(SCARG(uap, msg), &msg, sizeof (msg));
  453. if (error)
  454. return (error);
  455. #ifdef KTRACE
  456. if (KTRPOINT(p, KTR_STRUCT))
  457. ktrmsghdr(p, &msg);
  458. #endif
  459. if (tame_sendto_check(p, msg.msg_name))
  460. return (tame_fail(p, EPERM, _TM_UNIX));
  461. if (msg.msg_iovlen > IOV_MAX)
  462. return (EMSGSIZE);
  463. if (msg.msg_iovlen > UIO_SMALLIOV)
  464. iov = mallocarray(msg.msg_iovlen, sizeof(struct iovec),
  465. M_IOV, M_WAITOK);
  466. else
  467. iov = aiov;
  468. if (msg.msg_iovlen &&
  469. (error = copyin(msg.msg_iov, iov,
  470. (unsigned)(msg.msg_iovlen * sizeof (struct iovec)))))
  471. goto done;
  472. #ifdef KTRACE
  473. if (msg.msg_iovlen && KTRPOINT(p, KTR_STRUCT))
  474. ktriovec(p, iov, msg.msg_iovlen);
  475. #endif
  476. msg.msg_iov = iov;
  477. msg.msg_flags = 0;
  478. error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
  479. done:
  480. if (iov != aiov)
  481. free(iov, M_IOV, sizeof(struct iovec) * msg.msg_iovlen);
  482. return (error);
  483. }
  484. int
  485. sendit(struct proc *p, int s, struct msghdr *mp, int flags, register_t *retsize)
  486. {
  487. struct file *fp;
  488. struct uio auio;
  489. struct iovec *iov;
  490. int i;
  491. struct mbuf *to, *control;
  492. size_t len;
  493. int error;
  494. #ifdef KTRACE
  495. struct iovec *ktriov = NULL;
  496. int iovlen = 0;
  497. #endif
  498. to = NULL;
  499. if ((error = getsock(p, s, &fp)) != 0)
  500. return (error);
  501. auio.uio_iov = mp->msg_iov;
  502. auio.uio_iovcnt = mp->msg_iovlen;
  503. auio.uio_segflg = UIO_USERSPACE;
  504. auio.uio_rw = UIO_WRITE;
  505. auio.uio_procp = p;
  506. auio.uio_offset = 0; /* XXX */
  507. auio.uio_resid = 0;
  508. iov = mp->msg_iov;
  509. for (i = 0; i < mp->msg_iovlen; i++, iov++) {
  510. /* Don't allow sum > SSIZE_MAX */
  511. if (iov->iov_len > SSIZE_MAX ||
  512. (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
  513. error = EINVAL;
  514. goto bad;
  515. }
  516. }
  517. if (mp->msg_name) {
  518. error = sockargs(&to, mp->msg_name, mp->msg_namelen,
  519. MT_SONAME);
  520. if (error)
  521. goto bad;
  522. #ifdef KTRACE
  523. if (KTRPOINT(p, KTR_STRUCT))
  524. ktrsockaddr(p, mtod(to, caddr_t), mp->msg_namelen);
  525. #endif
  526. }
  527. if (mp->msg_control) {
  528. if (mp->msg_controllen < CMSG_ALIGN(sizeof(struct cmsghdr))) {
  529. error = EINVAL;
  530. goto bad;
  531. }
  532. error = sockargs(&control, mp->msg_control,
  533. mp->msg_controllen, MT_CONTROL);
  534. if (error)
  535. goto bad;
  536. #ifdef KTRACE
  537. if (KTRPOINT(p, KTR_STRUCT) && mp->msg_controllen)
  538. ktrcmsghdr(p, mtod(control, char *),
  539. mp->msg_controllen);
  540. #endif
  541. if (tame_cmsg_send(p, control, mp->msg_controllen)) {
  542. m_free(control);
  543. goto bad;
  544. }
  545. } else
  546. control = 0;
  547. #ifdef KTRACE
  548. if (KTRPOINT(p, KTR_GENIO)) {
  549. ktriov = mallocarray(auio.uio_iovcnt, sizeof(struct iovec),
  550. M_TEMP, M_WAITOK);
  551. iovlen = auio.uio_iovcnt * sizeof (struct iovec);
  552. memcpy(ktriov, auio.uio_iov, iovlen);
  553. }
  554. #endif
  555. len = auio.uio_resid;
  556. error = sosend(fp->f_data, to, &auio, NULL, control, flags);
  557. if (error) {
  558. if (auio.uio_resid != len && (error == ERESTART ||
  559. error == EINTR || error == EWOULDBLOCK))
  560. error = 0;
  561. if (error == EPIPE && (flags & MSG_NOSIGNAL) == 0)
  562. ptsignal(p, SIGPIPE, STHREAD);
  563. }
  564. if (error == 0) {
  565. *retsize = len - auio.uio_resid;
  566. fp->f_wxfer++;
  567. fp->f_wbytes += *retsize;
  568. }
  569. #ifdef KTRACE
  570. if (ktriov != NULL) {
  571. if (error == 0)
  572. ktrgenio(p, s, UIO_WRITE, ktriov, *retsize);
  573. free(ktriov, M_TEMP, iovlen);
  574. }
  575. #endif
  576. bad:
  577. FRELE(fp, p);
  578. if (to)
  579. m_freem(to);
  580. return (error);
  581. }
  582. int
  583. sys_recvfrom(struct proc *p, void *v, register_t *retval)
  584. {
  585. struct sys_recvfrom_args /* {
  586. syscallarg(int) s;
  587. syscallarg(void *) buf;
  588. syscallarg(size_t) len;
  589. syscallarg(int) flags;
  590. syscallarg(struct sockaddr *) from;
  591. syscallarg(socklen_t *) fromlenaddr;
  592. } */ *uap = v;
  593. struct msghdr msg;
  594. struct iovec aiov;
  595. int error;
  596. if (tame_recvfrom_check(p, SCARG(uap, from)))
  597. return (tame_fail(p, EPERM, _TM_UNIX));
  598. if (SCARG(uap, fromlenaddr)) {
  599. error = copyin(SCARG(uap, fromlenaddr),
  600. &msg.msg_namelen, sizeof (msg.msg_namelen));
  601. if (error)
  602. return (error);
  603. } else
  604. msg.msg_namelen = 0;
  605. msg.msg_name = (caddr_t)SCARG(uap, from);
  606. msg.msg_iov = &aiov;
  607. msg.msg_iovlen = 1;
  608. aiov.iov_base = SCARG(uap, buf);
  609. aiov.iov_len = SCARG(uap, len);
  610. msg.msg_control = 0;
  611. msg.msg_flags = SCARG(uap, flags);
  612. return (recvit(p, SCARG(uap, s), &msg,
  613. (caddr_t)SCARG(uap, fromlenaddr), retval));
  614. }
  615. int
  616. sys_recvmsg(struct proc *p, void *v, register_t *retval)
  617. {
  618. struct sys_recvmsg_args /* {
  619. syscallarg(int) s;
  620. syscallarg(struct msghdr *) msg;
  621. syscallarg(int) flags;
  622. } */ *uap = v;
  623. struct msghdr msg;
  624. struct iovec aiov[UIO_SMALLIOV], *uiov, *iov;
  625. int error;
  626. error = copyin(SCARG(uap, msg), &msg, sizeof (msg));
  627. if (error)
  628. return (error);
  629. if (tame_recvfrom_check(p, msg.msg_name))
  630. return (tame_fail(p, EPERM, _TM_UNIX));
  631. if (msg.msg_iovlen > IOV_MAX)
  632. return (EMSGSIZE);
  633. if (msg.msg_iovlen > UIO_SMALLIOV)
  634. iov = mallocarray(msg.msg_iovlen, sizeof(struct iovec),
  635. M_IOV, M_WAITOK);
  636. else
  637. iov = aiov;
  638. msg.msg_flags = SCARG(uap, flags);
  639. if (msg.msg_iovlen > 0) {
  640. error = copyin(msg.msg_iov, iov,
  641. msg.msg_iovlen * sizeof(struct iovec));
  642. if (error)
  643. goto done;
  644. }
  645. uiov = msg.msg_iov;
  646. msg.msg_iov = iov;
  647. if ((error = recvit(p, SCARG(uap, s), &msg, NULL, retval)) == 0) {
  648. msg.msg_iov = uiov;
  649. #ifdef KTRACE
  650. if (KTRPOINT(p, KTR_STRUCT)) {
  651. ktrmsghdr(p, &msg);
  652. if (msg.msg_iovlen)
  653. ktriovec(p, iov, msg.msg_iovlen);
  654. }
  655. #endif
  656. error = copyout(&msg, SCARG(uap, msg), sizeof(msg));
  657. }
  658. done:
  659. if (iov != aiov)
  660. free(iov, M_IOV, sizeof(struct iovec) * msg.msg_iovlen);
  661. return (error);
  662. }
  663. int
  664. recvit(struct proc *p, int s, struct msghdr *mp, caddr_t namelenp,
  665. register_t *retsize)
  666. {
  667. struct file *fp;
  668. struct uio auio;
  669. struct iovec *iov;
  670. int i;
  671. size_t len;
  672. int error;
  673. struct mbuf *from = NULL, *control = NULL;
  674. #ifdef KTRACE
  675. struct iovec *ktriov = NULL;
  676. int iovlen = 0;
  677. #endif
  678. if ((error = getsock(p, s, &fp)) != 0)
  679. return (error);
  680. auio.uio_iov = mp->msg_iov;
  681. auio.uio_iovcnt = mp->msg_iovlen;
  682. auio.uio_segflg = UIO_USERSPACE;
  683. auio.uio_rw = UIO_READ;
  684. auio.uio_procp = p;
  685. auio.uio_offset = 0; /* XXX */
  686. auio.uio_resid = 0;
  687. iov = mp->msg_iov;
  688. for (i = 0; i < mp->msg_iovlen; i++, iov++) {
  689. /* Don't allow sum > SSIZE_MAX */
  690. if (iov->iov_len > SSIZE_MAX ||
  691. (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
  692. error = EINVAL;
  693. goto out;
  694. }
  695. }
  696. #ifdef KTRACE
  697. if (KTRPOINT(p, KTR_GENIO)) {
  698. ktriov = mallocarray(auio.uio_iovcnt, sizeof(struct iovec),
  699. M_TEMP, M_WAITOK);
  700. iovlen = auio.uio_iovcnt * sizeof (struct iovec);
  701. memcpy(ktriov, auio.uio_iov, iovlen);
  702. }
  703. #endif
  704. len = auio.uio_resid;
  705. error = soreceive(fp->f_data, &from, &auio, NULL,
  706. mp->msg_control ? &control : NULL,
  707. &mp->msg_flags,
  708. mp->msg_control ? mp->msg_controllen : 0);
  709. if (error) {
  710. if (auio.uio_resid != len && (error == ERESTART ||
  711. error == EINTR || error == EWOULDBLOCK))
  712. error = 0;
  713. }
  714. #ifdef KTRACE
  715. if (ktriov != NULL) {
  716. if (error == 0)
  717. ktrgenio(p, s, UIO_READ, ktriov, len - auio.uio_resid);
  718. free(ktriov, M_TEMP, iovlen);
  719. }
  720. #endif
  721. if (error)
  722. goto out;
  723. *retsize = len - auio.uio_resid;
  724. if (mp->msg_name) {
  725. socklen_t alen;
  726. if (from == NULL)
  727. alen = 0;
  728. else {
  729. alen = from->m_len;
  730. error = copyout(mtod(from, caddr_t), mp->msg_name,
  731. MIN(alen, mp->msg_namelen));
  732. if (error)
  733. goto out;
  734. #ifdef KTRACE
  735. if (KTRPOINT(p, KTR_STRUCT))
  736. ktrsockaddr(p, mtod(from, caddr_t), alen);
  737. #endif
  738. }
  739. mp->msg_namelen = alen;
  740. if (namelenp &&
  741. (error = copyout(&alen, namelenp, sizeof(alen)))) {
  742. goto out;
  743. }
  744. }
  745. if (mp->msg_control) {
  746. len = mp->msg_controllen;
  747. if (len <= 0 || control == NULL)
  748. len = 0;
  749. else {
  750. struct mbuf *m = control;
  751. caddr_t cp = mp->msg_control;
  752. #ifdef KTRACE
  753. if (KTRPOINT(p, KTR_STRUCT) && len)
  754. ktrcmsghdr(p, mtod(control, char *), len);
  755. #endif
  756. do {
  757. i = m->m_len;
  758. if (len < i) {
  759. mp->msg_flags |= MSG_CTRUNC;
  760. i = len;
  761. }
  762. if (tame_cmsg_recv(p, control, mp->msg_controllen))
  763. goto out;
  764. error = copyout(mtod(m, caddr_t), cp, i);
  765. if (m->m_next)
  766. i = ALIGN(i);
  767. cp += i;
  768. len -= i;
  769. if (error != 0 || len <= 0)
  770. break;
  771. } while ((m = m->m_next) != NULL);
  772. len = cp - (caddr_t)mp->msg_control;
  773. }
  774. mp->msg_controllen = len;
  775. }
  776. if (!error) {
  777. fp->f_rxfer++;
  778. fp->f_rbytes += *retsize;
  779. }
  780. out:
  781. FRELE(fp, p);
  782. if (from)
  783. m_freem(from);
  784. if (control)
  785. m_freem(control);
  786. return (error);
  787. }
  788. /* ARGSUSED */
  789. int
  790. sys_shutdown(struct proc *p, void *v, register_t *retval)
  791. {
  792. struct sys_shutdown_args /* {
  793. syscallarg(int) s;
  794. syscallarg(int) how;
  795. } */ *uap = v;
  796. struct file *fp;
  797. int error;
  798. if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
  799. return (error);
  800. error = soshutdown(fp->f_data, SCARG(uap, how));
  801. FRELE(fp, p);
  802. return (error);
  803. }
  804. /* ARGSUSED */
  805. int
  806. sys_setsockopt(struct proc *p, void *v, register_t *retval)
  807. {
  808. struct sys_setsockopt_args /* {
  809. syscallarg(int) s;
  810. syscallarg(int) level;
  811. syscallarg(int) name;
  812. syscallarg(const void *) val;
  813. syscallarg(socklen_t) valsize;
  814. } */ *uap = v;
  815. struct file *fp;
  816. struct mbuf *m = NULL;
  817. int error;
  818. if (tame_setsockopt_check(p, SCARG(uap, level), SCARG(uap, name)))
  819. return (tame_fail(p, EPERM, _TM_INET));
  820. if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
  821. return (error);
  822. if (SCARG(uap, valsize) > MCLBYTES) {
  823. error = EINVAL;
  824. goto bad;
  825. }
  826. if (SCARG(uap, val)) {
  827. m = m_get(M_WAIT, MT_SOOPTS);
  828. if (SCARG(uap, valsize) > MLEN) {
  829. MCLGET(m, M_DONTWAIT);
  830. if ((m->m_flags & M_EXT) == 0) {
  831. error = ENOBUFS;
  832. goto bad;
  833. }
  834. }
  835. if (m == NULL) {
  836. error = ENOBUFS;
  837. goto bad;
  838. }
  839. error = copyin(SCARG(uap, val), mtod(m, caddr_t),
  840. SCARG(uap, valsize));
  841. if (error) {
  842. goto bad;
  843. }
  844. m->m_len = SCARG(uap, valsize);
  845. }
  846. error = sosetopt(fp->f_data, SCARG(uap, level), SCARG(uap, name), m);
  847. m = NULL;
  848. bad:
  849. if (m)
  850. m_freem(m);
  851. FRELE(fp, p);
  852. return (error);
  853. }
  854. /* ARGSUSED */
  855. int
  856. sys_getsockopt(struct proc *p, void *v, register_t *retval)
  857. {
  858. struct sys_getsockopt_args /* {
  859. syscallarg(int) s;
  860. syscallarg(int) level;
  861. syscallarg(int) name;
  862. syscallarg(void *) val;
  863. syscallarg(socklen_t *) avalsize;
  864. } */ *uap = v;
  865. struct file *fp;
  866. struct mbuf *m = NULL;
  867. socklen_t valsize;
  868. int error;
  869. if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
  870. return (error);
  871. if (SCARG(uap, val)) {
  872. error = copyin(SCARG(uap, avalsize),
  873. &valsize, sizeof (valsize));
  874. if (error)
  875. goto out;
  876. } else
  877. valsize = 0;
  878. if ((error = sogetopt(fp->f_data, SCARG(uap, level),
  879. SCARG(uap, name), &m)) == 0 && SCARG(uap, val) && valsize &&
  880. m != NULL) {
  881. if (valsize > m->m_len)
  882. valsize = m->m_len;
  883. error = copyout(mtod(m, caddr_t), SCARG(uap, val), valsize);
  884. if (error == 0)
  885. error = copyout(&valsize,
  886. SCARG(uap, avalsize), sizeof (valsize));
  887. }
  888. out:
  889. FRELE(fp, p);
  890. if (m != NULL)
  891. (void)m_free(m);
  892. return (error);
  893. }
  894. /*
  895. * Get socket name.
  896. */
  897. /* ARGSUSED */
  898. int
  899. sys_getsockname(struct proc *p, void *v, register_t *retval)
  900. {
  901. struct sys_getsockname_args /* {
  902. syscallarg(int) fdes;
  903. syscallarg(struct sockaddr *) asa;
  904. syscallarg(socklen_t *) alen;
  905. } */ *uap = v;
  906. struct file *fp;
  907. struct socket *so;
  908. struct mbuf *m = NULL;
  909. socklen_t len;
  910. int error;
  911. if ((error = getsock(p, SCARG(uap, fdes), &fp)) != 0)
  912. return (error);
  913. error = copyin(SCARG(uap, alen), &len, sizeof (len));
  914. if (error)
  915. goto bad;
  916. so = fp->f_data;
  917. m = m_getclr(M_WAIT, MT_SONAME);
  918. error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0, p);
  919. if (error)
  920. goto bad;
  921. error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));
  922. bad:
  923. FRELE(fp, p);
  924. if (m)
  925. m_freem(m);
  926. return (error);
  927. }
  928. /*
  929. * Get name of peer for connected socket.
  930. */
  931. /* ARGSUSED */
  932. int
  933. sys_getpeername(struct proc *p, void *v, register_t *retval)
  934. {
  935. struct sys_getpeername_args /* {
  936. syscallarg(int) fdes;
  937. syscallarg(struct sockaddr *) asa;
  938. syscallarg(socklen_t *) alen;
  939. } */ *uap = v;
  940. struct file *fp;
  941. struct socket *so;
  942. struct mbuf *m = NULL;
  943. socklen_t len;
  944. int error;
  945. if ((error = getsock(p, SCARG(uap, fdes), &fp)) != 0)
  946. return (error);
  947. so = fp->f_data;
  948. if ((so->so_state & SS_ISCONNECTED) == 0) {
  949. FRELE(fp, p);
  950. return (ENOTCONN);
  951. }
  952. error = copyin(SCARG(uap, alen), &len, sizeof (len));
  953. if (error)
  954. goto bad;
  955. m = m_getclr(M_WAIT, MT_SONAME);
  956. error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0, p);
  957. if (error)
  958. goto bad;
  959. error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));
  960. bad:
  961. FRELE(fp, p);
  962. m_freem(m);
  963. return (error);
  964. }
  965. int
  966. sockargs(struct mbuf **mp, const void *buf, size_t buflen, int type)
  967. {
  968. struct sockaddr *sa;
  969. struct mbuf *m;
  970. int error;
  971. /*
  972. * We can't allow socket names > UCHAR_MAX in length, since that
  973. * will overflow sa_len. Also, control data more than MCLBYTES in
  974. * length is just too much.
  975. */
  976. if (buflen > (type == MT_SONAME ? UCHAR_MAX : MCLBYTES))
  977. return (EINVAL);
  978. /* Allocate an mbuf to hold the arguments. */
  979. m = m_get(M_WAIT, type);
  980. if ((u_int)buflen > MLEN) {
  981. MCLGET(m, M_WAITOK);
  982. if ((m->m_flags & M_EXT) == 0) {
  983. m_free(m);
  984. return ENOBUFS;
  985. }
  986. }
  987. m->m_len = buflen;
  988. error = copyin(buf, mtod(m, caddr_t), buflen);
  989. if (error) {
  990. (void) m_free(m);
  991. return (error);
  992. }
  993. *mp = m;
  994. if (type == MT_SONAME) {
  995. sa = mtod(m, struct sockaddr *);
  996. sa->sa_len = buflen;
  997. }
  998. return (0);
  999. }
  1000. int
  1001. getsock(struct proc *p, int fdes, struct file **fpp)
  1002. {
  1003. struct file *fp;
  1004. if ((fp = fd_getfile(p->p_fd, fdes)) == NULL)
  1005. return (EBADF);
  1006. if (fp->f_type != DTYPE_SOCKET)
  1007. return (ENOTSOCK);
  1008. *fpp = fp;
  1009. FREF(fp);
  1010. return (0);
  1011. }
  1012. /* ARGSUSED */
  1013. int
  1014. sys_setrtable(struct proc *p, void *v, register_t *retval)
  1015. {
  1016. struct sys_setrtable_args /* {
  1017. syscallarg(int) rtableid;
  1018. } */ *uap = v;
  1019. int rtableid, error;
  1020. rtableid = SCARG(uap, rtableid);
  1021. if (p->p_p->ps_rtableid == (u_int)rtableid)
  1022. return (0);
  1023. if (p->p_p->ps_rtableid != 0 && (error = suser(p, 0)) != 0)
  1024. return (error);
  1025. if (rtableid < 0 || !rtable_exists((u_int)rtableid))
  1026. return (EINVAL);
  1027. p->p_p->ps_rtableid = (u_int)rtableid;
  1028. return (0);
  1029. }
  1030. /* ARGSUSED */
  1031. int
  1032. sys_getrtable(struct proc *p, void *v, register_t *retval)
  1033. {
  1034. *retval = (int)p->p_p->ps_rtableid;
  1035. return (0);
  1036. }
  1037. int
  1038. copyaddrout(struct proc *p, struct mbuf *name, struct sockaddr *sa,
  1039. socklen_t buflen, socklen_t *outlen)
  1040. {
  1041. int error;
  1042. socklen_t namelen = name->m_len;
  1043. /* SHOULD COPY OUT A CHAIN HERE */
  1044. error = copyout(mtod(name, caddr_t), sa, MIN(buflen, namelen));
  1045. if (error == 0) {
  1046. #ifdef KTRACE
  1047. if (KTRPOINT(p, KTR_STRUCT))
  1048. ktrsockaddr(p, mtod(name, caddr_t), namelen);
  1049. #endif
  1050. error = copyout(&namelen, outlen, sizeof(*outlen));
  1051. }
  1052. return (error);
  1053. }