aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrooks Davis <brooks@FreeBSD.org>2021-11-29 22:02:59 +0000
committerBrooks Davis <brooks@FreeBSD.org>2021-11-29 22:04:41 +0000
commit28f047188492c8f2ddca66f162fd2ac9bdc170a6 (patch)
treec900ca99cb499e02a4e65fabb8a3fbaf73665497
parent3660e76a2220d5218b4c28c2d2f2c90142f1ec4e (diff)
downloadsrc-28f047188492c8f2ddca66f162fd2ac9bdc170a6.tar.gz
src-28f047188492c8f2ddca66f162fd2ac9bdc170a6.zip
uipc: rework recvfrom, getsockname, getpeername
Stop using <foo>_args structs as part of internal kernel APIs. Add a kern_recvfrom and adjust getsockname and getpeername's equivalent functions to take individual arguments rather than a uap pointer. Adopt a convention from CheriBSD that a function interacting with userspace pointers and sitting between the sys_<foo> syscall and kern_<foo> implementation is named user_<foo>. Reviewed by: kib, imp
-rw-r--r--sys/kern/uipc_syscalls.c79
1 files changed, 37 insertions, 42 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 44079bae1e9b..3111ce7e16e4 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -78,10 +78,6 @@ static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp);
static int accept1(struct thread *td, int s, struct sockaddr *uname,
socklen_t *anamelen, int flags);
-static int getsockname1(struct thread *td, struct getsockname_args *uap,
- int compat);
-static int getpeername1(struct thread *td, struct getpeername_args *uap,
- int compat);
static int sockargs(struct mbuf **, char *, socklen_t, int);
/*
@@ -1069,40 +1065,48 @@ recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp)
return (error);
}
-int
-sys_recvfrom(struct thread *td, struct recvfrom_args *uap)
+static int
+kern_recvfrom(struct thread *td, int s, void *buf, size_t len, int flags,
+ struct sockaddr *from, socklen_t *fromlenaddr)
{
struct msghdr msg;
struct iovec aiov;
int error;
- if (uap->fromlenaddr) {
- error = copyin(uap->fromlenaddr,
- &msg.msg_namelen, sizeof (msg.msg_namelen));
+ if (fromlenaddr != NULL) {
+ error = copyin(fromlenaddr, &msg.msg_namelen,
+ sizeof (msg.msg_namelen));
if (error != 0)
goto done2;
} else {
msg.msg_namelen = 0;
}
- msg.msg_name = uap->from;
+ msg.msg_name = from;
msg.msg_iov = &aiov;
msg.msg_iovlen = 1;
- aiov.iov_base = uap->buf;
- aiov.iov_len = uap->len;
+ aiov.iov_base = buf;
+ aiov.iov_len = len;
msg.msg_control = 0;
- msg.msg_flags = uap->flags;
- error = recvit(td, uap->s, &msg, uap->fromlenaddr);
+ msg.msg_flags = flags;
+ error = recvit(td, s, &msg, fromlenaddr);
done2:
return (error);
}
+int
+sys_recvfrom(struct thread *td, struct recvfrom_args *uap)
+{
+ return (kern_recvfrom(td, uap->s, uap->buf, uap->len,
+ uap->flags, uap->from, uap->fromlenaddr));
+}
+
+
#ifdef COMPAT_OLDSOCK
int
orecvfrom(struct thread *td, struct recvfrom_args *uap)
{
-
- uap->flags |= MSG_COMPAT;
- return (sys_recvfrom(td, uap));
+ return (kern_recvfrom(td, uap->s, uap->buf, uap->len,
+ uap->flags | MSG_COMPAT, uap->from, uap->fromlenaddr));
}
#endif
@@ -1331,21 +1335,19 @@ kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
return (error);
}
-/*
- * getsockname1() - Get socket name.
- */
static int
-getsockname1(struct thread *td, struct getsockname_args *uap, int compat)
+user_getsockname(struct thread *td, int fdes, struct sockaddr *asa,
+ socklen_t *alen, bool compat)
{
struct sockaddr *sa;
socklen_t len;
int error;
- error = copyin(uap->alen, &len, sizeof(len));
+ error = copyin(alen, &len, sizeof(len));
if (error != 0)
return (error);
- error = kern_getsockname(td, uap->fdes, &sa, &len);
+ error = kern_getsockname(td, fdes, &sa, &len);
if (error != 0)
return (error);
@@ -1354,11 +1356,11 @@ getsockname1(struct thread *td, struct getsockname_args *uap, int compat)
if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT))
((struct osockaddr *)sa)->sa_family = sa->sa_family;
#endif
- error = copyout(sa, uap->asa, (u_int)len);
+ error = copyout(sa, asa, len);
}
free(sa, M_SONAME);
if (error == 0)
- error = copyout(&len, uap->alen, sizeof(len));
+ error = copyout(&len, alen, sizeof(len));
return (error);
}
@@ -1404,34 +1406,30 @@ bad:
int
sys_getsockname(struct thread *td, struct getsockname_args *uap)
{
-
- return (getsockname1(td, uap, 0));
+ return (user_getsockname(td, uap->fdes, uap->asa, uap->alen, false));
}
#ifdef COMPAT_OLDSOCK
int
ogetsockname(struct thread *td, struct getsockname_args *uap)
{
-
- return (getsockname1(td, uap, 1));
+ return (user_getsockname(td, uap->fdes, uap->asa, uap->alen, true));
}
#endif /* COMPAT_OLDSOCK */
-/*
- * getpeername1() - Get name of peer for connected socket.
- */
static int
-getpeername1(struct thread *td, struct getpeername_args *uap, int compat)
+user_getpeername(struct thread *td, int fdes, struct sockaddr *asa,
+ socklen_t *alen, int compat)
{
struct sockaddr *sa;
socklen_t len;
int error;
- error = copyin(uap->alen, &len, sizeof (len));
+ error = copyin(alen, &len, sizeof (len));
if (error != 0)
return (error);
- error = kern_getpeername(td, uap->fdes, &sa, &len);
+ error = kern_getpeername(td, fdes, &sa, &len);
if (error != 0)
return (error);
@@ -1440,11 +1438,11 @@ getpeername1(struct thread *td, struct getpeername_args *uap, int compat)
if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT))
((struct osockaddr *)sa)->sa_family = sa->sa_family;
#endif
- error = copyout(sa, uap->asa, (u_int)len);
+ error = copyout(sa, asa, len);
}
free(sa, M_SONAME);
if (error == 0)
- error = copyout(&len, uap->alen, sizeof(len));
+ error = copyout(&len, alen, sizeof(len));
return (error);
}
@@ -1495,17 +1493,14 @@ done:
int
sys_getpeername(struct thread *td, struct getpeername_args *uap)
{
-
- return (getpeername1(td, uap, 0));
+ return (user_getpeername(td, uap->fdes, uap->asa, uap->alen, 0));
}
#ifdef COMPAT_OLDSOCK
int
ogetpeername(struct thread *td, struct ogetpeername_args *uap)
{
-
- /* XXX uap should have type `getpeername_args *' to begin with. */
- return (getpeername1(td, (struct getpeername_args *)uap, 1));
+ return (user_getpeername(td, uap->fdes, uap->asa, uap->alen, 1));
}
#endif /* COMPAT_OLDSOCK */