Skip to content

SHM_REMAP is broken #2698

Description

@bsdjhb

While testing some other SYSV SHM changes, I noticed that the kyua sysv_test:shm_remap fails on CheriBSD.

The test does this:

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);
}

So it maps a single page, then shmat() on top of it with SHM_REMAP. The second call to shmat() fails with ENOMEM:

# kyua test -k /usr/tests/sys/kern/Kyuafile sysv_test:shm_remap
sysv_test:shm_remap  ->  failed: /usr/home/john/work/cheri/git/cheribsd/contrib/netbsd-tests/kernel/t_sysv.c:800: shmat(SHM_REMAP): 12  [1.660s]

Single stepping in the kernel, I traced this down to this seeming bug in vm_map_find_locked():

	if (find_space != VMFS_NO_SPACE) {
...
	} else if ((cow & MAP_REMAP) != 0) {
		if (!vm_map_range_valid(map, vaddr, vaddr + length))
			return (KERN_INVALID_ADDRESS);
		rv = vm_map_delete(map, vaddr, vaddr + length, true);
		if (rv != KERN_SUCCESS)
			return (rv);
	}

	reservation = vaddr;
	rv = vm_map_reservation_create_locked(map, &reservation,
	    length, max);
	if (rv != KERN_SUCCESS)
		return (rv);

In this case MAP_REMAP is set, so the old range is deleted, but the existing reservation is left in place, so then the vm_map_reservation_create_locked() fails. Possibly for the SHM_REMAP case we should be using vm_map_fixed instead? Or maybe for the MAP_REMAP case we should try using vm_map_reservation_get?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions