Page MenuHomeFreeBSD

D18837.id52848.diff
No OneTemporary

D18837.id52848.diff

Index: contrib/netbsd-tests/kernel/t_sysv.c
===================================================================
--- contrib/netbsd-tests/kernel/t_sysv.c
+++ contrib/netbsd-tests/kernel/t_sysv.c
@@ -47,6 +47,7 @@
#include <unistd.h>
#include <sys/ipc.h>
+#include <sys/mman.h>
#include <sys/msg.h>
#include <sys/param.h>
#include <sys/sem.h>
@@ -772,17 +773,25 @@
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
@@ -837,12 +846,53 @@
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);
+ 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();
}
Index: lib/libc/sys/shmat.2
===================================================================
--- lib/libc/sys/shmat.2
+++ lib/libc/sys/shmat.2
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 25, 2018
+.Dd January 14, 2019
.Dt SHMAT 2
.Os
.Sh NAME
@@ -64,17 +64,34 @@
.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 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 NULL, and the virtual address range contains
+some pre-existing mappings, the
+.Fn shmat
+call fails.
+.Pp
The
.Fn shmdt
system call
@@ -104,6 +121,14 @@
.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 available space smaller
+than the segment size, or because pre-existing mappings 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
Index: sys/kern/sysv_shm.c
===================================================================
--- sys/kern/sysv_shm.c
+++ sys/kern/sysv_shm.c
@@ -388,7 +388,7 @@
vm_offset_t attach_va;
vm_prot_t prot;
vm_size_t size;
- int error, i, rv;
+ int cow, error, find_space, i, rv;
AUDIT_ARG_SVIPC_ID(shmid);
AUDIT_ARG_VALUE(shmflg);
@@ -427,6 +427,7 @@
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) {
@@ -436,6 +437,9 @@
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
@@ -443,12 +447,12 @@
*/
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);
Index: sys/sys/shm.h
===================================================================
--- sys/sys/shm.h
+++ sys/sys/shm.h
@@ -52,6 +52,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
Index: sys/vm/vm_map.h
===================================================================
--- sys/vm/vm_map.h
+++ sys/vm/vm_map.h
@@ -342,6 +342,7 @@
#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
Index: sys/vm/vm_map.c
===================================================================
--- sys/vm/vm_map.c
+++ sys/vm/vm_map.c
@@ -1565,6 +1565,8 @@
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;
@@ -1595,6 +1597,8 @@
}
goto done;
}
+ } else if ((cow & MAP_REMAP) != 0) {
+ vm_map_delete(map, *addr, *addr + length);
}
if ((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) != 0) {
rv = vm_map_stack_locked(map, *addr, length, sgrowsiz, prot,

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 28, 2:28 PM (21 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14368700
Default Alt Text
D18837.id52848.diff (6 KB)

Event Timeline