|
| 1 | +#include <signal.h> |
| 2 | +#include <sys/types.h> |
| 3 | +#include <sys/wait.h> |
| 4 | + |
1 | 5 | #include "catch2/catch.hpp" |
2 | 6 | #include "msgq/msgq.h" |
3 | 7 |
|
@@ -271,6 +275,67 @@ TEST_CASE("Write 1 msg, read 1 msg", "[integration]") |
271 | 275 | msgq_msg_close(&incoming_msg2); |
272 | 276 | } |
273 | 277 |
|
| 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 | + |
274 | 339 | TEST_CASE("Write 2 msg, read 2 msg - conflate = false", "[integration]") |
275 | 340 | { |
276 | 341 | remove("/dev/shm/test_queue"); |
|
0 commit comments