diff options
author | attilio <attilio@FreeBSD.org> | 2013-03-08 00:03:07 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2013-03-08 00:03:07 +0000 |
commit | bf1dc904466a6994f1b4cd94d2187edfeca7b187 (patch) | |
tree | 7d66370442268ff1c2639db0446b7970c995c657 /sys/kern/uipc_syscalls.c | |
parent | e98f58faf63a90d85e0e2ad78353915f9615a4eb (diff) | |
parent | 281d1157a14218414e773086b47c81754114b42a (diff) | |
download | FreeBSD-src-bf1dc904466a6994f1b4cd94d2187edfeca7b187.zip FreeBSD-src-bf1dc904466a6994f1b4cd94d2187edfeca7b187.tar.gz |
MFC
Diffstat (limited to 'sys/kern/uipc_syscalls.c')
-rw-r--r-- | sys/kern/uipc_syscalls.c | 117 |
1 files changed, 88 insertions, 29 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index eca171c..894cffc 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -202,26 +202,23 @@ sys_bind(td, uap) struct sockaddr *sa; int error; - if ((error = getsockaddr(&sa, uap->name, uap->namelen)) != 0) - return (error); - - error = kern_bind(td, uap->s, sa); - free(sa, M_SONAME); + error = getsockaddr(&sa, uap->name, uap->namelen); + if (error == 0) { + error = kern_bind(td, uap->s, sa); + free(sa, M_SONAME); + } return (error); } -int -kern_bind(td, fd, sa) - struct thread *td; - int fd; - struct sockaddr *sa; +static int +kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) { struct socket *so; struct file *fp; int error; AUDIT_ARG_FD(fd); - AUDIT_ARG_SOCKADDR(td, sa); + AUDIT_ARG_SOCKADDR(td, dirfd, sa); error = getsock_cap(td->td_proc->p_fd, fd, CAP_BIND, &fp, NULL); if (error) return (error); @@ -232,13 +229,48 @@ kern_bind(td, fd, sa) #endif #ifdef MAC error = mac_socket_check_bind(td->td_ucred, so, sa); - if (error == 0) + if (error == 0) { +#endif + if (dirfd == AT_FDCWD) + error = sobind(so, sa, td); + else + error = sobindat(dirfd, so, sa, td); +#ifdef MAC + } #endif - error = sobind(so, sa, td); fdrop(fp, td); return (error); } +int +kern_bind(struct thread *td, int fd, struct sockaddr *sa) +{ + + return (kern_bindat(td, AT_FDCWD, fd, sa)); +} + +/* ARGSUSED */ +int +sys_bindat(td, uap) + struct thread *td; + struct bindat_args /* { + int fd; + int s; + caddr_t name; + int namelen; + } */ *uap; +{ + struct sockaddr *sa; + int error; + + error = getsockaddr(&sa, uap->name, uap->namelen); + if (error == 0) { + error = kern_bindat(td, uap->fd, uap->s, sa); + free(sa, M_SONAME); + } + return (error); +} + /* ARGSUSED */ int sys_listen(td, uap) @@ -436,7 +468,7 @@ kern_accept(struct thread *td, int s, struct sockaddr **name, *namelen = 0; goto done; } - AUDIT_ARG_SOCKADDR(td, sa); + AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa); if (name) { /* check sa_len before it is destroyed */ if (*namelen > sa->sa_len) @@ -511,20 +543,15 @@ sys_connect(td, uap) int error; error = getsockaddr(&sa, uap->name, uap->namelen); - if (error) - return (error); - - error = kern_connect(td, uap->s, sa); - free(sa, M_SONAME); + if (error == 0) { + error = kern_connect(td, uap->s, sa); + free(sa, M_SONAME); + } return (error); } - -int -kern_connect(td, fd, sa) - struct thread *td; - int fd; - struct sockaddr *sa; +static int +kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) { struct socket *so; struct file *fp; @@ -532,7 +559,7 @@ kern_connect(td, fd, sa) int interrupted = 0; AUDIT_ARG_FD(fd); - AUDIT_ARG_SOCKADDR(td, sa); + AUDIT_ARG_SOCKADDR(td, dirfd, sa); error = getsock_cap(td->td_proc->p_fd, fd, CAP_CONNECT, &fp, NULL); if (error) return (error); @@ -550,7 +577,10 @@ kern_connect(td, fd, sa) if (error) goto bad; #endif - error = soconnect(so, sa, td); + if (dirfd == AT_FDCWD) + error = soconnect(so, sa, td); + else + error = soconnectat(dirfd, so, sa, td); if (error) goto bad; if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { @@ -583,6 +613,35 @@ done1: } int +kern_connect(struct thread *td, int fd, struct sockaddr *sa) +{ + + return (kern_connectat(td, AT_FDCWD, fd, sa)); +} + +/* ARGSUSED */ +int +sys_connectat(td, uap) + struct thread *td; + struct connectat_args /* { + int fd; + int s; + caddr_t name; + int namelen; + } */ *uap; +{ + struct sockaddr *sa; + int error; + + error = getsockaddr(&sa, uap->name, uap->namelen); + if (error == 0) { + error = kern_connectat(td, uap->fd, uap->s, sa); + free(sa, M_SONAME); + } + return (error); +} + +int kern_socketpair(struct thread *td, int domain, int type, int protocol, int *rsv) { @@ -750,7 +809,7 @@ kern_sendit(td, s, mp, flags, control, segflg) AUDIT_ARG_FD(s); rights = CAP_SEND; if (mp->msg_name != NULL) { - AUDIT_ARG_SOCKADDR(td, mp->msg_name); + AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name); rights |= CAP_CONNECT; } error = getsock_cap(td->td_proc->p_fd, s, rights, &fp, NULL); @@ -998,7 +1057,7 @@ kern_recvit(td, s, mp, fromseg, controlp) error = 0; } if (fromsa != NULL) - AUDIT_ARG_SOCKADDR(td, fromsa); + AUDIT_ARG_SOCKADDR(td, AT_FDCWD, fromsa); #ifdef KTRACE if (ktruio != NULL) { ktruio->uio_resid = len - auio.uio_resid; |