xref: /aosp_15_r20/external/ltp/testcases/kernel/containers/sysvipc/msg_comm.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2014 Red Hat, Inc.
4  * Copyright (C) 2022 SUSE LLC Andrea Cervesato <[email protected]>
5  */
6 
7 /*\
8  * [Description]
9  *
10  * Test SysV IPC message passing through different processes.
11  *
12  * [Algorithm]
13  *
14  * 1. Clones two child processes with CLONE_NEWIPC flag, each child
15  *    gets System V message queue (msg) with the _identical_ key.
16  * 2. Child1 appends a message with identifier #1 to the message queue.
17  * 3. Child2 appends a message with identifier #2 to the message queue.
18  * 4. Appends to the message queue with the identical key but from
19  *    two different IPC namespaces should not interfere with each other
20  *    and so child1 checks whether its message queue doesn't contain
21  *    a message with identifier #2, if it doesn't test passes, otherwise
22  *    test fails.
23  */
24 
25 #define _GNU_SOURCE
26 
27 #include <sys/wait.h>
28 #include <sys/msg.h>
29 #include <sys/types.h>
30 #include "tst_safe_sysv_ipc.h"
31 #include "tst_test.h"
32 #include "common.h"
33 
34 #define TESTKEY 124426L
35 
36 struct sysv_msg {
37 	long mtype;
38 	char mtext[1];
39 };
40 
chld1_msg(void)41 static void chld1_msg(void)
42 {
43 	int id;
44 	struct sysv_msg m = {
45 		.mtype = 1,
46 		.mtext = "A",
47 	};
48 	struct sysv_msg rec;
49 
50 	id = SAFE_MSGGET(TESTKEY, IPC_CREAT | 0600);
51 
52 	SAFE_MSGSND(id, &m, sizeof(m.mtext), 0);
53 
54 	TST_CHECKPOINT_WAIT(0);
55 
56 	TEST(msgrcv(id, &rec, sizeof(rec.mtext), 2, IPC_NOWAIT));
57 	if (TST_RET < 0 && TST_ERR != ENOMSG)
58 		tst_brk(TBROK | TERRNO, "msgrcv error");
59 
60 	/* if child1 message queue has changed (by child2) report fail */
61 	if (TST_RET > 0)
62 		tst_res(TFAIL, "messages leak between namespacess");
63 	else
64 		tst_res(TPASS, "messages does not leak between namespaces");
65 
66 	TST_CHECKPOINT_WAKE(0);
67 
68 	SAFE_MSGCTL(id, IPC_RMID, NULL);
69 }
70 
chld2_msg(void)71 static void chld2_msg(void)
72 {
73 	int id;
74 	struct sysv_msg m = {
75 		.mtype = 2,
76 		.mtext = "B",
77 	};
78 
79 	id = SAFE_MSGGET(TESTKEY, IPC_CREAT | 0600);
80 
81 	SAFE_MSGSND(id, &m, sizeof(m.mtext), 0);
82 
83 	TST_CHECKPOINT_WAKE_AND_WAIT(0);
84 
85 	SAFE_MSGCTL(id, IPC_RMID, NULL);
86 }
87 
run(void)88 static void run(void)
89 {
90 	clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld1_msg);
91 	clone_unshare_test(T_CLONE, CLONE_NEWIPC, chld2_msg);
92 }
93 
94 static struct tst_test test = {
95 	.test_all = run,
96 	.needs_root = 1,
97 	.needs_checkpoints = 1,
98 	.forks_child = 1,
99 };
100