From owner-svn-src-stable@freebsd.org Fri Jan 25 11:46:09 2019 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5249214B241C; Fri, 25 Jan 2019 11:46:09 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id E84307759B; Fri, 25 Jan 2019 11:46:08 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id DC09779F7; Fri, 25 Jan 2019 11:46:08 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x0PBk8ON026933; Fri, 25 Jan 2019 11:46:08 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x0PBk7wl026926; Fri, 25 Jan 2019 11:46:07 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201901251146.x0PBk7wl026926@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Fri, 25 Jan 2019 11:46:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r343426 - in stable/11: contrib/netbsd-tests/kernel lib/libc/sys sys/kern sys/sys sys/vm X-SVN-Group: stable-11 X-SVN-Commit-Author: kib X-SVN-Commit-Paths: in stable/11: contrib/netbsd-tests/kernel lib/libc/sys sys/kern sys/sys sys/vm X-SVN-Commit-Revision: 343426 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: E84307759B X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.95 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.998,0]; NEURAL_HAM_SHORT(-0.96)[-0.956,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Jan 2019 11:46:09 -0000 Author: kib Date: Fri Jan 25 11:46:07 2019 New Revision: 343426 URL: https://svnweb.freebsd.org/changeset/base/343426 Log: MFC r343082: Implement shmat(2) flag SHM_REMAP. Modified: stable/11/contrib/netbsd-tests/kernel/t_sysv.c stable/11/lib/libc/sys/shmat.2 stable/11/sys/kern/sysv_shm.c stable/11/sys/sys/shm.h stable/11/sys/vm/vm_map.c stable/11/sys/vm/vm_map.h Directory Properties: stable/11/ (props changed) Modified: stable/11/contrib/netbsd-tests/kernel/t_sysv.c ============================================================================== --- stable/11/contrib/netbsd-tests/kernel/t_sysv.c Fri Jan 25 11:26:05 2019 (r343425) +++ stable/11/contrib/netbsd-tests/kernel/t_sysv.c Fri Jan 25 11:46:07 2019 (r343426) @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -774,19 +775,27 @@ ATF_TC_BODY(shm, tc) atf_tc_fail("sender: received unexpected signal"); } -ATF_TC_CLEANUP(shm, tc) +static void +shmid_cleanup(const char *name) { - int sender_shmid; + int shmid; /* * Remove the shared memory area if it exists. */ - sender_shmid = read_int("sender_shmid"); - if (sender_shmid != -1) - if (shmctl(sender_shmid, IPC_RMID, NULL) == -1) + shmid = read_int(name); + if (shmid != -1) { + if (shmctl(shmid, IPC_RMID, NULL) == -1) err(1, "shmctl IPC_RMID"); + } } +ATF_TC_CLEANUP(shm, tc) +{ + + shmid_cleanup("sender_shmid"); +} + void print_shmid_ds(struct shmid_ds *sp, mode_t mode) { @@ -839,12 +848,53 @@ sharer(void) exit(0); } +#ifdef SHM_REMAP +ATF_TC_WITH_CLEANUP(shm_remap); +ATF_TC_HEAD(shm_remap, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks SHM_REMAP"); +} + +ATF_TC_BODY(shm_remap, tc) +{ + char *shm_buf; + int shmid_remap; + + pgsize = sysconf(_SC_PAGESIZE); + + shmkey = get_ftok(4160); + ATF_REQUIRE_MSG(shmkey != (key_t)-1, "get_ftok failed"); + + ATF_REQUIRE_MSG((shmid_remap = shmget(shmkey, pgsize, + IPC_CREAT | 0640)) != -1, "shmget: %d", errno); + write_int("shmid_remap", shmid_remap); + + ATF_REQUIRE_MSG((shm_buf = mmap(NULL, pgsize, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0)) != MAP_FAILED, "mmap: %d", errno); + + ATF_REQUIRE_MSG(shmat(shmid_remap, shm_buf, 0) == (void *)-1, + "shmat without MAP_REMAP succeeded"); + ATF_REQUIRE_MSG(shmat(shmid_remap, shm_buf, SHM_REMAP) == shm_buf, + "shmat(SHM_REMAP): %d", errno); +} + +ATF_TC_CLEANUP(shm_remap, tc) +{ + + shmid_cleanup("shmid_remap"); +} +#endif /* SHM_REMAP */ + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, msg); ATF_TP_ADD_TC(tp, sem); ATF_TP_ADD_TC(tp, shm); +#ifdef SHM_REMAP + ATF_TP_ADD_TC(tp, shm_remap); +#endif return atf_no_error(); } Modified: stable/11/lib/libc/sys/shmat.2 ============================================================================== --- stable/11/lib/libc/sys/shmat.2 Fri Jan 25 11:26:05 2019 (r343425) +++ stable/11/lib/libc/sys/shmat.2 Fri Jan 25 11:46:07 2019 (r343426) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 25, 2018 +.Dd January 14, 2019 .Dt SHMAT 2 .Os .Sh NAME @@ -64,17 +64,38 @@ kernel. .It If .Fa addr -is nonzero and SHM_RND is not specified in +is nonzero and +.Va SHM_RND +is not specified in .Fa flag , the segment is attached the specified address. .It If .Fa addr -is specified and SHM_RND is specified, +is specified and +.Va SHM_RND +is specified, .Fa addr is rounded down to the nearest multiple of SHMLBA. .El .Pp +If the +.Va SHM_REMAP +flag is specified and the passed +.Fa addr +is not +.Dv NULL , +any existing mappings in the virtual addresses range are +cleared before the segment is attached. +If the flag is not specified, +.Fa addr +is not +.Dv NULL , +and the virtual address range contains +some pre-existing mappings, the +.Fn shmat +call fails. +.Pp The .Fn shmdt system call @@ -104,6 +125,14 @@ The .Fa addr argument was not an acceptable address. +.It Bq Er ENOMEM +The specified +.Fa addr +cannot be used for mapping, for instance due to the amount of available +space being smaller than the segment size, +or because pre-existing mappings are in the range and no +.Va SHM_REMAP +flag was provided. .It Bq Er EMFILE Failed to attach the shared memory segment because the per-process .Va kern.ipc.shmseg Modified: stable/11/sys/kern/sysv_shm.c ============================================================================== --- stable/11/sys/kern/sysv_shm.c Fri Jan 25 11:26:05 2019 (r343425) +++ stable/11/sys/kern/sysv_shm.c Fri Jan 25 11:46:07 2019 (r343426) @@ -379,7 +379,7 @@ kern_shmat_locked(struct thread *td, int shmid, const vm_offset_t attach_va; vm_prot_t prot; vm_size_t size; - int error, i, rv; + int cow, error, find_space, i, rv; SYSVSHM_ASSERT_LOCKED(); rpr = shm_find_prison(td->td_ucred); @@ -415,6 +415,7 @@ kern_shmat_locked(struct thread *td, int shmid, const return (EMFILE); size = round_page(shmseg->u.shm_segsz); prot = VM_PROT_READ; + cow = MAP_INHERIT_SHARE | MAP_PREFAULT_PARTIAL; if ((shmflg & SHM_RDONLY) == 0) prot |= VM_PROT_WRITE; if (shmaddr != NULL) { @@ -424,6 +425,9 @@ kern_shmat_locked(struct thread *td, int shmid, const attach_va = (vm_offset_t)shmaddr; else return (EINVAL); + if ((shmflg & SHM_REMAP) != 0) + cow |= MAP_REMAP; + find_space = VMFS_NO_SPACE; } else { /* * This is just a hint to vm_map_find() about where to @@ -431,12 +435,12 @@ kern_shmat_locked(struct thread *td, int shmid, const */ attach_va = round_page((vm_offset_t)p->p_vmspace->vm_daddr + lim_max(td, RLIMIT_DATA)); + find_space = VMFS_OPTIMAL_SPACE; } vm_object_reference(shmseg->object); rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->object, 0, &attach_va, - size, 0, shmaddr != NULL ? VMFS_NO_SPACE : VMFS_OPTIMAL_SPACE, - prot, prot, MAP_INHERIT_SHARE | MAP_PREFAULT_PARTIAL); + size, 0, find_space, prot, prot, cow); if (rv != KERN_SUCCESS) { vm_object_deallocate(shmseg->object); return (ENOMEM); Modified: stable/11/sys/sys/shm.h ============================================================================== --- stable/11/sys/sys/shm.h Fri Jan 25 11:26:05 2019 (r343425) +++ stable/11/sys/sys/shm.h Fri Jan 25 11:46:07 2019 (r343426) @@ -47,6 +47,7 @@ #define SHM_RDONLY 010000 /* Attach read-only (else read-write) */ #define SHM_RND 020000 /* Round attach address to SHMLBA */ +#define SHM_REMAP 030000 /* Unmap before mapping */ #define SHMLBA PAGE_SIZE /* Segment low boundary address multiple */ /* "official" access mode definitions; somewhat braindead since you have Modified: stable/11/sys/vm/vm_map.c ============================================================================== --- stable/11/sys/vm/vm_map.c Fri Jan 25 11:26:05 2019 (r343425) +++ stable/11/sys/vm/vm_map.c Fri Jan 25 11:46:07 2019 (r343426) @@ -1492,6 +1492,8 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffs KASSERT((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) == 0 || object == NULL, ("vm_map_find: non-NULL backing object for stack")); + MPASS((cow & MAP_REMAP) == 0 || (find_space == VMFS_NO_SPACE && + (cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) == 0)); if (find_space == VMFS_OPTIMAL_SPACE && (object == NULL || (object->flags & OBJ_COLORED) == 0)) find_space = VMFS_ANY_SPACE; @@ -1532,6 +1534,14 @@ again: } start = *addr; + } else if ((cow & MAP_REMAP) != 0) { + if (start < vm_map_min(map) || + start + length > vm_map_max(map) || + start + length <= length) { + result = KERN_INVALID_ADDRESS; + break; + } + vm_map_delete(map, start, start + length); } if ((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) != 0) { result = vm_map_stack_locked(map, start, length, Modified: stable/11/sys/vm/vm_map.h ============================================================================== --- stable/11/sys/vm/vm_map.h Fri Jan 25 11:26:05 2019 (r343425) +++ stable/11/sys/vm/vm_map.h Fri Jan 25 11:46:07 2019 (r343426) @@ -342,6 +342,7 @@ long vmspace_resident_count(struct vmspace *vmspace); #define MAP_DISABLE_COREDUMP 0x0100 #define MAP_PREFAULT_MADVISE 0x0200 /* from (user) madvise request */ #define MAP_VN_WRITECOUNT 0x0400 +#define MAP_REMAP 0x0800 #define MAP_STACK_GROWS_DOWN 0x1000 #define MAP_STACK_GROWS_UP 0x2000 #define MAP_ACC_CHARGED 0x4000