MAC: improve handling of listening sockets

so_peerlabel can only be used when the socket is not listening.

Reviewed by:		markj
MFC after:		1 week
Sponsored by:		Netflix, Inc.
Differential Revision:	https://reviews.freebsd.org/D46755
This commit is contained in:
Michael Tuexen 2024-09-26 08:06:24 +02:00
parent 3f2792166a
commit 2fb778fab8
3 changed files with 19 additions and 6 deletions

View File

@ -153,6 +153,7 @@
#include <net/vnet.h>
#include <security/mac/mac_framework.h>
#include <security/mac/mac_internal.h>
#include <vm/uma.h>
@ -1485,6 +1486,10 @@ solisten_proto(struct socket *so, int backlog)
sbrcv_timeo = so->so_rcv.sb_timeo;
sbsnd_timeo = so->so_snd.sb_timeo;
#ifdef MAC
mac_socketpeer_label_free(so->so_peerlabel);
#endif
if (!(so->so_proto->pr_flags & PR_SOCKBUF)) {
sbdestroy(so, SO_SND);
sbdestroy(so, SO_RCV);

View File

@ -242,6 +242,7 @@ struct label *mac_pipe_label_alloc(void);
void mac_pipe_label_free(struct label *label);
struct label *mac_socket_label_alloc(int flag);
void mac_socket_label_free(struct label *label);
void mac_socketpeer_label_free(struct label *label);
struct label *mac_vnode_label_alloc(void);
void mac_vnode_label_free(struct label *label);

View File

@ -170,7 +170,7 @@ mac_socket_label_free(struct label *label)
mac_labelzone_free(label);
}
static void
void
mac_socketpeer_label_free(struct label *label)
{
@ -185,8 +185,10 @@ mac_socket_destroy(struct socket *so)
if (so->so_label != NULL) {
mac_socket_label_free(so->so_label);
so->so_label = NULL;
mac_socketpeer_label_free(so->so_peerlabel);
so->so_peerlabel = NULL;
if (!SOLISTENING(so)) {
mac_socketpeer_label_free(so->so_peerlabel);
so->so_peerlabel = NULL;
}
}
}
@ -618,10 +620,15 @@ mac_getsockopt_peerlabel(struct ucred *cred, struct socket *so,
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
intlabel = mac_socket_label_alloc(M_WAITOK);
SOCK_LOCK(so);
mac_socket_copy_label(so->so_peerlabel, intlabel);
if (SOLISTENING(so))
error = EINVAL;
else
mac_socket_copy_label(so->so_peerlabel, intlabel);
SOCK_UNLOCK(so);
error = mac_socketpeer_externalize_label(intlabel, elements, buffer,
mac->m_buflen);
if (error == 0) {
error = mac_socketpeer_externalize_label(intlabel, elements, buffer,
mac->m_buflen);
}
mac_socket_label_free(intlabel);
if (error == 0)
error = copyout(buffer, mac->m_string, strlen(buffer)+1);