// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2022 Google LLC.
 * Author: Suren Baghdasaryan <surenb@google.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
/*
 * Fork a child that concurrently modifies address space while the main
 * process is reading /proc/$PID/maps and /proc/$PID/smaps, verifying the
 * results. Address space modifications include:
 *     VMA splitting and merging
 *
 */
#define _GNU_SOURCE
#include "kselftest_harness.h"
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>

#define min(a, b) \
	({ \
		typeof(a) _a = (a); \
		typeof(b) _b = (b); \
		_a < _b ? _a : _b; \
	})

/* /proc/pid/maps parsing routines */
struct page_content {
	char *data;
	ssize_t size;
};

#define LINE_MAX_SIZE		256

struct line_content {
	char text[LINE_MAX_SIZE];
	unsigned long start_addr;
	unsigned long end_addr;
};

enum test_state {
	INIT,
	CHILD_READY,
	PARENT_READY,
	SETUP_READY,
	SETUP_MODIFY_MAPS,
	SETUP_MAPS_MODIFIED,
	SETUP_RESTORE_MAPS,
	SETUP_MAPS_RESTORED,
	TEST_READY,
	TEST_DONE,
};

enum maps_file {
	MAPS,
	SMAPS,
};

struct vma_modifier_info;

FIXTURE(proc_maps_race)
{
	struct vma_modifier_info *mod_info;
	struct page_content page1;
	struct page_content page2;
	struct line_content last_line;
	struct line_content first_line;
	unsigned long duration_sec;
	enum maps_file maps_file;
	int shared_mem_size;
	int skip_pages;
	int page_size;
	int vma_count;
	bool verbose;
	int maps_fd;
	pid_t pid;
};

FIXTURE_VARIANT(proc_maps_race)
{
	const enum maps_file maps_file;
};

FIXTURE_VARIANT_ADD(proc_maps_race, maps) {
	.maps_file = MAPS,
};

FIXTURE_VARIANT_ADD(proc_maps_race, smaps) {
	.maps_file = SMAPS,
};

typedef bool (*vma_modifier_op)(FIXTURE_DATA(proc_maps_race) *self);
typedef bool (*vma_mod_result_check_op)(struct line_content *mod_last_line,
					struct line_content *mod_first_line,
					struct line_content *restored_last_line,
					struct line_content *restored_first_line);

struct vma_modifier_info {
	int vma_count;
	void *addr;
	int prot;
	void *next_addr;
	vma_modifier_op vma_modify;
	vma_modifier_op vma_restore;
	vma_mod_result_check_op vma_mod_check;
	pthread_mutex_t sync_lock;
	pthread_cond_t sync_cond;
	enum test_state curr_state;
	bool exit;
	void *child_mapped_addr[];
};

static bool read_page(FIXTURE_DATA(proc_maps_race) *self,
		      struct page_content *page)
{
	ssize_t  bytes_read;

	bytes_read = read(self->maps_fd, page->data, self->page_size);
	if (bytes_read <= 0)
		return false;

	/* Make sure data always ends with a newline character. */
	if (page->data[bytes_read - 1] != '\n')
		return false;

	page->size = bytes_read;

	return true;
}

static bool parse_vma_line(char *line_start, char *line_end,
			   unsigned long *start, unsigned long *end)
{
	bool found;

	*line_end = '\0'; /* stop sscanf at the EOL */
	found = (sscanf(line_start, "%lx-%lx", start, end) == 2);
	*line_end = '\n';

	return found;
}

static int locate_containing_page(FIXTURE_DATA(proc_maps_race) *self,
				  unsigned long addr, unsigned long size)
{
	unsigned long start, end;
	int page = 0;

	if (lseek(self->maps_fd, 0, SEEK_SET) < 0)
		return -1;

	while (true) {
		char *curr_pos;
		char *end_pos;

		if (!read_page(self, &self->page1))
			return -1;

		curr_pos = self->page1.data;
		end_pos = self->page1.data + self->page1.size;
		while (curr_pos < end_pos) {
			char *line_end;

			line_end = strchr(curr_pos, '\n');
			if (!line_end)
				break;

			if (parse_vma_line(curr_pos, line_end, &start, &end) &&
			    start == addr && end == addr + size)
				return page;

			curr_pos = line_end + 1;
		}
		page++;
	}

	return 0;
}

