diff options
author | Michael Tuexen <tuexen@FreeBSD.org> | 2024-09-26 06:06:24 +0000 |
---|---|---|
committer | Michael Tuexen <tuexen@FreeBSD.org> | 2024-09-26 06:06:24 +0000 |
commit | 2fb778fab893b4a8a86ecfa20acf2e23bb2cdae8 (patch) | |
tree | 3fba7948e7c2eb1fff37cc0a4aea3a0055de6e94 | |
parent | 3f2792166aeed4baf07d351bcb12a9d196c443eb (diff) | |
download | src-2fb778fab893.tar.gz src-2fb778fab893.zip |
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
-rw-r--r-- | sys/kern/uipc_socket.c | 5 | ||||
-rw-r--r-- | sys/security/mac/mac_internal.h | 1 | ||||
-rw-r--r-- | sys/security/mac/mac_socket.c | 19 |
3 files changed, 19 insertions, 6 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index e83422e3a29f..189e8ca5b498 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -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); diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h index aa407598600a..89f74a65c803 100644 --- a/sys/security/mac/mac_internal.h +++ b/sys/security/mac/mac_internal.h @@ -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); diff --git a/sys/security/mac/mac_socket.c b/sys/security/mac/mac_socket.c index e9f94404734a..b03f98bbfdb5 100644 --- a/sys/security/mac/mac_socket.c +++ b/sys/security/mac/mac_socket.c @@ -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); |