mirror of
https://github.com/opnsense/src.git
synced 2026-06-04 22:32:43 -04:00
capsicum: propagate rights on accept(2)
Descriptor returned by accept(2) should inherits capabilities rights from the listening socket. PR: 201052 Reviewed by: emaste, jonathan Discussed with: many Differential Revision: https://reviews.freebsd.org/D7724
This commit is contained in:
parent
32f7d047c3
commit
85b0f9de11
6 changed files with 29 additions and 21 deletions
|
|
@ -210,7 +210,7 @@ cloudabi_sys_sock_stat_get(struct thread *td,
|
|||
int error;
|
||||
|
||||
error = getsock_cap(td, uap->sock, cap_rights_init(&rights,
|
||||
CAP_GETSOCKOPT, CAP_GETPEERNAME, CAP_GETSOCKNAME), &fp, NULL);
|
||||
CAP_GETSOCKOPT, CAP_GETPEERNAME, CAP_GETSOCKNAME), &fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
|
|
|
|||
|
|
@ -855,7 +855,7 @@ linux_accept_common(struct thread *td, int s, l_uintptr_t addr,
|
|||
if (error == EFAULT && namelen != sizeof(struct sockaddr_in))
|
||||
return (EINVAL);
|
||||
if (error == EINVAL) {
|
||||
error1 = getsock_cap(td, s, &rights, &fp, NULL);
|
||||
error1 = getsock_cap(td, s, &rights, &fp, NULL, NULL);
|
||||
if (error1 != 0)
|
||||
return (error1);
|
||||
so = fp->f_data;
|
||||
|
|
|
|||
|
|
@ -502,7 +502,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_rights_init(&rights, CAP_SEND),
|
||||
sock_fp, NULL);
|
||||
sock_fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
*so = (*sock_fp)->f_data;
|
||||
|
|
|
|||
|
|
@ -89,20 +89,23 @@ static int sockargs(struct mbuf **, char *, socklen_t, int);
|
|||
/*
|
||||
* Convert a user file descriptor to a kernel file entry and check if required
|
||||
* capability rights are present.
|
||||
* If required copy of current set of capability rights is returned.
|
||||
* A reference on the file entry is held upon returning.
|
||||
*/
|
||||
int
|
||||
getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
|
||||
struct file **fpp, u_int *fflagp)
|
||||
struct file **fpp, u_int *fflagp, struct filecaps *havecapsp)
|
||||
{
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
error = fget_unlocked(td->td_proc->p_fd, fd, rightsp, &fp, NULL);
|
||||
error = fget_cap(td, fd, rightsp, &fp, havecapsp);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (fp->f_type != DTYPE_SOCKET) {
|
||||
fdrop(fp, td);
|
||||
if (havecapsp != NULL)
|
||||
filecaps_free(havecapsp);
|
||||
return (ENOTSOCK);
|
||||
}
|
||||
if (fflagp != NULL)
|
||||
|
|
@ -188,7 +191,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_rights_init(&rights, CAP_BIND),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
|
|
@ -235,7 +238,7 @@ sys_listen(struct thread *td, struct listen_args *uap)
|
|||
|
||||
AUDIT_ARG_FD(uap->s);
|
||||
error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_LISTEN),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
#ifdef MAC
|
||||
|
|
@ -308,6 +311,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
|
|||
struct file *headfp, *nfp = NULL;
|
||||
struct sockaddr *sa = NULL;
|
||||
struct socket *head, *so;
|
||||
struct filecaps fcaps;
|
||||
cap_rights_t rights;
|
||||
u_int fflag;
|
||||
pid_t pgid;
|
||||
|
|
@ -318,7 +322,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
|
|||
|
||||
AUDIT_ARG_FD(s);
|
||||
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_ACCEPT),
|
||||
&headfp, &fflag);
|
||||
&headfp, &fflag, &fcaps);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
head = headfp->f_data;
|
||||
|
|
@ -331,7 +335,8 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
|
|||
if (error != 0)
|
||||
goto done;
|
||||
#endif
|
||||
error = falloc(td, &nfp, &fd, (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0);
|
||||
error = falloc_caps(td, &nfp, &fd,
|
||||
(flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0, &fcaps);
|
||||
if (error != 0)
|
||||
goto done;
|
||||
ACCEPT_LOCK();
|
||||
|
|
@ -440,6 +445,8 @@ noconnection:
|
|||
* a reference on nfp to the caller on success if they request it.
|
||||
*/
|
||||
done:
|
||||
if (nfp == NULL)
|
||||
filecaps_free(&fcaps);
|
||||
if (fp != NULL) {
|
||||
if (error == 0) {
|
||||
*fp = nfp;
|
||||
|
|
@ -511,7 +518,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_rights_init(&rights, CAP_CONNECT),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
|
|
@ -754,7 +761,7 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
|
|||
AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
|
||||
cap_rights_set(&rights, CAP_CONNECT);
|
||||
}
|
||||
error = getsock_cap(td, s, &rights, &fp, NULL);
|
||||
error = getsock_cap(td, s, &rights, &fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = (struct socket *)fp->f_data;
|
||||
|
|
@ -923,7 +930,7 @@ kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg,
|
|||
|
||||
AUDIT_ARG_FD(s);
|
||||
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_RECV),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
|
|
@ -1198,7 +1205,7 @@ sys_shutdown(struct thread *td, struct shutdown_args *uap)
|
|||
|
||||
AUDIT_ARG_FD(uap->s);
|
||||
error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_SHUTDOWN),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
error = soshutdown(so, uap->how);
|
||||
|
|
@ -1257,7 +1264,7 @@ kern_setsockopt(struct thread *td, int s, int level, int name, void *val,
|
|||
|
||||
AUDIT_ARG_FD(s);
|
||||
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SETSOCKOPT),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
error = sosetopt(so, &sopt);
|
||||
|
|
@ -1323,7 +1330,7 @@ kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
|
|||
|
||||
AUDIT_ARG_FD(s);
|
||||
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_GETSOCKOPT),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
error = sogetopt(so, &sopt);
|
||||
|
|
@ -1376,7 +1383,7 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
|
|||
|
||||
AUDIT_ARG_FD(fd);
|
||||
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETSOCKNAME),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
|
|
@ -1463,7 +1470,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
|
|||
|
||||
AUDIT_ARG_FD(fd);
|
||||
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETPEERNAME),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ sys_sctp_generic_sendmsg (td, uap)
|
|||
}
|
||||
|
||||
AUDIT_ARG_FD(uap->sd);
|
||||
error = getsock_cap(td, uap->sd, &rights, &fp, NULL);
|
||||
error = getsock_cap(td, uap->sd, &rights, &fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
goto sctp_bad;
|
||||
#ifdef KTRACE
|
||||
|
|
@ -361,7 +361,7 @@ sys_sctp_generic_sendmsg_iov(td, uap)
|
|||
}
|
||||
|
||||
AUDIT_ARG_FD(uap->sd);
|
||||
error = getsock_cap(td, uap->sd, &rights, &fp, NULL);
|
||||
error = getsock_cap(td, uap->sd, &rights, &fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
goto sctp_bad1;
|
||||
|
||||
|
|
@ -477,7 +477,7 @@ sys_sctp_generic_recvmsg(td, uap)
|
|||
|
||||
AUDIT_ARG_FD(uap->sd);
|
||||
error = getsock_cap(td, uap->sd, cap_rights_init(&rights, CAP_RECV),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ extern u_long sb_max;
|
|||
extern so_gen_t so_gencnt;
|
||||
|
||||
struct file;
|
||||
struct filecaps;
|
||||
struct filedesc;
|
||||
struct mbuf;
|
||||
struct sockaddr;
|
||||
|
|
@ -340,7 +341,7 @@ struct uio;
|
|||
*/
|
||||
int getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len);
|
||||
int getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
|
||||
struct file **fpp, u_int *fflagp);
|
||||
struct file **fpp, u_int *fflagp, struct filecaps *havecaps);
|
||||
void soabort(struct socket *so);
|
||||
int soaccept(struct socket *so, struct sockaddr **nam);
|
||||
void soaio_enqueue(struct task *task);
|
||||
|
|
|
|||
Loading…
Reference in a new issue