static bool read_two_pages(FIXTURE_DATA(proc_maps_race) *self)
{
	if (lseek(self->maps_fd, 0, SEEK_SET) < 0)
		return false;

	for (int i = 0; i < self->skip_pages; i++)
		if (!read_page(self, &self->page1))
			return false;

	return read_page(self, &self->page1) && read_page(self, &self->page2);
}

static void copy_line(const char *line_start, const char *line_end,
		      char *buf, size_t buf_size)
{
	size_t len = min(line_end - line_start, buf_size - 1);

	strncpy(buf, line_start, len);
	buf[len] = '\0';
}

static void copy_first_line(struct page_content *page, char *first_line,
			    size_t line_size)
{
	copy_line(page->data, strchr(page->data, '\n'), first_line, line_size);
}

static void copy_last_line(struct page_content *page, char *last_line,
			   size_t line_size)
{
	/* Get the last line in the first page */
	const char *end = page->data + page->size - 1;
	/* skip last newline */
	const char *pos = end - 1;

	/* search previous newline */
	while (pos[-1] != '\n')
		pos--;

	copy_line(pos, end, last_line, line_size);
}

static bool copy_first_entry(struct page_content *page, char *first_line,
			     size_t line_size)
{
	char *start_pos = page->data;

	while (start_pos < page->data + page->size) {
		unsigned long start_addr;
		unsigned long end_addr;
		char *end_pos;

		end_pos = strchr(start_pos, '\n');
		if (!end_pos)
			break;

		if (parse_vma_line(start_pos, end_pos, &start_addr, &end_addr)) {
			copy_line(start_pos, end_pos, first_line, line_size);
			return true;
		}

		start_pos = end_pos + 1;
	}

	return false;
}

static bool copy_last_entry(struct page_content *page, char *last_line,
			    size_t line_size)
{
	char *end_pos = page->data + page->size - 1;
	char *start_pos;

	while (end_pos > page->data) {
		unsigned long start_addr;
		unsigned long end_addr;

		/* skip last newline */
		start_pos = end_pos - 1;
		/* search previous newline */
		while (start_pos > page->data && start_pos[-1] != '\n')
			start_pos--;
		if (parse_vma_line(start_pos, end_pos, &start_addr, &end_addr)) {
			copy_line(start_pos, end_pos, last_line, line_size);
			return true;
		}

		end_pos = start_pos - 1;
	}

	return false;
}

/* Read the last line of the first page and the first line of the second page */
static bool read_boundary_lines(FIXTURE_DATA(proc_maps_race) *self,
				struct line_content *last_line,
				struct line_content *first_line)
{
	if (!read_two_pages(self))
		return false;

	if (self->maps_file == MAPS) {
		copy_last_line(&self->page1, last_line->text, LINE_MAX_SIZE);
		copy_first_line(&self->page2, first_line->text, LINE_MAX_SIZE);
	} else if (self->maps_file == SMAPS) {
		if (!copy_last_entry(&self->page1, last_line->text, LINE_MAX_SIZE) ||
		    !copy_first_entry(&self->page2, first_line->text, LINE_MAX_SIZE))
			return false;
	} else {
		return false;
	}

	return sscanf(last_line->text, "%lx-%lx", &last_line->start_addr,
		      &last_line->end_addr) == 2 &&
	       sscanf(first_line->text, "%lx-%lx", &first_line->start_addr,
		      &first_line->end_addr) == 2;
}

/* Thread synchronization routines */
static void wait_for_state(struct vma_modifier_info *mod_info, enum test_state state)
{
	pthread_mutex_lock(&mod_info->sync_lock);
	while (mod_info->curr_state != state)
		pthread_cond_wait(&mod_info->sync_cond, &mod_info->sync_lock);
	pthread_mutex_unlock(&mod_info->sync_lock);
}

