Skip to content

Commit cec1e90

Browse files
committed
msgq: add a new test for the queue of write protection
This patch introduces a new test for write protection of queue from the subscriber. This test intentionally disables CATCH2's signal handler in the subscriber process to detect SIGSEGV signals.
1 parent 3c0f0c4 commit cec1e90

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

msgq/msgq_tests.cc

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#include <signal.h>
2+
#include <sys/types.h>
3+
#include <sys/wait.h>
4+
15
#include "catch2/catch.hpp"
26
#include "msgq/msgq.h"
37

@@ -271,6 +275,67 @@ TEST_CASE("Write 1 msg, read 1 msg", "[integration]")
271275
msgq_msg_close(&incoming_msg2);
272276
}
273277

278+
TEST_CASE("Write/read 1 msg, detect violate permission", "[integration]")
279+
{
280+
remove("/dev/shm/test_queue");
281+
const size_t msg_size = 128;
282+
msgq_queue_t writer, reader;
283+
284+
msgq_new_queue_pub(&writer, "test_queue", 1024);
285+
msgq_new_queue_sub(&reader, "test_queue", 1024);
286+
287+
msgq_init_publisher(&writer);
288+
msgq_init_subscriber(&reader);
289+
290+
// Build 128 byte message
291+
msgq_msg_t outgoing_msg;
292+
msgq_msg_init_size(&outgoing_msg, msg_size);
293+
294+
for (size_t i = 0; i < msg_size; i++)
295+
{
296+
outgoing_msg.data[i] = i;
297+
}
298+
299+
REQUIRE(msgq_msg_send(&outgoing_msg, &writer) == msg_size);
300+
301+
msgq_msg_t incoming_msg1;
302+
REQUIRE(msgq_msg_recv(&incoming_msg1, &reader) == msg_size);
303+
REQUIRE(memcmp(incoming_msg1.data, outgoing_msg.data, msg_size) == 0);
304+
305+
// Verify that there are no more messages
306+
msgq_msg_t incoming_msg2;
307+
REQUIRE(msgq_msg_recv(&incoming_msg2, &reader) == 0);
308+
309+
// Wait SIGSEGV to detect write access from subscriber
310+
pid_t pid = fork();
311+
if (pid != 0) {
312+
// Parent: Wait SIGSEGV of the child
313+
int status;
314+
pid_t res = waitpid(pid, &status, 0);
315+
REQUIRE(res == pid);
316+
REQUIRE(WIFSIGNALED(status));
317+
REQUIRE(WTERMSIG(status) == SIGSEGV);
318+
} else {
319+
// Child: Remove CATCH2's signal handler and write
320+
struct sigaction act = {
321+
.sa_handler = SIG_DFL,
322+
};
323+
sigaction(SIGSEGV, &act, NULL);
324+
// Try to write into read-only area
325+
incoming_msg2.data[0] = 1;
326+
exit(0);
327+
}
328+
329+
for (size_t i = 0; i < msg_size; i++)
330+
{
331+
REQUIRE(outgoing_msg.data[i] == i);
332+
}
333+
334+
msgq_msg_close(&outgoing_msg);
335+
msgq_msg_close(&incoming_msg1);
336+
msgq_msg_close(&incoming_msg2);
337+
}
338+
274339
TEST_CASE("Write 2 msg, read 2 msg - conflate = false", "[integration]")
275340
{
276341
remove("/dev/shm/test_queue");

0 commit comments

Comments
 (0)