1 /*- 2 * Copyright (c) 1982, 1986, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)sys_socket.c 8.1 (Berkeley) 6/10/93 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/domain.h> 38 #include <sys/file.h> 39 #include <sys/filedesc.h> 40 #include <sys/malloc.h> 41 #include <sys/proc.h> 42 #include <sys/protosw.h> 43 #include <sys/sigio.h> 44 #include <sys/signal.h> 45 #include <sys/signalvar.h> 46 #include <sys/socket.h> 47 #include <sys/socketvar.h> 48 #include <sys/filio.h> /* XXX */ 49 #include <sys/sockio.h> 50 #include <sys/stat.h> 51 #include <sys/uio.h> 52 #include <sys/ucred.h> 53 #include <sys/un.h> 54 #include <sys/unpcb.h> 55 #include <sys/user.h> 56 57 #include <net/if.h> 58 #include <net/if_var.h> 59 #include <net/route.h> 60 #include <net/vnet.h> 61 62 #include <netinet/in.h> 63 #include <netinet/in_pcb.h> 64 65 #include <security/mac/mac_framework.h> 66 67 static fo_rdwr_t soo_read; 68 static fo_rdwr_t soo_write; 69 static fo_ioctl_t soo_ioctl; 70 static fo_poll_t soo_poll; 71 extern fo_kqfilter_t soo_kqfilter; 72 static fo_stat_t soo_stat; 73 static fo_close_t soo_close; 74 static fo_fill_kinfo_t soo_fill_kinfo; 75 76 struct fileops socketops = { 77 .fo_read = soo_read, 78 .fo_write = soo_write, 79 .fo_truncate = invfo_truncate, 80 .fo_ioctl = soo_ioctl, 81 .fo_poll = soo_poll, 82 .fo_kqfilter = soo_kqfilter, 83 .fo_stat = soo_stat, 84 .fo_close = soo_close, 85 .fo_chmod = invfo_chmod, 86 .fo_chown = invfo_chown, 87 .fo_sendfile = invfo_sendfile, 88 .fo_fill_kinfo = soo_fill_kinfo, 89 .fo_flags = DFLAG_PASSABLE 90 }; 91 92 static int 93 soo_read(struct file *fp, struct uio *uio, struct ucred *active_cred, 94 int flags, struct thread *td) 95 { 96 struct socket *so = fp->f_data; 97 int error; 98 99 #ifdef MAC 100 error = mac_socket_check_receive(active_cred, so); 101 if (error) 102 return (error); 103 #endif 104 error = soreceive(so, 0, uio, 0, 0, 0); 105 return (error); 106 } 107 108 static int 109 soo_write(struct file *fp, struct uio *uio, struct ucred *active_cred, 110 int flags, struct thread *td) 111 { 112 struct socket *so = fp->f_data; 113 int error; 114 115 #ifdef MAC 116 error = mac_socket_check_send(active_cred, so); 117 if (error) 118 return (error); 119 #endif 120 error = sosend(so, 0, uio, 0, 0, 0, uio->uio_td); 121 if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) { 122 PROC_LOCK(uio->uio_td->td_proc); 123 tdsignal(uio->uio_td, SIGPIPE); 124 PROC_UNLOCK(uio->uio_td->td_proc); 125 } 126 return (error); 127 } 128 129 static int 130 soo_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred, 131 struct thread *td) 132 { 133 struct socket *so = fp->f_data; 134 int error = 0; 135 136 switch (cmd) { 137 case FIONBIO: 138 SOCK_LOCK(so); 139 if (*(int *)data) 140 so->so_state |= SS_NBIO; 141 else 142 so->so_state &= ~SS_NBIO; 143 SOCK_UNLOCK(so); 144 break; 145 146 case FIOASYNC: 147 /* 148 * XXXRW: This code separately acquires SOCK_LOCK(so) and 149 * SOCKBUF_LOCK(&so->so_rcv) even though they are the same 150 * mutex to avoid introducing the assumption that they are 151 * the same. 152 */ 153 if (*(int *)data) { 154 SOCK_LOCK(so); 155 so->so_state |= SS_ASYNC; 156 SOCK_UNLOCK(so); 157 SOCKBUF_LOCK(&so->so_rcv); 158 so->so_rcv.sb_flags |= SB_ASYNC; 159 SOCKBUF_UNLOCK(&so->so_rcv); 160 SOCKBUF_LOCK(&so->so_snd); 161 so->so_snd.sb_flags |= SB_ASYNC; 162 SOCKBUF_UNLOCK(&so->so_snd); 163 } else { 164 SOCK_LOCK(so); 165 so->so_state &= ~SS_ASYNC; 166 SOCK_UNLOCK(so); 167 SOCKBUF_LOCK(&so->so_rcv); 168 so->so_rcv.sb_flags &= ~SB_ASYNC; 169 SOCKBUF_UNLOCK(&so->so_rcv); 170 SOCKBUF_LOCK(&so->so_snd); 171 so->so_snd.sb_flags &= ~SB_ASYNC; 172 SOCKBUF_UNLOCK(&so->so_snd); 173 } 174 break; 175 176 case FIONREAD: 177 /* Unlocked read. */ 178 *(int *)data = sbavail(&so->so_rcv); 179 break; 180 181 case FIONWRITE: 182 /* Unlocked read. */ 183 *(int *)data = sbavail(&so->so_snd); 184 break; 185 186 case FIONSPACE: 187 /* Unlocked read. */ 188 if ((so->so_snd.sb_hiwat < sbused(&so->so_snd)) || 189 (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt)) 190 *(int *)data = 0; 191 else 192 *(int *)data = sbspace(&so->so_snd); 193 break; 194 195 case FIOSETOWN: 196 error = fsetown(*(int *)data, &so->so_sigio); 197 break; 198 199 case FIOGETOWN: 200 *(int *)data = fgetown(&so->so_sigio); 201 break; 202 203 case SIOCSPGRP: 204 error = fsetown(-(*(int *)data), &so->so_sigio); 205 break; 206 207 case SIOCGPGRP: 208 *(int *)data = -fgetown(&so->so_sigio); 209 break; 210 211 case SIOCATMARK: 212 /* Unlocked read. */ 213 *(int *)data = (so->so_rcv.sb_state & SBS_RCVATMARK) != 0; 214 break; 215 default: 216 /* 217 * Interface/routing/protocol specific ioctls: interface and 218 * routing ioctls should have a different entry since a 219 * socket is unnecessary. 220 */ 221 if (IOCGROUP(cmd) == 'i') 222 error = ifioctl(so, cmd, data, td); 223 else if (IOCGROUP(cmd) == 'r') { 224 CURVNET_SET(so->so_vnet); 225 error = rtioctl_fib(cmd, data, so->so_fibnum); 226 CURVNET_RESTORE(); 227 } else { 228 CURVNET_SET(so->so_vnet); 229 error = ((*so->so_proto->pr_usrreqs->pru_control) 230 (so, cmd, data, 0, td)); 231 CURVNET_RESTORE(); 232 } 233 break; 234 } 235 return (error); 236 } 237 238 static int 239 soo_poll(struct file *fp, int events, struct ucred *active_cred, 240 struct thread *td) 241 { 242 struct socket *so = fp->f_data; 243 #ifdef MAC 244 int error; 245 246 error = mac_socket_check_poll(active_cred, so); 247 if (error) 248 return (error); 249 #endif 250 return (sopoll(so, events, fp->f_cred, td)); 251 } 252 253 static int 254 soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred, 255 struct thread *td) 256 { 257 struct socket *so = fp->f_data; 258 struct sockbuf *sb; 259 #ifdef MAC 260 int error; 261 #endif 262 263 bzero((caddr_t)ub, sizeof (*ub)); 264 ub->st_mode = S_IFSOCK; 265 #ifdef MAC 266 error = mac_socket_check_stat(active_cred, so); 267 if (error) 268 return (error); 269 #endif 270 /* 271 * If SBS_CANTRCVMORE is set, but there's still data left in the 272 * receive buffer, the socket is still readable. 273 */ 274 sb = &so->so_rcv; 275 SOCKBUF_LOCK(sb); 276 if ((sb->sb_state & SBS_CANTRCVMORE) == 0 || sbavail(sb)) 277 ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; 278 ub->st_size = sbavail(sb) - sb->sb_ctl; 279 SOCKBUF_UNLOCK(sb); 280 281 sb = &so->so_snd; 282 SOCKBUF_LOCK(sb); 283 if ((sb->sb_state & SBS_CANTSENDMORE) == 0) 284 ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; 285 SOCKBUF_UNLOCK(sb); 286 ub->st_uid = so->so_cred->cr_uid; 287 ub->st_gid = so->so_cred->cr_gid; 288 return (*so->so_proto->pr_usrreqs->pru_sense)(so, ub); 289 } 290 291 /* 292 * API socket close on file pointer. We call soclose() to close the socket 293 * (including initiating closing protocols). soclose() will sorele() the 294 * file reference but the actual socket will not go away until the socket's 295 * ref count hits 0. 296 */ 297 static int 298 soo_close(struct file *fp, struct thread *td) 299 { 300 int error = 0; 301 struct socket *so; 302 303 so = fp->f_data; 304 fp->f_ops = &badfileops; 305 fp->f_data = NULL; 306 307 if (so) 308 error = soclose(so); 309 return (error); 310 } 311 312 static int 313 soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) 314 { 315 struct sockaddr *sa; 316 struct inpcb *inpcb; 317 struct unpcb *unpcb; 318 struct socket *so; 319 int error; 320 321 kif->kf_type = KF_TYPE_SOCKET; 322 so = fp->f_data; 323 kif->kf_sock_domain = so->so_proto->pr_domain->dom_family; 324 kif->kf_sock_type = so->so_type; 325 kif->kf_sock_protocol = so->so_proto->pr_protocol; 326 kif->kf_un.kf_sock.kf_sock_pcb = (uintptr_t)so->so_pcb; 327 switch (kif->kf_sock_domain) { 328 case AF_INET: 329 case AF_INET6: 330 if (kif->kf_sock_protocol == IPPROTO_TCP) { 331 if (so->so_pcb != NULL) { 332 inpcb = (struct inpcb *)(so->so_pcb); 333 kif->kf_un.kf_sock.kf_sock_inpcb = 334 (uintptr_t)inpcb->inp_ppcb; 335 } 336 } 337 break; 338 case AF_UNIX: 339 if (so->so_pcb != NULL) { 340 unpcb = (struct unpcb *)(so->so_pcb); 341 if (unpcb->unp_conn) { 342 kif->kf_un.kf_sock.kf_sock_unpconn = 343 (uintptr_t)unpcb->unp_conn; 344 kif->kf_un.kf_sock.kf_sock_rcv_sb_state = 345 so->so_rcv.sb_state; 346 kif->kf_un.kf_sock.kf_sock_snd_sb_state = 347 so->so_snd.sb_state; 348 } 349 } 350 break; 351 } 352 error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); 353 if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_local)) { 354 bcopy(sa, &kif->kf_sa_local, sa->sa_len); 355 free(sa, M_SONAME); 356 } 357 error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa); 358 if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) { 359 bcopy(sa, &kif->kf_sa_peer, sa->sa_len); 360 free(sa, M_SONAME); 361 } 362 strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name, 363 sizeof(kif->kf_path)); 364 return (0); 365 } 366