mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-30 13:44:55 +00:00
socket: Pass capsicum rights down to socket option handlers
One needs the CAP_GETSOCKOPT and CAP_SETSOCKOPT rights to call getsockopt(2) and setsockopt(2) on a socket descriptor, respectively. The syscall layer checks this, but individual socket option handlers have no access to the file descriptor and so can't check for additional rights, should the want to do so. In particular, a forthcoming implementation of SO_SPLICE logically requires at least CAP_RECV and CAP_SEND rights. Modify the syscall layer to look up Capsicum rights on the descriptor and pass that along to socket option handlers; this way, the handlers can check for additional rights if they need to. Reviewed by: gallatin, glebius MFC after: 2 weeks Sponsored by: Klara, Inc. Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D45673
This commit is contained in:
parent
bdf2c8fff9
commit
e2e771deec
|
@ -1220,6 +1220,7 @@ kern_setsockopt(struct thread *td, int s, int level, int name, const void *val,
|
|||
{
|
||||
struct socket *so;
|
||||
struct file *fp;
|
||||
struct filecaps fcaps;
|
||||
struct sockopt sopt;
|
||||
int error;
|
||||
|
||||
|
@ -1245,8 +1246,10 @@ kern_setsockopt(struct thread *td, int s, int level, int name, const void *val,
|
|||
}
|
||||
|
||||
AUDIT_ARG_FD(s);
|
||||
error = getsock(td, s, &cap_setsockopt_rights, &fp);
|
||||
error = getsock_cap(td, s, &cap_setsockopt_rights, &fp,
|
||||
&fcaps);
|
||||
if (error == 0) {
|
||||
sopt.sopt_rights = &fcaps.fc_rights;
|
||||
so = fp->f_data;
|
||||
error = sosetopt(so, &sopt);
|
||||
fdrop(fp, td);
|
||||
|
@ -1284,6 +1287,7 @@ kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
|
|||
{
|
||||
struct socket *so;
|
||||
struct file *fp;
|
||||
struct filecaps fcaps;
|
||||
struct sockopt sopt;
|
||||
int error;
|
||||
|
||||
|
@ -1309,8 +1313,9 @@ kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
|
|||
}
|
||||
|
||||
AUDIT_ARG_FD(s);
|
||||
error = getsock(td, s, &cap_getsockopt_rights, &fp);
|
||||
error = getsock_cap(td, s, &cap_getsockopt_rights, &fp, &fcaps);
|
||||
if (error == 0) {
|
||||
sopt.sopt_rights = &fcaps.fc_rights;
|
||||
so = fp->f_data;
|
||||
error = sogetopt(so, &sopt);
|
||||
*valsize = sopt.sopt_valsize;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#error "no user-serviceable parts inside"
|
||||
#endif
|
||||
|
||||
struct cap_rights;
|
||||
struct thread;
|
||||
struct socket;
|
||||
|
||||
|
@ -50,6 +51,7 @@ struct sockopt {
|
|||
int sopt_name; /* third arg of [gs]etsockopt */
|
||||
void *sopt_val; /* fourth arg of [gs]etsockopt */
|
||||
size_t sopt_valsize; /* (almost) fifth arg of [gs]etsockopt */
|
||||
struct cap_rights *sopt_rights; /* Capsicum rights attached to the fd */
|
||||
struct thread *sopt_td; /* calling thread or null if kernel */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue