diff --git a/sys/security/mac/mac_syscalls.h b/sys/security/mac/mac_syscalls.h --- a/sys/security/mac/mac_syscalls.h +++ b/sys/security/mac/mac_syscalls.h @@ -23,6 +23,16 @@ char **const u_string); void free_copied_label(const struct mac *const mac); +#ifdef COMPAT_FREEBSD32 +struct freebsd32_mac { + uint32_t m_buflen; /* size_t */ + uint32_t m_string; /* char * */ +}; + +int mac_label_copyin32(const struct freebsd32_mac *const u_mac, + struct mac *const mac, char **const u_string); +#endif /* COMPAT_FREEBSD32 */ + int mac_set_proc_prepare(struct thread *const td, const struct mac *const mac, void **const mac_set_proc_data); int mac_set_proc_core(struct thread *const td, struct ucred *const newcred, diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c --- a/sys/security/mac/mac_syscalls.c +++ b/sys/security/mac/mac_syscalls.c @@ -46,6 +46,7 @@ #include "opt_mac.h" #include +#include #include #include #include @@ -86,16 +87,27 @@ * after use by calling free_copied_label() (which see). On success, 'u_string' * if not NULL is filled with the userspace address for 'u_mac->m_string'. */ -int -mac_label_copyin(const struct mac *const u_mac, struct mac *const mac, - char **const u_string) +static int +mac_label_copyin_int(const void *const u_mac, struct mac *const mac, + char **const u_string, bool is_32bit) { char *buffer; int error; - error = copyin(u_mac, mac, sizeof(*mac)); - if (error != 0) - return (error); + if (is_32bit) { + struct freebsd32_mac mac32; + + error = copyin(u_mac, &mac32, sizeof(mac32)); + if (error != 0) + return (error); + + CP(mac32, *mac, m_buflen); + PTRIN_CP(mac32, *mac, m_string); + } else { + error = copyin(u_mac, mac, sizeof(*mac)); + if (error != 0) + return (error); + } error = mac_check_structmac_consistent(mac); if (error != 0) @@ -116,12 +128,26 @@ return (0); } +int +mac_label_copyin(const struct mac *const u_mac, struct mac *const mac, + char **const u_string) +{ + return (mac_label_copyin_int(u_mac, mac, u_string, false)); +} + void free_copied_label(const struct mac *const mac) { free(mac->m_string, M_MACTEMP); } +int +mac_label_copyin32(const struct freebsd32_mac *const u_mac, + struct mac *const mac, char **const u_string) +{ + return (mac_label_copyin_int(u_mac, mac, u_string, true)); +} + int sys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) {