static void signal_state(struct vma_modifier_info *mod_info, enum test_state state)
{
	pthread_mutex_lock(&mod_info->sync_lock);
	mod_info->curr_state = state;
	pthread_cond_signal(&mod_info->sync_cond);
	pthread_mutex_unlock(&mod_info->sync_lock);
}

static void stop_vma_modifier(struct vma_modifier_info *mod_info)
{
	wait_for_state(mod_info, SETUP_READY);
	mod_info->exit = true;
	signal_state(mod_info, SETUP_MODIFY_MAPS);
}

static void print_first_lines(char *text, int nr)
{
	const char *end = text;

	while (nr && (end = strchr(end, '\n')) != NULL) {
		nr--;
		end++;
	}

	if (end) {
		int offs = end - text;

		text[offs] = '\0';
		printf("%s", text);
		text[offs] = '\n';
		printf("\n");
	} else {
		printf("%s", text);
	}
}

static void print_last_lines(char *text, int nr)
{
	const char *start = text + strlen(text);

	nr++; /* to ignore the last newline */
	while (nr) {
		while (start > text && *start != '\n')
			start--;
		nr--;
		start--;
	}
	printf("%s", start);
}

static void print_boundaries(const char *title, FIXTURE_DATA(proc_maps_race) *self)
{
	if (!self->verbose)
		return;

	printf("%s", title);
	/* Print 3 boundary lines from each page */
	print_last_lines(self->page1.data, 3);
	printf("-----------------page boundary-----------------\n");
	print_first_lines(self->page2.data, 3);
}

static bool print_boundaries_on(bool condition, const char *title,
				FIXTURE_DATA(proc_maps_race) *self)
{
	if (self->verbose && condition)
		print_boundaries(title, self);

	return condition;
}

static void report_test_start(const char *name, bool verbose)
{
	if (verbose)
		printf("==== %s ====\n", name);
}

static struct timespec print_ts;

static void start_test_loop(struct timespec *ts, bool verbose)
{
	if (verbose)
		print_ts.tv_sec = ts->tv_sec;
}

static void end_test_iteration(struct timespec *ts, bool verbose)
{
	if (!verbose)
		return;

	/* Update every second */
	if (print_ts.tv_sec == ts->tv_sec)
		return;

	printf(".");
	fflush(stdout);
	print_ts.tv_sec = ts->tv_sec;
}

static void end_test_loop(bool verbose)
{
	if (verbose)
		printf("\n");
}

static bool capture_mod_pattern(FIXTURE_DATA(proc_maps_race) *self,
				struct line_content *mod_last_line,
				struct line_content *mod_first_line,
				struct line_content *restored_last_line,
				struct line_content *restored_first_line)
{
	print_boundaries("Before modification", self);

	signal_state(self->mod_info, SETUP_MODIFY_MAPS);
	wait_for_state(self->mod_info, SETUP_MAPS_MODIFIED);

	/* Copy last line of the first page and first line of the last page */
	if (!read_boundary_lines(self, mod_last_line, mod_first_line))
		return false;

	print_boundaries("After modification", self);

	signal_state(self->mod_info, SETUP_RESTORE_MAPS);
	wait_for_state(self->mod_info, SETUP_MAPS_RESTORED);

	/* Copy last line of the first page and first line of the last page */
	if (!read_boundary_lines(self, restored_last_line, restored_first_line))
		return false;

	print_boundaries("After restore", self);

	if (!self->mod_info->vma_mod_check(mod_last_line, mod_first_line,
					   restored_last_line, restored_first_line))
		return false;

	/*
	 * The content of these lines after modify+resore should be the same
	 * as the original.
	 */
	return strcmp(restored_last_line->text, self->last_line.text) == 0 &&
	       strcmp(restored_first_line->text, self->first_line.text) == 0;
}

