Author: dab Date: Mon Nov 18 13:31:16 2019 New Revision: 354808 URL: https://svnweb.freebsd.org/changeset/base/354808
Log: Jail and capability mode for shm_rename; add audit support for shm_rename Co-mingling two things here: * Addressing some feedback from Konstantin and Kyle re: jail, capability mode, and a few other things * Adding audit support as promised. The audit support change includes a partial refresh of OpenBSM from upstream, where the change to add shm_rename has already been accepted. Matthew doesn't plan to work on refreshing anything else to support audit for those new event types. Submitted by: Matthew Bryan <matthew.br...@isilon.com> Reviewed by: kib Relnotes: Yes Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D22083 Modified: head/contrib/openbsm/etc/audit_event head/contrib/openbsm/sys/bsm/audit_kevents.h head/sys/bsm/audit_kevents.h head/sys/compat/freebsd32/freebsd32_sysent.c head/sys/compat/freebsd32/syscalls.master head/sys/kern/init_sysent.c head/sys/kern/syscalls.master head/sys/kern/uipc_shm.c head/sys/security/audit/audit_bsm.c head/sys/sys/mman.h head/sys/sys/sysproto.h head/tests/sys/posixshm/posixshm_test.c Modified: head/contrib/openbsm/etc/audit_event ============================================================================== --- head/contrib/openbsm/etc/audit_event Mon Nov 18 10:46:55 2019 (r354807) +++ head/contrib/openbsm/etc/audit_event Mon Nov 18 13:31:16 2019 (r354808) @@ -601,6 +601,19 @@ 43238:AUE_SETLOGINCLASS:setloginclass(2):pc 43239:AUE_POSIX_FADVISE:posix_fadvise(2):no 43240:AUE_SCTP_GENERIC_SENDMSG_IOV:sctp_generic_sendmsg_iov(2):nt +43241:AUE_ABORT2:abort(2):pc +43242:AUE_SEMTIMEDWAIT:sem_timedwait(3):ip +43243:AUE_SEMDESTROY:sem_destroy(3):ip +43244:AUE_SEMGETVALUE:sem_getvalue(3):ip +43245:AUE_SEMINIT:sem_init(3):ip +43246:AUE_SEMPOST:sem_post(3):ip +43247:AUE_SEMTRYWAIT:sem_trywait(3):ip +43258:AUE_SEMWAIT:sem_wait(3):ip +43259:AUE_FGETUUID:fgetuuid(2):ip +43260:AUE_GETUUID:getuuid(2):ip +43261:AUE_LGETUUID:lgetuuid(2):ip +43262:AUE_EXECVEAT:execveat(2):pc,ex +43263:AUE_SHMRENAME:shm_rename(2):ip # # Solaris userspace events. # Modified: head/contrib/openbsm/sys/bsm/audit_kevents.h ============================================================================== --- head/contrib/openbsm/sys/bsm/audit_kevents.h Mon Nov 18 10:46:55 2019 (r354807) +++ head/contrib/openbsm/sys/bsm/audit_kevents.h Mon Nov 18 13:31:16 2019 (r354808) @@ -640,6 +640,19 @@ #define AUE_SETLOGINCLASS 43238 /* FreeBSD-specific. */ #define AUE_POSIX_FADVISE 43239 /* FreeBSD-specific. */ #define AUE_SCTP_GENERIC_SENDMSG_IOV 43240 /* FreeBSD-specific. */ +#define AUE_ABORT2 43241 /* FreeBSD-specific. */ +#define AUE_SEMTIMEDWAIT 43242 /* FreeBSD-specific. */ +#define AUE_SEMDESTROY 43243 /* FreeBSD-specific. */ +#define AUE_SEMGETVALUE 43244 /* FreeBSD-specific. */ +#define AUE_SEMINIT 43245 /* FreeBSD-specific. */ +#define AUE_SEMPOST 43246 /* FreeBSD-specific. */ +#define AUE_SEMTRYWAIT 43247 /* FreeBSD-specific. */ +#define AUE_SEMWAIT 43258 /* FreeBSD-specific. */ +#define AUE_FGETUUID 43259 /* CADETS. */ +#define AUE_GETUUID 43260 /* CADETS. */ +#define AUE_LGETUUID 43261 /* CADETS. */ +#define AUE_EXECVEAT 43262 /* FreeBSD/Linux. */ +#define AUE_SHMRENAME 43263 /* FreeBSD-specific. */ /* * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the @@ -794,12 +807,6 @@ #define AUE_REMOVEXATTR AUE_NULL #define AUE_SBRK AUE_NULL #define AUE_SELECT AUE_NULL -#define AUE_SEMDESTROY AUE_NULL -#define AUE_SEMGETVALUE AUE_NULL -#define AUE_SEMINIT AUE_NULL -#define AUE_SEMPOST AUE_NULL -#define AUE_SEMTRYWAIT AUE_NULL -#define AUE_SEMWAIT AUE_NULL #define AUE_SEMWAITSIGNAL AUE_NULL #define AUE_SETITIMER AUE_NULL #define AUE_SETSGROUPS AUE_NULL Modified: head/sys/bsm/audit_kevents.h ============================================================================== --- head/sys/bsm/audit_kevents.h Mon Nov 18 10:46:55 2019 (r354807) +++ head/sys/bsm/audit_kevents.h Mon Nov 18 13:31:16 2019 (r354808) @@ -644,6 +644,19 @@ #define AUE_SETLOGINCLASS 43238 /* FreeBSD-specific. */ #define AUE_POSIX_FADVISE 43239 /* FreeBSD-specific. */ #define AUE_SCTP_GENERIC_SENDMSG_IOV 43240 /* FreeBSD-specific. */ +#define AUE_ABORT2 43241 /* FreeBSD-specific. */ +#define AUE_SEMTIMEDWAIT 43242 /* FreeBSD-specific. */ +#define AUE_SEMDESTROY 43243 /* FreeBSD-specific. */ +#define AUE_SEMGETVALUE 43244 /* FreeBSD-specific. */ +#define AUE_SEMINIT 43245 /* FreeBSD-specific. */ +#define AUE_SEMPOST 43246 /* FreeBSD-specific. */ +#define AUE_SEMTRYWAIT 43247 /* FreeBSD-specific. */ +#define AUE_SEMWAIT 43258 /* FreeBSD-specific. */ +#define AUE_FGETUUID 43259 /* CADETS. */ +#define AUE_GETUUID 43260 /* CADETS. */ +#define AUE_LGETUUID 43261 /* CADETS. */ +#define AUE_EXECVEAT 43262 /* FreeBSD/Linux. */ +#define AUE_SHMRENAME 43263 /* FreeBSD-specific. */ /* * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the @@ -798,12 +811,6 @@ #define AUE_REMOVEXATTR AUE_NULL #define AUE_SBRK AUE_NULL #define AUE_SELECT AUE_NULL -#define AUE_SEMDESTROY AUE_NULL -#define AUE_SEMGETVALUE AUE_NULL -#define AUE_SEMINIT AUE_NULL -#define AUE_SEMPOST AUE_NULL -#define AUE_SEMTRYWAIT AUE_NULL -#define AUE_SEMWAIT AUE_NULL #define AUE_SEMWAITSIGNAL AUE_NULL #define AUE_SETITIMER AUE_NULL #define AUE_SETSGROUPS AUE_NULL Modified: head/sys/compat/freebsd32/freebsd32_sysent.c ============================================================================== --- head/sys/compat/freebsd32/freebsd32_sysent.c Mon Nov 18 10:46:55 2019 (r354807) +++ head/sys/compat/freebsd32/freebsd32_sysent.c Mon Nov 18 13:31:16 2019 (r354808) @@ -661,5 +661,5 @@ struct sysent freebsd32_sysent[] = { { AS(copy_file_range_args), (sy_call_t *)sys_copy_file_range, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 569 = copy_file_range */ { AS(freebsd32___sysctlbyname_args), (sy_call_t *)freebsd32___sysctlbyname, AUE_SYSCTL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 570 = freebsd32___sysctlbyname */ { AS(shm_open2_args), (sy_call_t *)sys_shm_open2, AUE_SHMOPEN, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 571 = shm_open2 */ - { AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 572 = shm_rename */ + { AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_SHMRENAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 572 = shm_rename */ }; Modified: head/sys/compat/freebsd32/syscalls.master ============================================================================== --- head/sys/compat/freebsd32/syscalls.master Mon Nov 18 10:46:55 2019 (r354807) +++ head/sys/compat/freebsd32/syscalls.master Mon Nov 18 13:31:16 2019 (r354808) @@ -1157,7 +1157,7 @@ 571 AUE_SHMOPEN NOPROTO { int shm_open2( \ const char *path, int flags, mode_t mode, \ int shmflags, const char *name); } -572 AUE_NULL NOPROTO { int shm_rename(const char *path_from, \ +572 AUE_SHMRENAME NOPROTO { int shm_rename(const char *path_from, \ const char *path_to, int flags); } ; vim: syntax=off Modified: head/sys/kern/init_sysent.c ============================================================================== --- head/sys/kern/init_sysent.c Mon Nov 18 10:46:55 2019 (r354807) +++ head/sys/kern/init_sysent.c Mon Nov 18 13:31:16 2019 (r354808) @@ -627,5 +627,5 @@ struct sysent sysent[] = { { AS(copy_file_range_args), (sy_call_t *)sys_copy_file_range, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 569 = copy_file_range */ { AS(__sysctlbyname_args), (sy_call_t *)sys___sysctlbyname, AUE_SYSCTL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 570 = __sysctlbyname */ { AS(shm_open2_args), (sy_call_t *)sys_shm_open2, AUE_SHMOPEN, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 571 = shm_open2 */ - { AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 572 = shm_rename */ + { AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_SHMRENAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 572 = shm_rename */ }; Modified: head/sys/kern/syscalls.master ============================================================================== --- head/sys/kern/syscalls.master Mon Nov 18 10:46:55 2019 (r354807) +++ head/sys/kern/syscalls.master Mon Nov 18 13:31:16 2019 (r354808) @@ -3205,7 +3205,7 @@ _In_z_ const char *name ); } -572 AUE_NULL STD { +572 AUE_SHMRENAME STD { int shm_rename( _In_z_ const char *path_from, _In_z_ const char *path_to, Modified: head/sys/kern/uipc_shm.c ============================================================================== --- head/sys/kern/uipc_shm.c Mon Nov 18 10:46:55 2019 (r354807) +++ head/sys/kern/uipc_shm.c Mon Nov 18 13:31:16 2019 (r354808) @@ -122,6 +122,8 @@ static struct shmfd *shm_lookup(char *path, Fnv32_t fn static int shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred); static int shm_dotruncate_locked(struct shmfd *shmfd, off_t length, void *rl_cookie); +static int shm_copyin_path(struct thread *td, const char *userpath_in, + char **path_out); static fo_rdwr_t shm_read; static fo_rdwr_t shm_write; @@ -422,6 +424,44 @@ shm_close(struct file *fp, struct thread *td) } static int +shm_copyin_path(struct thread *td, const char *userpath_in, char **path_out) { + int error; + char *path; + const char *pr_path; + size_t pr_pathlen; + + path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK); + pr_path = td->td_ucred->cr_prison->pr_path; + + /* Construct a full pathname for jailed callers. */ + pr_pathlen = strcmp(pr_path, "/") == + 0 ? 0 : strlcpy(path, pr_path, MAXPATHLEN); + error = copyinstr(userpath_in, path + pr_pathlen, + MAXPATHLEN - pr_pathlen, NULL); + if (error != 0) + goto out; + +#ifdef KTRACE + if (KTRPOINT(curthread, KTR_NAMEI)) + ktrnamei(path); +#endif + + /* Require paths to start with a '/' character. */ + if (path[pr_pathlen] != '/') { + error = EINVAL; + goto out; + } + + *path_out = path; + +out: + if (error != 0) + free(path, M_SHMFD); + + return (error); +} + +static int shm_dotruncate_locked(struct shmfd *shmfd, off_t length, void *rl_cookie) { vm_object_t object; @@ -707,9 +747,7 @@ kern_shm_open(struct thread *td, const char *userpath, struct shmfd *shmfd; struct file *fp; char *path; - const char *pr_path; void *rl_cookie; - size_t pr_pathlen; Fnv32_t fnv; mode_t cmode; int fd, error; @@ -767,25 +805,10 @@ kern_shm_open(struct thread *td, const char *userpath, shmfd = shm_alloc(td->td_ucred, cmode); shmfd->shm_seals = initial_seals; } else { - path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK); - pr_path = td->td_ucred->cr_prison->pr_path; - - /* Construct a full pathname for jailed callers. */ - pr_pathlen = strcmp(pr_path, "/") == 0 ? 0 - : strlcpy(path, pr_path, MAXPATHLEN); - error = copyinstr(userpath, path + pr_pathlen, - MAXPATHLEN - pr_pathlen, NULL); -#ifdef KTRACE - if (error == 0 && KTRPOINT(curthread, KTR_NAMEI)) - ktrnamei(path); -#endif - /* Require paths to start with a '/' character. */ - if (error == 0 && path[pr_pathlen] != '/') - error = EINVAL; - if (error) { + error = shm_copyin_path(td, userpath, &path); + if (error != 0) { fdclose(td, fp, fd); fdrop(fp, td); - free(path, M_SHMFD); return (error); } @@ -918,25 +941,13 @@ int sys_shm_unlink(struct thread *td, struct shm_unlink_args *uap) { char *path; - const char *pr_path; - size_t pr_pathlen; Fnv32_t fnv; int error; - path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); - pr_path = td->td_ucred->cr_prison->pr_path; - pr_pathlen = strcmp(pr_path, "/") == 0 ? 0 - : strlcpy(path, pr_path, MAXPATHLEN); - error = copyinstr(uap->path, path + pr_pathlen, MAXPATHLEN - pr_pathlen, - NULL); - if (error) { - free(path, M_TEMP); + error = shm_copyin_path(td, uap->path, &path); + if (error != 0) return (error); - } -#ifdef KTRACE - if (KTRPOINT(curthread, KTR_NAMEI)) - ktrnamei(path); -#endif + AUDIT_ARG_UPATH1_CANON(path); fnv = fnv_32_str(path, FNV1_32_INIT); sx_xlock(&shm_dict_lock); @@ -958,6 +969,7 @@ sys_shm_rename(struct thread *td, struct shm_rename_ar int flags; flags = uap->flags; + AUDIT_ARG_FFLAGS(flags); /* * Make sure the user passed only valid flags. @@ -981,22 +993,25 @@ sys_shm_rename(struct thread *td, struct shm_rename_ar goto out; } - /* - * Malloc zone M_SHMFD, since this path may end up freed later from - * M_SHMFD if we end up doing an insert. - */ - path_from = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK); - error = copyinstr(uap->path_from, path_from, MAXPATHLEN, NULL); - if (error) + /* Renaming to or from anonymous makes no sense */ + if (uap->path_from == SHM_ANON || uap->path_to == SHM_ANON) { + error = EINVAL; goto out; + } - path_to = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK); - error = copyinstr(uap->path_to, path_to, MAXPATHLEN, NULL); - if (error) + error = shm_copyin_path(td, uap->path_from, &path_from); + if (error != 0) goto out; + error = shm_copyin_path(td, uap->path_to, &path_to); + if (error != 0) + goto out; + + AUDIT_ARG_UPATH1_CANON(path_from); + AUDIT_ARG_UPATH2_CANON(path_to); + /* Rename with from/to equal is a no-op */ - if (strncmp(path_from, path_to, MAXPATHLEN) == 0) + if (strcmp(path_from, path_to) == 0) goto out; fnv_from = fnv_32_str(path_from, FNV1_32_INIT); @@ -1006,16 +1021,14 @@ sys_shm_rename(struct thread *td, struct shm_rename_ar fd_from = shm_lookup(path_from, fnv_from); if (fd_from == NULL) { - sx_xunlock(&shm_dict_lock); error = ENOENT; - goto out; + goto out_locked; } fd_to = shm_lookup(path_to, fnv_to); if ((flags & SHM_RENAME_NOREPLACE) != 0 && fd_to != NULL) { - sx_xunlock(&shm_dict_lock); error = EEXIST; - goto out; + goto out_locked; } /* @@ -1031,10 +1044,9 @@ sys_shm_rename(struct thread *td, struct shm_rename_ar */ KASSERT(error != ENOENT, ("Our shm disappeared during shm_rename: %s", path_from)); - if (error) { + if (error != 0) { shm_drop(fd_from); - sx_xunlock(&shm_dict_lock); - goto out; + goto out_locked; } /* @@ -1057,15 +1069,16 @@ sys_shm_rename(struct thread *td, struct shm_rename_ar * operation. */ error = shm_remove(path_to, fnv_to, td->td_ucred); - if (error && error != ENOENT) { + if (error != 0 && error != ENOENT) { shm_insert(path_from, fnv_from, fd_from); shm_drop(fd_from); /* Don't free path_from now, since the hash references it */ path_from = NULL; - sx_xunlock(&shm_dict_lock); - goto out; + goto out_locked; } + error = 0; + shm_insert(path_to, fnv_to, fd_from); /* Don't free path_to now, since the hash references it */ @@ -1073,30 +1086,24 @@ sys_shm_rename(struct thread *td, struct shm_rename_ar /* We kept a ref when we removed, and incremented again in insert */ shm_drop(fd_from); -#ifdef DEBUG KASSERT(fd_from->shm_refs > 0, ("Expected >0 refs; got: %d\n", fd_from->shm_refs)); -#endif if ((flags & SHM_RENAME_EXCHANGE) != 0 && fd_to != NULL) { shm_insert(path_from, fnv_from, fd_to); path_from = NULL; shm_drop(fd_to); -#ifdef DEBUG KASSERT(fd_to->shm_refs > 0, ("Expected >0 refs; got: %d\n", fd_to->shm_refs)); -#endif } - error = 0; +out_locked: sx_xunlock(&shm_dict_lock); out: - if (path_from != NULL) - free(path_from, M_SHMFD); - if (path_to != NULL) - free(path_to, M_SHMFD); - return(error); + free(path_from, M_SHMFD); + free(path_to, M_SHMFD); + return (error); } int Modified: head/sys/security/audit/audit_bsm.c ============================================================================== --- head/sys/security/audit/audit_bsm.c Mon Nov 18 10:46:55 2019 (r354807) +++ head/sys/security/audit/audit_bsm.c Mon Nov 18 13:31:16 2019 (r354808) @@ -1565,6 +1565,16 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_rec } break; + /* shm_rename is a non-Posix extension to the Posix shm implementation */ + case AUE_SHMRENAME: + UPATH1_TOKENS; + UPATH2_TOKENS; + if (ARG_IS_VALID(kar, ARG_FFLAGS)) { + tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); + kau_write(rec, tok); + } + break; + /* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE * and AUE_SEMUNLINK are Posix IPC */ case AUE_SHMOPEN: Modified: head/sys/sys/mman.h ============================================================================== --- head/sys/sys/mman.h Mon Nov 18 10:46:55 2019 (r354807) +++ head/sys/sys/mman.h Mon Nov 18 13:31:16 2019 (r354808) @@ -118,6 +118,15 @@ #define MAP_ALIGNMENT_SHIFT 24 #define MAP_ALIGNMENT_MASK MAP_ALIGNED(0xff) #define MAP_ALIGNED_SUPER MAP_ALIGNED(1) /* align on a superpage */ + +/* + * Flags provided to shm_rename + */ +/* Don't overwrite dest, if it exists */ +#define SHM_RENAME_NOREPLACE (1 << 0) +/* Atomically swap src and dest */ +#define SHM_RENAME_EXCHANGE (1 << 1) + #endif /* __BSD_VISIBLE */ #if __POSIX_VISIBLE >= 199309 @@ -134,14 +143,6 @@ #define MAP_FAILED ((void *)-1) /* - * Flags provided to shm_rename - */ -/* Don't overwrite dest, if it exists */ -#define SHM_RENAME_NOREPLACE (1 << 0) -/* Atomically swap src and dest */ -#define SHM_RENAME_EXCHANGE (1 << 1) - -/* * msync() flags */ #define MS_SYNC 0x0000 /* msync synchronously */ @@ -321,11 +322,11 @@ int posix_madvise(void *, size_t, int); int mlockall(int); int munlockall(void); int shm_open(const char *, int, mode_t); -int shm_rename(const char *, const char *, int); int shm_unlink(const char *); #endif #if __BSD_VISIBLE int memfd_create(const char *, unsigned int); +int shm_rename(const char *, const char *, int); #endif __END_DECLS Modified: head/sys/sys/sysproto.h ============================================================================== --- head/sys/sys/sysproto.h Mon Nov 18 10:46:55 2019 (r354807) +++ head/sys/sys/sysproto.h Mon Nov 18 13:31:16 2019 (r354808) @@ -3129,7 +3129,7 @@ int freebsd12_shm_open(struct thread *, struct freebsd #define SYS_AUE_copy_file_range AUE_NULL #define SYS_AUE___sysctlbyname AUE_SYSCTL #define SYS_AUE_shm_open2 AUE_SHMOPEN -#define SYS_AUE_shm_rename AUE_NULL +#define SYS_AUE_shm_rename AUE_SHMRENAME #undef PAD_ #undef PADL_ Modified: head/tests/sys/posixshm/posixshm_test.c ============================================================================== --- head/tests/sys/posixshm/posixshm_test.c Mon Nov 18 10:46:55 2019 (r354807) +++ head/tests/sys/posixshm/posixshm_test.c Mon Nov 18 13:31:16 2019 (r354808) @@ -53,7 +53,7 @@ static unsigned int test_path_idx = 0; static void gen_a_test_path(char *path) { - snprintf(path, TEST_PATH_LEN, "%s/tmp.XXXXXX%d", + snprintf(path, TEST_PATH_LEN, "/%s/tmp.XXXXXX%d", getenv("TMPDIR") == NULL ? "/tmp" : getenv("TMPDIR"), test_path_idx); @@ -232,12 +232,14 @@ ATF_TC_BODY(rename_from_nonexisting, tc) int rc; gen_test_path(); + gen_test_path2(); rc = shm_rename(test_path, test_path2, 0); if (rc != -1) atf_tc_fail("shm_rename of nonexisting shm succeeded unexpectedly"); if (errno != ENOENT) - atf_tc_fail("Expected ENOENT to rename of nonexistent shm"); + atf_tc_fail("Expected ENOENT to rename of nonexistent shm; got %d", + errno); } ATF_TC_WITHOUT_HEAD(rename_to_anon); _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"