1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) Zilogic Systems Pvt. Ltd., 2020
4f08c3bdfSopenharmony_ci * Email: code@zilogic.com
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci
7f08c3bdfSopenharmony_ci/*
8f08c3bdfSopenharmony_ci * Test mmap with MAP_FIXED_NOREPLACE flag
9f08c3bdfSopenharmony_ci *
10f08c3bdfSopenharmony_ci * We are testing the MAP_FIXED_NOREPLACE flag of mmap() syscall. To check
11f08c3bdfSopenharmony_ci * if an attempt to mmap at an exisiting mapping fails with EEXIST.
12f08c3bdfSopenharmony_ci * The code allocates a free address by passing NULL to first mmap call
13f08c3bdfSopenharmony_ci * Then tries to mmap with the same address using MAP_FIXED_NOREPLACE flag
14f08c3bdfSopenharmony_ci * and the mapping fails as expected.
15f08c3bdfSopenharmony_ci */
16f08c3bdfSopenharmony_ci
17f08c3bdfSopenharmony_ci#include <stdio.h>
18f08c3bdfSopenharmony_ci#include <fcntl.h>
19f08c3bdfSopenharmony_ci#include <sys/types.h>
20f08c3bdfSopenharmony_ci#include <sys/stat.h>
21f08c3bdfSopenharmony_ci#include <unistd.h>
22f08c3bdfSopenharmony_ci#include <errno.h>
23f08c3bdfSopenharmony_ci#include <string.h>
24f08c3bdfSopenharmony_ci#include <stdlib.h>
25f08c3bdfSopenharmony_ci#include "lapi/mmap.h"
26f08c3bdfSopenharmony_ci#include "tst_test.h"
27f08c3bdfSopenharmony_ci
28f08c3bdfSopenharmony_cistatic int fd_file1;
29f08c3bdfSopenharmony_cistatic int fd_file2;
30f08c3bdfSopenharmony_cistatic void *mapped_address;
31f08c3bdfSopenharmony_cistatic const char str[] = "Writing to mapped file";
32f08c3bdfSopenharmony_ci
33f08c3bdfSopenharmony_ci#define FNAME1 "file1_to_mmap"
34f08c3bdfSopenharmony_ci#define FNAME2 "file2_to_mmap"
35f08c3bdfSopenharmony_ci
36f08c3bdfSopenharmony_cistatic void setup(void)
37f08c3bdfSopenharmony_ci{
38f08c3bdfSopenharmony_ci	fd_file1 = SAFE_OPEN(FNAME1, O_CREAT | O_RDWR, 0600);
39f08c3bdfSopenharmony_ci	fd_file2 = SAFE_OPEN(FNAME2, O_CREAT | O_RDWR, 0600);
40f08c3bdfSopenharmony_ci}
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_cistatic void cleanup(void)
43f08c3bdfSopenharmony_ci{
44f08c3bdfSopenharmony_ci	int str_len;
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci	str_len = strlen(str);
47f08c3bdfSopenharmony_ci
48f08c3bdfSopenharmony_ci	if (fd_file2 > 0)
49f08c3bdfSopenharmony_ci		SAFE_CLOSE(fd_file2);
50f08c3bdfSopenharmony_ci	if (fd_file1 > 0)
51f08c3bdfSopenharmony_ci		SAFE_CLOSE(fd_file1);
52f08c3bdfSopenharmony_ci	if (mapped_address)
53f08c3bdfSopenharmony_ci		SAFE_MUNMAP(mapped_address, str_len);
54f08c3bdfSopenharmony_ci}
55f08c3bdfSopenharmony_ci
56f08c3bdfSopenharmony_cistatic void test_mmap(void)
57f08c3bdfSopenharmony_ci{
58f08c3bdfSopenharmony_ci	int str_len;
59f08c3bdfSopenharmony_ci	void *address;
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_ci	str_len = strlen(str);
62f08c3bdfSopenharmony_ci
63f08c3bdfSopenharmony_ci	SAFE_WRITE(SAFE_WRITE_ALL, fd_file1, str, str_len);
64f08c3bdfSopenharmony_ci	mapped_address = SAFE_MMAP(NULL, str_len, PROT_WRITE,
65f08c3bdfSopenharmony_ci				   MAP_PRIVATE, fd_file1, 0);
66f08c3bdfSopenharmony_ci
67f08c3bdfSopenharmony_ci	SAFE_WRITE(SAFE_WRITE_ALL, fd_file2, str, str_len);
68f08c3bdfSopenharmony_ci
69f08c3bdfSopenharmony_ci	address = mmap(mapped_address, str_len, PROT_WRITE,
70f08c3bdfSopenharmony_ci		  MAP_PRIVATE | MAP_FIXED_NOREPLACE, fd_file2, 0);
71f08c3bdfSopenharmony_ci	if (address == MAP_FAILED && errno == EEXIST)
72f08c3bdfSopenharmony_ci		tst_res(TPASS, "mmap set errno to EEXIST as expected");
73f08c3bdfSopenharmony_ci	else
74f08c3bdfSopenharmony_ci		tst_res(TFAIL | TERRNO, "mmap failed, with unexpected error "
75f08c3bdfSopenharmony_ci			"code, expected EEXIST");
76f08c3bdfSopenharmony_ci}
77f08c3bdfSopenharmony_ci
78f08c3bdfSopenharmony_cistatic struct tst_test test = {
79f08c3bdfSopenharmony_ci	.setup = setup,
80f08c3bdfSopenharmony_ci	.cleanup = cleanup,
81f08c3bdfSopenharmony_ci	.test_all = test_mmap,
82f08c3bdfSopenharmony_ci	.min_kver = "4.17",
83f08c3bdfSopenharmony_ci	.needs_tmpdir = 1
84f08c3bdfSopenharmony_ci};
85