static bool query_addr_at(int maps_fd, void *addr,
			  unsigned long *vma_start, unsigned long *vma_end)
{
	struct procmap_query q;

	memset(&q, 0, sizeof(q));
	q.size = sizeof(q);
	/* Find the VMA at the split address */
	q.query_addr = (unsigned long long)addr;
	q.query_flags = 0;
	if (ioctl(maps_fd, PROCMAP_QUERY, &q))
		return false;

	*vma_start = q.vma_start;
	*vma_end = q.vma_end;

	return true;
}

static inline bool split_vma(FIXTURE_DATA(proc_maps_race) *self)
{
	/* PROT_NONE differs from both readable neighbors. */
	return mmap(self->mod_info->addr, self->page_size, PROT_NONE,
		    MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != MAP_FAILED;
}

static inline bool merge_vma(FIXTURE_DATA(proc_maps_race) *self)
{
	return mmap(self->mod_info->addr, self->page_size, self->mod_info->prot,
		    MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != MAP_FAILED;
}

static inline bool check_split_result(struct line_content *mod_last_line,
				      struct line_content *mod_first_line,
				      struct line_content *restored_last_line,
				      struct line_content *restored_first_line)
{
	/* Make sure vmas at the boundaries are changing */
	return strcmp(mod_last_line->text, restored_last_line->text) != 0 &&
	       strcmp(mod_first_line->text, restored_first_line->text) != 0;
}

static inline bool shrink_vma(FIXTURE_DATA(proc_maps_race) *self)
{
	return mremap(self->mod_info->addr, self->page_size * 3,
		      self->page_size, 0) != MAP_FAILED;
}

static inline bool expand_vma(FIXTURE_DATA(proc_maps_race) *self)
{
	return mremap(self->mod_info->addr, self->page_size,
		      self->page_size * 3, 0) != MAP_FAILED;
}

static inline bool check_shrink_result(struct line_content *mod_last_line,
				       struct line_content *mod_first_line,
				       struct line_content *restored_last_line,
				       struct line_content *restored_first_line)
{
	/* Make sure only the last vma of the first page is changing */
	return strcmp(mod_last_line->text, restored_last_line->text) != 0 &&
	       strcmp(mod_first_line->text, restored_first_line->text) == 0;
}

static inline bool remap_vma(FIXTURE_DATA(proc_maps_race) *self)
{
	/*
	 * Remap the last page of the next vma into the middle of the vma.
	 * This splits the current vma and the first and middle parts (the
	 * parts at lower addresses) become the last vma objserved in the
	 * first page and the first vma observed in the last page.
	 */
	return mremap(self->mod_info->next_addr + self->page_size * 2, self->page_size,
		      self->page_size, MREMAP_FIXED | MREMAP_MAYMOVE | MREMAP_DONTUNMAP,
		      self->mod_info->addr + self->page_size) != MAP_FAILED;
}

static inline bool patch_vma(FIXTURE_DATA(proc_maps_race) *self)
{
	return mprotect(self->mod_info->addr + self->page_size, self->page_size,
			self->mod_info->prot) == 0;
}

static inline bool check_remap_result(struct line_content *mod_last_line,
				      struct line_content *mod_first_line,
				      struct line_content *restored_last_line,
				      struct line_content *restored_first_line)
{
	/* Make sure vmas at the boundaries are changing */
	return strcmp(mod_last_line->text, restored_last_line->text) != 0 &&
	       strcmp(mod_first_line->text, restored_first_line->text) != 0;
}

FIXTURE_SETUP(proc_maps_race)
{
	const char *verbose = getenv("VERBOSE");
	const char *duration = getenv("DURATION");
	struct vma_modifier_info *mod_info;
	pthread_mutexattr_t mutex_attr;
	pthread_condattr_t cond_attr;
	unsigned long first_map_addr;
	unsigned long last_map_addr;
	unsigned long duration_sec;
	char fname[32];

	self->page_size = (unsigned long)sysconf(_SC_PAGESIZE);
	self->verbose = verbose && !strncmp(verbose, "1", 1);
	self->maps_file = variant->maps_file;
	duration_sec = duration ? atol(duration) : 0;
	self->duration_sec = duration_sec ? duration_sec : 5UL;

	/*
	 * Have to map enough vmas for /proc/pid/maps to contain more than one
	 * page worth of vmas. Assume at least 32 bytes per line in maps output
	 */
	self->vma_count = self->page_size / 32 + 1;
	self->shared_mem_size = sizeof(struct vma_modifier_info) + self->vma_count * sizeof(void *);

	/* map shared memory for communication with the child process */
	self->mod_info = (struct vma_modifier_info *)mmap(NULL, self->shared_mem_size,
				PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
	ASSERT_NE(self->mod_info, MAP_FAILED);
	mod_info = self->mod_info;

	/* Initialize shared members */
	pthread_mutexattr_init(&mutex_attr);
	pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
	ASSERT_EQ(pthread_mutex_init(&mod_info->sync_lock, &mutex_attr), 0);
	pthread_condattr_init(&cond_attr);
	pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
	ASSERT_EQ(pthread_cond_init(&mod_info->sync_cond, &cond_attr), 0);
	mod_info->vma_count = self->vma_count;
	mod_info->curr_state = INIT;
	mod_info->exit = false;

	self->pid = fork();
	if (!self->pid) {
		/* Child process modifying the address space */
		int prot = PROT_READ | PROT_WRITE;
		int i;

		for (i = 0; i < mod_info->vma_count; i++) {
			mod_info->child_mapped_addr[i] = mmap(NULL, self->page_size * 3, prot,
					MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
			ASSERT_NE(mod_info->child_mapped_addr[i], MAP_FAILED);
			/* change protection in adjacent maps to prevent merging */
			prot ^= PROT_WRITE;
		}
		signal_state(mod_info, CHILD_READY);
		wait_for_state(mod_info, PARENT_READY);
		while (true) {
			signal_state(mod_info, SETUP_READY);
			wait_for_state(mod_info, SETUP_MODIFY_MAPS);
			if (mod_info->exit)
				break;

			ASSERT_TRUE(mod_info->vma_modify(self));
			signal_state(mod_info, SETUP_MAPS_MODIFIED);
			wait_for_state(mod_info, SETUP_RESTORE_MAPS);
			ASSERT_TRUE(mod_info->vma_restore(self));
			signal_state(mod_info, SETUP_MAPS_RESTORED);

			wait_for_state(mod_info, TEST_READY);
			while (mod_info->curr_state != TEST_DONE) {
				ASSERT_TRUE(mod_info->vma_modify(self));
				ASSERT_TRUE(mod_info->vma_restore(self));
			}
		}
		for (i = 0; i < mod_info->vma_count; i++)
			munmap(mod_info->child_mapped_addr[i], self->page_size * 3);

		exit(0);
	}

	switch (self->maps_file) {
	case MAPS:
		sprintf(fname, "/proc/%d/maps", self->pid);
		break;
	case SMAPS:
		sprintf(fname, "/proc/%d/smaps", self->pid);
		break;
	default:
		ksft_exit_fail();
	}
	self->maps_fd = open(fname, O_RDONLY);
	ASSERT_NE(self->maps_fd, -1);

	/* Wait for the child to map the VMAs */
	wait_for_state(mod_info, CHILD_READY);

	/* Read first two pages */
	self->page1.data = malloc(self->page_size);
	ASSERT_NE(self->page1.data, NULL);
	self->page2.data = malloc(self->page_size);
	ASSERT_NE(self->page2.data, NULL);

	first_map_addr = (unsigned long)mod_info->child_mapped_addr[0];
	last_map_addr = (unsigned long)mod_info->child_mapped_addr[mod_info->vma_count - 1];

	self->skip_pages = locate_containing_page(self,
					min(first_map_addr, last_map_addr),
					self->page_size * 3);
	ASSERT_NE(self->skip_pages, -1);
	ASSERT_TRUE(read_boundary_lines(self, &self->last_line, &self->first_line));

	/*
	 * Find the addresses corresponding to the last line in the first page
	 * and the first line in the last page.
	 */
	mod_info->addr = NULL;
	mod_info->next_addr = NULL;
	for (int i = 0; i < mod_info->vma_count; i++) {
		if (mod_info->child_mapped_addr[i] == (void *)self->last_line.start_addr) {
			mod_info->addr = mod_info->child_mapped_addr[i];
			mod_info->prot = PROT_READ;
			/* Even VMAs have write permission */
			if ((i % 2) == 0)
				mod_info->prot |= PROT_WRITE;
		} else if (mod_info->child_mapped_addr[i] == (void *)self->first_line.start_addr) {
			mod_info->next_addr = mod_info->child_mapped_addr[i];
		}

		if (mod_info->addr && mod_info->next_addr)
			break;
	}
	ASSERT_TRUE(mod_info->addr && mod_info->next_addr);

	signal_state(mod_info, PARENT_READY);
}

FIXTURE_TEARDOWN(proc_maps_race)
{
	int status;

	stop_vma_modifier(self->mod_info);

	free(self->page2.data);
	free(self->page1.data);

	for (int i = 0; i < self->vma_count; i++)
		munmap(self->mod_info->child_mapped_addr[i], self->page_size);
	close(self->maps_fd);
	waitpid(self->pid, &status, 0);
	munmap(self->mod_info, self->shared_mem_size);
}

TEST_F(proc_maps_race, test_maps_tearing_from_split)
{
	struct vma_modifier_info *mod_info = self->mod_info;

	struct line_content split_last_line;
	struct line_content split_first_line;
	struct line_content restored_last_line;
	struct line_content restored_first_line;

	wait_for_state(mod_info, SETUP_READY);

	/* re-read the file to avoid using stale data from previous test */
	ASSERT_TRUE(read_boundary_lines(self, &self->last_line, &self->first_line));

	mod_info->vma_modify = split_vma;
	mod_info->vma_restore = merge_vma;
	mod_info->vma_mod_check = check_split_result;

	report_test_start("Tearing from split", self->verbose);
	ASSERT_TRUE(capture_mod_pattern(self, &split_last_line, &split_first_line,
					&restored_last_line, &restored_first_line));

	/* Now start concurrent modifications for self->duration_sec */
	signal_state(mod_info, TEST_READY);

	struct line_content new_last_line;
	struct line_content new_first_line;
	struct timespec start_ts, end_ts;

	clock_gettime(CLOCK_MONOTONIC_COARSE, &start_ts);
	start_test_loop(&start_ts, self->verbose);
	do {
		bool last_line_changed;
		bool first_line_changed;
		unsigned long vma_start;
		unsigned long vma_end;

		ASSERT_TRUE(read_boundary_lines(self, &new_last_line, &new_first_line));

		/* Check if we read vmas after split */
		if (!strcmp(new_last_line.text, split_last_line.text)) {
			/*
			 * The vmas should be consistent with split results,
			 * however if vma was concurrently restored after a
			 * split, it can be reported twice (first the original
			 * split one, then the same vma but extended after the
			 * merge) because we found it as the next vma again.
			 * In that case new first line will be the same as the
			 * last restored line.
			 */
			ASSERT_FALSE(print_boundaries_on(
					strcmp(new_first_line.text, split_first_line.text) &&
					strcmp(new_first_line.text, restored_last_line.text),
					"Split result invalid", self));
		} else {
			/* The vmas should be consistent with merge results */
			ASSERT_FALSE(print_boundaries_on(
					strcmp(new_last_line.text, restored_last_line.text),
					"Merge result invalid", self));
			ASSERT_FALSE(print_boundaries_on(
					strcmp(new_first_line.text, restored_first_line.text),
					"Merge result invalid", self));
		}
		/*
		 * First and last lines should change in unison. If the last
		 * line changed then the first line should change as well and
		 * vice versa.
		 */
		last_line_changed = strcmp(new_last_line.text, self->last_line.text) != 0;
		first_line_changed = strcmp(new_first_line.text, self->first_line.text) != 0;
		ASSERT_EQ(last_line_changed, first_line_changed);
		if (self->maps_file == MAPS) {
			/* Check if PROCMAP_QUERY ioclt() finds the right VMA */
			ASSERT_TRUE(query_addr_at(self->maps_fd, mod_info->addr + self->page_size,
						  &vma_start, &vma_end));
			/*
			 * The vma at the split address can be either the same as
			 * original one (if read before the split) or the same as the
			 * first line in the second page (if read after the split).
			 */
			ASSERT_TRUE((vma_start == self->last_line.start_addr &&
				     vma_end == self->last_line.end_addr) ||
				    (vma_start == split_first_line.start_addr &&
				     vma_end == split_first_line.end_addr));
		}
		clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts);
		end_test_iteration(&end_ts, self->verbose);
	} while (end_ts.tv_sec - start_ts.tv_sec < self->duration_sec);
	end_test_loop(self->verbose);

	/* Signal the modifyer thread to stop and wait until it exits */
	signal_state(mod_info, TEST_DONE);
}

TEST_F(proc_maps_race, test_maps_tearing_from_resize)
{
	struct vma_modifier_info *mod_info = self->mod_info;

	struct line_content shrunk_last_line;
	struct line_content shrunk_first_line;
	struct line_content restored_last_line;
	struct line_content restored_first_line;

	wait_for_state(mod_info, SETUP_READY);

	/* re-read the file to avoid using stale data from previous test */
	ASSERT_TRUE(read_boundary_lines(self, &self->last_line, &self->first_line));

	mod_info->vma_modify = shrink_vma;
	mod_info->vma_restore = expand_vma;
	mod_info->vma_mod_check = check_shrink_result;

	report_test_start("Tearing from resize", self->verbose);
	ASSERT_TRUE(capture_mod_pattern(self, &shrunk_last_line, &shrunk_first_line,
					&restored_last_line, &restored_first_line));

	/* Now start concurrent modifications for self->duration_sec */
	signal_state(mod_info, TEST_READY);

	struct line_content new_last_line;
	struct line_content new_first_line;
	struct timespec start_ts, end_ts;

	clock_gettime(CLOCK_MONOTONIC_COARSE, &start_ts);
	start_test_loop(&start_ts, self->verbose);
	do {
		unsigned long vma_start;
		unsigned long vma_end;

		ASSERT_TRUE(read_boundary_lines(self, &new_last_line, &new_first_line));

		/* Check if we read vmas after shrinking it */
		if (!strcmp(new_last_line.text, shrunk_last_line.text)) {
			/*
			 * The vmas should be consistent with shrunk results,
			 * however if the vma was concurrently restored, it
			 * can be reported twice (first as shrunk one, then
			 * as restored one) because we found it as the next vma
			 * again. In that case new first line will be the same
			 * as the last restored line.
			 */
			ASSERT_FALSE(print_boundaries_on(
					strcmp(new_first_line.text, shrunk_first_line.text) &&
					strcmp(new_first_line.text, restored_last_line.text),
					"Shrink result invalid", self));
		} else {
			/* The vmas should be consistent with the original/resored state */
			ASSERT_FALSE(print_boundaries_on(
					strcmp(new_last_line.text, restored_last_line.text),
					"Expand result invalid", self));
			ASSERT_FALSE(print_boundaries_on(
					strcmp(new_first_line.text, restored_first_line.text),
					"Expand result invalid", self));
		}
		if (self->maps_file == MAPS) {
			/* Check if PROCMAP_QUERY ioclt() finds the right VMA */
			ASSERT_TRUE(query_addr_at(self->maps_fd, mod_info->addr,
						  &vma_start, &vma_end));
			/*
			 * The vma should stay at the same address and have either the
			 * original size of 3 pages or 1 page if read after shrinking.
			 */
			ASSERT_TRUE(vma_start == self->last_line.start_addr &&
				    (vma_end - vma_start == self->page_size * 3 ||
				     vma_end - vma_start == self->page_size));
		}
		clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts);
		end_test_iteration(&end_ts, self->verbose);
	} while (end_ts.tv_sec - start_ts.tv_sec < self->duration_sec);
	end_test_loop(self->verbose);

	/* Signal the modifyer thread to stop and wait until it exits */
	signal_state(mod_info, TEST_DONE);
}

TEST_F(proc_maps_race, test_maps_tearing_from_remap)
{
	struct vma_modifier_info *mod_info = self->mod_info;

	struct line_content remapped_last_line;
	struct line_content remapped_first_line;
	struct line_content restored_last_line;
	struct line_content restored_first_line;

	wait_for_state(mod_info, SETUP_READY);

	/* re-read the file to avoid using stale data from previous test */
	ASSERT_TRUE(read_boundary_lines(self, &self->last_line, &self->first_line));

	mod_info->vma_modify = remap_vma;
	mod_info->vma_restore = patch_vma;
	mod_info->vma_mod_check = check_remap_result;

	report_test_start("Tearing from remap", self->verbose);
	ASSERT_TRUE(capture_mod_pattern(self, &remapped_last_line, &remapped_first_line,
					&restored_last_line, &restored_first_line));

	/* Now start concurrent modifications for self->duration_sec */
	signal_state(mod_info, TEST_READY);

	struct line_content new_last_line;
	struct line_content new_first_line;
	struct timespec start_ts, end_ts;

	clock_gettime(CLOCK_MONOTONIC_COARSE, &start_ts);
	start_test_loop(&start_ts, self->verbose);
	do {
		unsigned long vma_start;
		unsigned long vma_end;

		ASSERT_TRUE(read_boundary_lines(self, &new_last_line, &new_first_line));

		/* Check if we read vmas after remapping it */
		if (!strcmp(new_last_line.text, remapped_last_line.text)) {
			/*
			 * The vmas should be consistent with remap results,
			 * however if the vma was concurrently restored, it
			 * can be reported twice (first as split one, then
			 * as restored one) because we found it as the next vma
			 * again. In that case new first line will be the same
			 * as the last restored line.
			 */
			ASSERT_FALSE(print_boundaries_on(
					strcmp(new_first_line.text, remapped_first_line.text) &&
					strcmp(new_first_line.text, restored_last_line.text),
					"Remap result invalid", self));
		} else {
			/* The vmas should be consistent with the original/resored state */
			ASSERT_FALSE(print_boundaries_on(
					strcmp(new_last_line.text, restored_last_line.text),
					"Remap restore result invalid", self));
			ASSERT_FALSE(print_boundaries_on(
					strcmp(new_first_line.text, restored_first_line.text),
					"Remap restore result invalid", self));
		}
		if (self->maps_file == MAPS) {
			/* Check if PROCMAP_QUERY ioclt() finds the right VMA */
			ASSERT_TRUE(query_addr_at(self->maps_fd, mod_info->addr + self->page_size,
						  &vma_start, &vma_end));
			/*
			 * The vma should either stay at the same address and have the
			 * original size of 3 pages or we should find the remapped vma
			 * at the remap destination address with size of 1 page.
			 */
			ASSERT_TRUE((vma_start == self->last_line.start_addr &&
				     vma_end - vma_start == self->page_size * 3) ||
				    (vma_start == self->last_line.start_addr + self->page_size &&
				     vma_end - vma_start == self->page_size));
		}
		clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts);
		end_test_iteration(&end_ts, self->verbose);
	} while (end_ts.tv_sec - start_ts.tv_sec < self->duration_sec);
	end_test_loop(self->verbose);

	/* Signal the modifyer thread to stop and wait until it exits */
	signal_state(mod_info, TEST_DONE);
}

TEST_HARNESS_MAIN
