Page MenuHomeFreeBSD

D7724.1793429306.diff
No OneTemporary

Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None

D7724.1793429306.diff

Index: sys/compat/cloudabi/cloudabi_sock.c
===================================================================
--- sys/compat/cloudabi/cloudabi_sock.c
+++ sys/compat/cloudabi/cloudabi_sock.c
@@ -210,7 +210,7 @@
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;
Index: sys/compat/linux/linux_socket.c
===================================================================
--- sys/compat/linux/linux_socket.c
+++ sys/compat/linux/linux_socket.c
@@ -855,7 +855,7 @@
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;
Index: sys/kern/kern_sendfile.c
===================================================================
--- sys/kern/kern_sendfile.c
+++ sys/kern/kern_sendfile.c
@@ -502,7 +502,7 @@
* 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;
Index: sys/kern/uipc_syscalls.c
===================================================================
--- sys/kern/uipc_syscalls.c
+++ sys/kern/uipc_syscalls.c
@@ -93,22 +93,47 @@
*/
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)
{
struct file *fp;
+ struct filedesc *fdp;
int error;
-
- error = fget_unlocked(td->td_proc->p_fd, fd, rightsp, &fp, NULL);
- if (error != 0)
- return (error);
- if (fp->f_type != DTYPE_SOCKET) {
+ bool locked;
+ seq_t seq;
+
+ error = 0;
+ locked = false;
+ fdp = td->td_proc->p_fd;
+ for (;;) {
+ error = fget_unlocked(fdp, fd, rightsp, &fp, &seq);
+ if (error != 0)
+ goto out;
+ if (fp->f_type != DTYPE_SOCKET) {
+ fdrop(fp, td);
+ error = ENOTSOCK;
+ goto out;
+ }
+ if (havecaps != NULL) {
+ if (filecaps_copy(&fdp->fd_ofiles[fd].fde_caps,
+ havecaps, locked)) {
+ fdrop(fp, td);
+ FILEDESC_SLOCK(fdp);
+ locked = true;
+ continue;
+ }
+ }
+ if (locked || !fd_modified(fdp, fd, seq))
+ break;
fdrop(fp, td);
- return (ENOTSOCK);
}
+
if (fflagp != NULL)
*fflagp = fp->f_flag;
*fpp = fp;
- return (0);
+out:
+ if (locked)
+ FILEDESC_SUNLOCK(fdp);
+ return (error);
}
/*
@@ -201,7 +226,7 @@
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;
@@ -262,7 +287,7 @@
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
@@ -335,6 +360,7 @@
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;
@@ -345,7 +371,7 @@
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;
@@ -358,7 +384,8 @@
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();
@@ -467,6 +494,8 @@
* 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;
@@ -545,7 +574,7 @@
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;
@@ -805,7 +834,7 @@
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;
@@ -1006,7 +1035,7 @@
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;
@@ -1321,7 +1350,7 @@
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);
@@ -1395,7 +1424,7 @@
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);
@@ -1476,7 +1505,7 @@
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);
@@ -1537,7 +1566,7 @@
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;
@@ -1636,7 +1665,7 @@
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;
Index: sys/netinet/sctp_syscalls.c
===================================================================
--- sys/netinet/sctp_syscalls.c
+++ sys/netinet/sctp_syscalls.c
@@ -248,7 +248,7 @@
}
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 @@
}
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 @@
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
Index: sys/sys/socketvar.h
===================================================================
--- sys/sys/socketvar.h
+++ sys/sys/socketvar.h
@@ -321,6 +321,7 @@
extern so_gen_t so_gencnt;
struct file;
+struct filecaps;
struct filedesc;
struct mbuf;
struct sockaddr;
@@ -340,7 +341,7 @@
*/
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);

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 31, 6:48 AM (19 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41255157
Default Alt Text
D7724.1793429306.diff (7 KB)

Event Timeline