1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2009
4f08c3bdfSopenharmony_ci *				Veerendra C <vechandr@in.ibm.com>
5f08c3bdfSopenharmony_ci * Copyright (C) 2022 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
6f08c3bdfSopenharmony_ci */
7f08c3bdfSopenharmony_ci
8f08c3bdfSopenharmony_ci/*\
9f08c3bdfSopenharmony_ci * [Description]
10f08c3bdfSopenharmony_ci *
11f08c3bdfSopenharmony_ci * Test SysV IPC message passing through different namespaces.
12f08c3bdfSopenharmony_ci *
13f08c3bdfSopenharmony_ci * [Algorithm]
14f08c3bdfSopenharmony_ci *
15f08c3bdfSopenharmony_ci * In parent process create a new mesgq with a specific key.
16f08c3bdfSopenharmony_ci * In cloned process try to access the created mesgq.
17f08c3bdfSopenharmony_ci *
18f08c3bdfSopenharmony_ci * Test will PASS if the mesgq is readable when flag is None.
19f08c3bdfSopenharmony_ci * Test will FAIL if the mesgq is readable when flag is Unshare or Clone or
20f08c3bdfSopenharmony_ci * the message received is wrong.
21f08c3bdfSopenharmony_ci */
22f08c3bdfSopenharmony_ci
23f08c3bdfSopenharmony_ci#define _GNU_SOURCE
24f08c3bdfSopenharmony_ci
25f08c3bdfSopenharmony_ci#include <sys/wait.h>
26f08c3bdfSopenharmony_ci#include <sys/msg.h>
27f08c3bdfSopenharmony_ci#include <sys/types.h>
28f08c3bdfSopenharmony_ci#include "tst_safe_sysv_ipc.h"
29f08c3bdfSopenharmony_ci#include "tst_test.h"
30f08c3bdfSopenharmony_ci#include "common.h"
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_ci#define KEY_VAL 154326L
33f08c3bdfSopenharmony_ci#define MSG_TYPE 5
34f08c3bdfSopenharmony_ci#define MSG_TEXT "My message!"
35f08c3bdfSopenharmony_ci
36f08c3bdfSopenharmony_cistatic char *str_op;
37f08c3bdfSopenharmony_cistatic int use_clone;
38f08c3bdfSopenharmony_cistatic int ipc_id = -1;
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_cistruct msg_buf {
41f08c3bdfSopenharmony_ci	long mtype;
42f08c3bdfSopenharmony_ci	char mtext[80];
43f08c3bdfSopenharmony_ci};
44f08c3bdfSopenharmony_ci
45f08c3bdfSopenharmony_cistatic void check_mesgq(void)
46f08c3bdfSopenharmony_ci{
47f08c3bdfSopenharmony_ci	int id, n;
48f08c3bdfSopenharmony_ci	struct msg_buf msg = {};
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_ci	id = msgget(KEY_VAL, 0);
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_ci	if (id < 0) {
53f08c3bdfSopenharmony_ci		if (use_clone == T_NONE)
54f08c3bdfSopenharmony_ci			tst_res(TFAIL, "Plain cloned process didn't find mesgq");
55f08c3bdfSopenharmony_ci		else
56f08c3bdfSopenharmony_ci			tst_res(TPASS, "%s: container didn't find mesgq", str_op);
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci		return;
59f08c3bdfSopenharmony_ci	}
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_ci	if (use_clone == T_NONE) {
62f08c3bdfSopenharmony_ci		tst_res(TPASS, "Plain cloned process found mesgq inside container");
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_ci		n = SAFE_MSGRCV(id, &msg, sizeof(msg.mtext), MSG_TYPE, 0);
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_ci		tst_res(TINFO, "Mesg read of %d bytes, Type %ld, Msg: %s", n, msg.mtype, msg.mtext);
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci		if (strcmp(msg.mtext, MSG_TEXT))
69f08c3bdfSopenharmony_ci			tst_res(TFAIL, "Received the wrong text message");
70f08c3bdfSopenharmony_ci
71f08c3bdfSopenharmony_ci		return;
72f08c3bdfSopenharmony_ci	}
73f08c3bdfSopenharmony_ci
74f08c3bdfSopenharmony_ci	tst_res(TFAIL, "%s: container init process found mesgq", str_op);
75f08c3bdfSopenharmony_ci}
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_cistatic void run(void)
78f08c3bdfSopenharmony_ci{
79f08c3bdfSopenharmony_ci	struct msg_buf msg = {
80f08c3bdfSopenharmony_ci		.mtype = MSG_TYPE,
81f08c3bdfSopenharmony_ci		.mtext = MSG_TEXT,
82f08c3bdfSopenharmony_ci	};
83f08c3bdfSopenharmony_ci
84f08c3bdfSopenharmony_ci	if (use_clone == T_NONE)
85f08c3bdfSopenharmony_ci		SAFE_MSGSND(ipc_id, &msg, strlen(msg.mtext), 0);
86f08c3bdfSopenharmony_ci
87f08c3bdfSopenharmony_ci	tst_res(TINFO, "mesgq namespaces test: %s", str_op);
88f08c3bdfSopenharmony_ci
89f08c3bdfSopenharmony_ci	clone_unshare_test(use_clone, CLONE_NEWIPC, check_mesgq);
90f08c3bdfSopenharmony_ci}
91f08c3bdfSopenharmony_ci
92f08c3bdfSopenharmony_cistatic void setup(void)
93f08c3bdfSopenharmony_ci{
94f08c3bdfSopenharmony_ci	use_clone = get_clone_unshare_enum(str_op);
95f08c3bdfSopenharmony_ci	ipc_id = SAFE_MSGGET(KEY_VAL, IPC_CREAT | IPC_EXCL | 0600);
96f08c3bdfSopenharmony_ci}
97f08c3bdfSopenharmony_ci
98f08c3bdfSopenharmony_cistatic void cleanup(void)
99f08c3bdfSopenharmony_ci{
100f08c3bdfSopenharmony_ci	if (ipc_id != -1) {
101f08c3bdfSopenharmony_ci		tst_res(TINFO, "Destroying message queue");
102f08c3bdfSopenharmony_ci		SAFE_MSGCTL(ipc_id, IPC_RMID, NULL);
103f08c3bdfSopenharmony_ci	}
104f08c3bdfSopenharmony_ci}
105f08c3bdfSopenharmony_ci
106f08c3bdfSopenharmony_cistatic struct tst_test test = {
107f08c3bdfSopenharmony_ci	.test_all = run,
108f08c3bdfSopenharmony_ci	.setup = setup,
109f08c3bdfSopenharmony_ci	.cleanup = cleanup,
110f08c3bdfSopenharmony_ci	.needs_root = 1,
111f08c3bdfSopenharmony_ci	.forks_child = 1,
112f08c3bdfSopenharmony_ci	.options = (struct tst_option[]) {
113f08c3bdfSopenharmony_ci		{ "m:", &str_op, "Test execution mode <clone|unshare|none>" },
114f08c3bdfSopenharmony_ci		{},
115f08c3bdfSopenharmony_ci	},
116f08c3bdfSopenharmony_ci};
117