summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_syscalls.c
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2013-03-08 00:03:07 +0000
committerattilio <attilio@FreeBSD.org>2013-03-08 00:03:07 +0000
commitbf1dc904466a6994f1b4cd94d2187edfeca7b187 (patch)
tree7d66370442268ff1c2639db0446b7970c995c657 /sys/kern/uipc_syscalls.c
parente98f58faf63a90d85e0e2ad78353915f9615a4eb (diff)
parent281d1157a14218414e773086b47c81754114b42a (diff)
downloadFreeBSD-src-bf1dc904466a6994f1b4cd94d2187edfeca7b187.zip
FreeBSD-src-bf1dc904466a6994f1b4cd94d2187edfeca7b187.tar.gz
MFC
Diffstat (limited to 'sys/kern/uipc_syscalls.c')
-rw-r--r--sys/kern/uipc_syscalls.c117
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;
OpenPOWER on IntegriCloud