Add getsock

All but one consumers of getsock_cap only pass 4 arguments.
Take advantage of it.
This commit is contained in:
Mateusz Guzik 2022-09-07 15:41:55 +00:00
parent a2ad70923f
commit 3212ad15ab
6 changed files with 49 additions and 48 deletions

View File

@ -970,7 +970,6 @@ linux_connect(struct thread *td, struct linux_connect_args *args)
struct socket *so;
struct sockaddr *sa;
struct file *fp;
u_int fflag;
int error;
error = linux_to_bsd_sockaddr(PTRIN(args->name), &sa,
@ -988,14 +987,13 @@ linux_connect(struct thread *td, struct linux_connect_args *args)
* when on a non-blocking socket. Instead it returns the
* error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD.
*/
error = getsock_cap(td, args->s, &cap_connect_rights,
&fp, &fflag, NULL);
error = getsock(td, args->s, &cap_connect_rights, &fp);
if (error != 0)
return (error);
error = EISCONN;
so = fp->f_data;
if (fflag & FNONBLOCK) {
if (atomic_load_int(&fp->f_flag) & FNONBLOCK) {
SOCK_LOCK(so);
if (so->so_emuldata == 0)
error = so->so_error;
@ -1058,7 +1056,7 @@ linux_accept_common(struct thread *td, int s, l_uintptr_t addr,
error = EINVAL;
break;
case EINVAL:
error1 = getsock_cap(td, s, &cap_accept_rights, &fp1, NULL, NULL);
error1 = getsock(td, s, &cap_accept_rights, &fp1);
if (error1 != 0) {
error = error1;
break;
@ -1207,7 +1205,7 @@ linux_send(struct thread *td, struct linux_send_args *args)
int tolen;
} */ bsd_args;
struct file *fp;
int error, fflag;
int error;
bsd_args.s = args->s;
bsd_args.buf = (caddr_t)PTRIN(args->msg);
@ -1221,10 +1219,9 @@ linux_send(struct thread *td, struct linux_send_args *args)
* Linux doesn't return ENOTCONN for non-blocking sockets.
* Instead it returns the EAGAIN.
*/
error = getsock_cap(td, args->s, &cap_send_rights, &fp,
&fflag, NULL);
error = getsock(td, args->s, &cap_send_rights, &fp);
if (error == 0) {
if (fflag & FNONBLOCK)
if (atomic_load_int(&fp->f_flag) & FNONBLOCK)
error = EAGAIN;
fdrop(fp, td);
}
@ -1275,8 +1272,7 @@ linux_sendto(struct thread *td, struct linux_sendto_args *args)
return (linux_sendto_hdrincl(td, args));
bzero(&msg, sizeof(msg));
error = getsock_cap(td, args->s, &cap_send_connect_rights,
&fp, NULL, NULL);
error = getsock(td, args->s, &cap_send_connect_rights, &fp);
if (error != 0)
return (error);
so = fp->f_data;
@ -1366,7 +1362,7 @@ linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
void *data;
l_size_t len;
l_size_t clen;
int error, fflag;
int error;
error = copyin(msghdr, &linux_msghdr, sizeof(linux_msghdr));
if (error != 0)
@ -1409,8 +1405,7 @@ linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
if (sa_family == AF_UNIX)
goto bad;
error = getsock_cap(td, s, &cap_send_rights, &fp,
&fflag, NULL);
error = getsock(td, s, &cap_send_rights, &fp);
if (error != 0)
goto bad;
so = fp->f_data;
@ -1908,8 +1903,7 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
struct file *fp;
int error;
error = getsock_cap(td, args->s, &cap_recv_rights,
&fp, NULL, NULL);
error = getsock(td, args->s, &cap_recv_rights, &fp);
if (error != 0)
return (error);
fdrop(fp, td);
@ -1927,8 +1921,7 @@ linux_recvmmsg_common(struct thread *td, l_int s, struct l_mmsghdr *msg,
l_uint retval;
int error, datagrams;
error = getsock_cap(td, s, &cap_recv_rights,
&fp, NULL, NULL);
error = getsock(td, s, &cap_recv_rights, &fp);
if (error != 0)
return (error);
datagrams = 0;

View File

@ -653,8 +653,7 @@ sendfile_getsock(struct thread *td, int s, struct file **sock_fp,
/*
* The socket must be a stream socket and connected.
*/
error = getsock_cap(td, s, &cap_send_rights,
sock_fp, NULL, NULL);
error = getsock(td, s, &cap_send_rights, sock_fp);
if (error != 0)
return (error);
*so = (*sock_fp)->f_data;

View File

@ -110,6 +110,23 @@ getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
return (0);
}
int
getsock(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp)
{
struct file *fp;
int error;
error = fget_unlocked(td, fd, rightsp, &fp);
if (__predict_false(error != 0))
return (error);
if (__predict_false(fp->f_type != DTYPE_SOCKET)) {
fdrop(fp, td);
return (ENOTSOCK);
}
*fpp = fp;
return (0);
}
/*
* System call interface to the socket abstraction.
*/
@ -194,8 +211,7 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
AUDIT_ARG_FD(fd);
AUDIT_ARG_SOCKADDR(td, dirfd, sa);
error = getsock_cap(td, fd, &cap_bind_rights,
&fp, NULL, NULL);
error = getsock(td, fd, &cap_bind_rights, &fp);
if (error != 0)
return (error);
so = fp->f_data;
@ -247,8 +263,7 @@ kern_listen(struct thread *td, int s, int backlog)
int error;
AUDIT_ARG_FD(s);
error = getsock_cap(td, s, &cap_listen_rights,
&fp, NULL, NULL);
error = getsock(td, s, &cap_listen_rights, &fp);
if (error == 0) {
so = fp->f_data;
#ifdef MAC
@ -491,8 +506,7 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
AUDIT_ARG_FD(fd);
AUDIT_ARG_SOCKADDR(td, dirfd, sa);
error = getsock_cap(td, fd, &cap_connect_rights,
&fp, NULL, NULL);
error = getsock(td, fd, &cap_connect_rights, &fp);
if (error != 0)
return (error);
so = fp->f_data;
@ -738,7 +752,7 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
rights = &cap_send_connect_rights;
}
error = getsock_cap(td, s, rights, &fp, NULL, NULL);
error = getsock(td, s, rights, &fp);
if (error != 0) {
m_freem(control);
return (error);
@ -916,8 +930,7 @@ kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg,
*controlp = NULL;
AUDIT_ARG_FD(s);
error = getsock_cap(td, s, &cap_recv_rights,
&fp, NULL, NULL);
error = getsock(td, s, &cap_recv_rights, &fp);
if (error != 0)
return (error);
so = fp->f_data;
@ -1205,8 +1218,7 @@ kern_shutdown(struct thread *td, int s, int how)
int error;
AUDIT_ARG_FD(s);
error = getsock_cap(td, s, &cap_shutdown_rights,
&fp, NULL, NULL);
error = getsock(td, s, &cap_shutdown_rights, &fp);
if (error == 0) {
so = fp->f_data;
error = soshutdown(so, how);
@ -1263,8 +1275,7 @@ kern_setsockopt(struct thread *td, int s, int level, int name, const void *val,
}
AUDIT_ARG_FD(s);
error = getsock_cap(td, s, &cap_setsockopt_rights,
&fp, NULL, NULL);
error = getsock(td, s, &cap_setsockopt_rights, &fp);
if (error == 0) {
so = fp->f_data;
error = sosetopt(so, &sopt);
@ -1328,8 +1339,7 @@ kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
}
AUDIT_ARG_FD(s);
error = getsock_cap(td, s, &cap_getsockopt_rights,
&fp, NULL, NULL);
error = getsock(td, s, &cap_getsockopt_rights, &fp);
if (error == 0) {
so = fp->f_data;
error = sogetopt(so, &sopt);
@ -1378,8 +1388,7 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
int error;
AUDIT_ARG_FD(fd);
error = getsock_cap(td, fd, &cap_getsockname_rights,
&fp, NULL, NULL);
error = getsock(td, fd, &cap_getsockname_rights, &fp);
if (error != 0)
return (error);
so = fp->f_data;
@ -1460,8 +1469,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
int error;
AUDIT_ARG_FD(fd);
error = getsock_cap(td, fd, &cap_getpeername_rights,
&fp, NULL, NULL);
error = getsock(td, fd, &cap_getpeername_rights, &fp);
if (error != 0)
return (error);
so = fp->f_data;

View File

@ -449,7 +449,6 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl)
struct ovpn_softc *sc = ifp->if_softc;
struct thread *td = curthread;
struct socket *so = NULL;
u_int fflag;
int fd;
uint32_t peerid;
int ret = 0, i;
@ -476,8 +475,7 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl)
fd = nvlist_get_number(nvl, "fd");
/* Look up the userspace process and use the fd to find the socket. */
ret = getsock_cap(td, fd, &cap_connect_rights, &fp,
&fflag, NULL);
ret = getsock(td, fd, &cap_connect_rights, &fp);
if (ret != 0)
return (ret);

View File

@ -153,10 +153,11 @@ sys_sctp_peeloff(td, uap)
int error, fd;
AUDIT_ARG_FD(uap->sd);
error = getsock_cap(td, uap->sd, cap_rights_init_one(&rights, CAP_PEELOFF),
&headfp, &fflag, NULL);
error = getsock(td, uap->sd, cap_rights_init_one(&rights, CAP_PEELOFF),
&headfp);
if (error != 0)
goto done2;
fflag = atomic_load_int(&fp->f_flag);
head = headfp->f_data;
if (head->so_proto->pr_protocol != IPPROTO_SCTP) {
error = EOPNOTSUPP;
@ -252,7 +253,7 @@ sys_sctp_generic_sendmsg (td, uap)
}
AUDIT_ARG_FD(uap->sd);
error = getsock_cap(td, uap->sd, &rights, &fp, NULL, NULL);
error = getsock(td, uap->sd, &rights, &fp);
if (error != 0)
goto sctp_bad;
#ifdef KTRACE
@ -361,7 +362,7 @@ sys_sctp_generic_sendmsg_iov(td, uap)
}
AUDIT_ARG_FD(uap->sd);
error = getsock_cap(td, uap->sd, &rights, &fp, NULL, NULL);
error = getsock(td, uap->sd, &rights, &fp);
if (error != 0)
goto sctp_bad1;
@ -472,8 +473,8 @@ sys_sctp_generic_recvmsg(td, uap)
int error, fromlen, i, msg_flags;
AUDIT_ARG_FD(uap->sd);
error = getsock_cap(td, uap->sd, cap_rights_init_one(&rights, CAP_RECV),
&fp, NULL, NULL);
error = getsock(td, uap->sd, cap_rights_init_one(&rights, CAP_RECV),
&fp);
if (error != 0)
return (error);
#ifdef COMPAT_FREEBSD32

View File

@ -450,6 +450,8 @@ int getsockaddr(struct sockaddr **namp, const struct sockaddr *uaddr,
size_t len);
int getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
struct file **fpp, u_int *fflagp, struct filecaps *havecaps);
int getsock(struct thread *td, int fd, cap_rights_t *rightsp,
struct file **fpp);
void soabort(struct socket *so);
int soaccept(struct socket *so, struct sockaddr **nam);
void soaio_enqueue(struct task *task);