1/*-
2 * Copyright (c) 2018 Aniket Pandey
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * SUCH DAMAGE.
24 */
25
26#include <sys/types.h>
27#include <sys/ipc.h>
28#include <sys/mman.h>
29#include <sys/msg.h>
30#include <sys/shm.h>
31#define _WANT_SEMUN
32#include <sys/sem.h>
33#include <sys/stat.h>
34
35#include <atf-c.h>
36#include <fcntl.h>
37#include <stdlib.h>
38#include <unistd.h>
39
40#include "utils.h"
41#define BUFFSIZE 80
42
43struct msgstr {
44	long int	 mtype;
45	char		 mtext[BUFFSIZE];
46};
47typedef struct msgstr msgstr_t;
48
49static pid_t pid;
50static int msqid, shmid, semid;
51static union semun semarg;
52static struct pollfd fds[1];
53static struct msqid_ds msgbuff;
54static struct shmid_ds shmbuff;
55static struct semid_ds sembuff;
56static char ipcregex[BUFFSIZE];
57static const char *auclass = "ip";
58static char path[BUFFSIZE] = "/fileforaudit";
59static unsigned short semvals[BUFFSIZE];
60
61
62ATF_TC_WITH_CLEANUP(msgget_success);
63ATF_TC_HEAD(msgget_success, tc)
64{
65	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
66					"msgget(2) call");
67}
68
69ATF_TC_BODY(msgget_success, tc)
70{
71	FILE *pipefd = setup(fds, auclass);
72	/* Create a message queue and obtain the corresponding identifier */
73	ATF_REQUIRE((msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR)) != -1);
74	/* Check the presence of message queue ID in audit record */
75	snprintf(ipcregex, sizeof(ipcregex),
76			"msgget.*return,success,%d", msqid);
77	check_audit(fds, ipcregex, pipefd);
78
79	/* Destroy the message queue with ID = msqid */
80	ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL));
81}
82
83ATF_TC_CLEANUP(msgget_success, tc)
84{
85	cleanup();
86}
87
88
89ATF_TC_WITH_CLEANUP(msgget_failure);
90ATF_TC_HEAD(msgget_failure, tc)
91{
92	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
93					"msgget(2) call");
94}
95
96ATF_TC_BODY(msgget_failure, tc)
97{
98	const char *regex = "msgget.*return,failure.*No such file or directory";
99	FILE *pipefd = setup(fds, auclass);
100	ATF_REQUIRE_EQ(-1, msgget((key_t)(-1), 0));
101	check_audit(fds, regex, pipefd);
102}
103
104ATF_TC_CLEANUP(msgget_failure, tc)
105{
106	cleanup();
107}
108
109
110ATF_TC_WITH_CLEANUP(msgsnd_success);
111ATF_TC_HEAD(msgsnd_success, tc)
112{
113	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
114					"msgsnd(2) call");
115}
116
117ATF_TC_BODY(msgsnd_success, tc)
118{
119	/* Create a message queue and obtain the corresponding identifier */
120	ATF_REQUIRE((msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR)) != -1);
121
122	/* Initialize a msgstr_t structure to store message */
123	msgstr_t msg;
124	msg.mtype = 1;
125	memset(msg.mtext, 0, BUFFSIZE);
126
127	/* Check the presence of message queue ID in audit record */
128	snprintf(ipcregex, sizeof(ipcregex),
129		"msgsnd.*Message IPC.*%d.*return,success", msqid);
130
131	FILE *pipefd = setup(fds, auclass);
132	ATF_REQUIRE_EQ(0, msgsnd(msqid, &msg, BUFFSIZE, IPC_NOWAIT));
133	check_audit(fds, ipcregex, pipefd);
134
135	/* Destroy the message queue with ID = msqid */
136	ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL));
137}
138
139ATF_TC_CLEANUP(msgsnd_success, tc)
140{
141	cleanup();
142}
143
144
145ATF_TC_WITH_CLEANUP(msgsnd_failure);
146ATF_TC_HEAD(msgsnd_failure, tc)
147{
148	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
149					"msgsnd(2) call");
150}
151
152ATF_TC_BODY(msgsnd_failure, tc)
153{
154	const char *regex = "msgsnd.*Message IPC.*return,failure : Bad address";
155	FILE *pipefd = setup(fds, auclass);
156	ATF_REQUIRE_EQ(-1, msgsnd(-1, NULL, 0, IPC_NOWAIT));
157	check_audit(fds, regex, pipefd);
158}
159
160ATF_TC_CLEANUP(msgsnd_failure, tc)
161{
162	cleanup();
163}
164
165
166ATF_TC_WITH_CLEANUP(msgrcv_success);
167ATF_TC_HEAD(msgrcv_success, tc)
168{
169	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
170					"msgrcv(2) call");
171}
172
173ATF_TC_BODY(msgrcv_success, tc)
174{
175	ssize_t recv_bytes;
176	/* Create a message queue and obtain the corresponding identifier */
177	ATF_REQUIRE((msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR)) != -1);
178
179	/* Initialize two msgstr_t structures to store respective messages */
180	msgstr_t msg1, msg2;
181	msg1.mtype = 1;
182	memset(msg1.mtext, 0, BUFFSIZE);
183
184	/* Send a message to the queue with ID = msqid */
185	ATF_REQUIRE_EQ(0, msgsnd(msqid, &msg1, BUFFSIZE, IPC_NOWAIT));
186
187	FILE *pipefd = setup(fds, auclass);
188	ATF_REQUIRE((recv_bytes = msgrcv(msqid, &msg2,
189			BUFFSIZE, 0, MSG_NOERROR | IPC_NOWAIT)) != -1);
190	/* Check the presence of queue ID and returned bytes in audit record */
191	snprintf(ipcregex, sizeof(ipcregex),
192	"msgrcv.*Message IPC,*%d.*return,success,%zd", msqid, recv_bytes);
193	check_audit(fds, ipcregex, pipefd);
194
195	/* Destroy the message queue with ID = msqid */
196	ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL));
197}
198
199ATF_TC_CLEANUP(msgrcv_success, tc)
200{
201	cleanup();
202}
203
204
205ATF_TC_WITH_CLEANUP(msgrcv_failure);
206ATF_TC_HEAD(msgrcv_failure, tc)
207{
208	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
209					"msgrcv(2) call");
210}
211
212ATF_TC_BODY(msgrcv_failure, tc)
213{
214	const char *regex = "msgrcv.*return,failure : Invalid argument";
215	FILE *pipefd = setup(fds, auclass);
216	ATF_REQUIRE_EQ(-1, msgrcv(-1, NULL, 0, 0, MSG_NOERROR | IPC_NOWAIT));
217	check_audit(fds, regex, pipefd);
218}
219
220ATF_TC_CLEANUP(msgrcv_failure, tc)
221{
222	cleanup();
223}
224
225
226ATF_TC_WITH_CLEANUP(msgctl_rmid_success);
227ATF_TC_HEAD(msgctl_rmid_success, tc)
228{
229	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
230					"msgctl(2) call for IPC_RMID command");
231}
232
233ATF_TC_BODY(msgctl_rmid_success, tc)
234{
235	/* Create a message queue and obtain the corresponding identifier */
236	ATF_REQUIRE((msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR)) != -1);
237
238	FILE *pipefd = setup(fds, auclass);
239	ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL));
240	/* Check the presence of queue ID and IPC_RMID in audit record */
241	snprintf(ipcregex, sizeof(ipcregex),
242			"msgctl.*IPC_RMID.*%d.*return,success", msqid);
243	check_audit(fds, ipcregex, pipefd);
244}
245
246ATF_TC_CLEANUP(msgctl_rmid_success, tc)
247{
248	cleanup();
249}
250
251
252ATF_TC_WITH_CLEANUP(msgctl_rmid_failure);
253ATF_TC_HEAD(msgctl_rmid_failure, tc)
254{
255	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
256					"msgctl(2) call for IPC_RMID command");
257}
258
259ATF_TC_BODY(msgctl_rmid_failure, tc)
260{
261	const char *regex = "msgctl.*IPC_RMID.*return,failur.*Invalid argument";
262	FILE *pipefd = setup(fds, auclass);
263	ATF_REQUIRE_EQ(-1, msgctl(-1, IPC_RMID, NULL));
264	check_audit(fds, regex, pipefd);
265}
266
267ATF_TC_CLEANUP(msgctl_rmid_failure, tc)
268{
269	cleanup();
270}
271
272
273ATF_TC_WITH_CLEANUP(msgctl_stat_success);
274ATF_TC_HEAD(msgctl_stat_success, tc)
275{
276	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
277					"msgctl(2) call for IPC_STAT command");
278}
279
280ATF_TC_BODY(msgctl_stat_success, tc)
281{
282	/* Create a message queue and obtain the corresponding identifier */
283	ATF_REQUIRE((msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR)) != -1);
284
285	FILE *pipefd = setup(fds, auclass);
286	ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_STAT, &msgbuff));
287	/* Check the presence of queue ID and IPC_STAT in audit record */
288	snprintf(ipcregex, sizeof(ipcregex),
289			"msgctl.*IPC_STAT.*%d.*return,success", msqid);
290	check_audit(fds, ipcregex, pipefd);
291
292	/* Destroy the message queue with ID = msqid */
293	ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL));
294}
295
296ATF_TC_CLEANUP(msgctl_stat_success, tc)
297{
298	cleanup();
299}
300
301
302ATF_TC_WITH_CLEANUP(msgctl_stat_failure);
303ATF_TC_HEAD(msgctl_stat_failure, tc)
304{
305	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
306					"msgctl(2) call for IPC_STAT command");
307}
308
309ATF_TC_BODY(msgctl_stat_failure, tc)
310{
311	const char *regex = "msgctl.*IPC_STAT.*return,failur.*Invalid argument";
312	FILE *pipefd = setup(fds, auclass);
313	ATF_REQUIRE_EQ(-1, msgctl(-1, IPC_STAT, &msgbuff));
314	check_audit(fds, regex, pipefd);
315}
316
317ATF_TC_CLEANUP(msgctl_stat_failure, tc)
318{
319	cleanup();
320}
321
322
323ATF_TC_WITH_CLEANUP(msgctl_set_success);
324ATF_TC_HEAD(msgctl_set_success, tc)
325{
326	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
327					"msgctl(2) call for IPC_SET command");
328}
329
330ATF_TC_BODY(msgctl_set_success, tc)
331{
332	/* Create a message queue and obtain the corresponding identifier */
333	ATF_REQUIRE((msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR)) != -1);
334	/* Fill up the msgbuff structure to be used with IPC_SET */
335	ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_STAT, &msgbuff));
336
337	FILE *pipefd = setup(fds, auclass);
338	ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_SET, &msgbuff));
339	/* Check the presence of message queue ID in audit record */
340	snprintf(ipcregex, sizeof(ipcregex),
341			"msgctl.*IPC_SET.*%d.*return,success", msqid);
342	check_audit(fds, ipcregex, pipefd);
343
344	/* Destroy the message queue with ID = msqid */
345	ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL));
346}
347
348ATF_TC_CLEANUP(msgctl_set_success, tc)
349{
350	cleanup();
351}
352
353
354ATF_TC_WITH_CLEANUP(msgctl_set_failure);
355ATF_TC_HEAD(msgctl_set_failure, tc)
356{
357	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
358					"msgctl(2) call for IPC_SET command");
359}
360
361ATF_TC_BODY(msgctl_set_failure, tc)
362{
363	const char *regex = "msgctl.*IPC_SET.*return,failure.*Invalid argument";
364	FILE *pipefd = setup(fds, auclass);
365	ATF_REQUIRE_EQ(-1, msgctl(-1, IPC_SET, &msgbuff));
366	check_audit(fds, regex, pipefd);
367}
368
369ATF_TC_CLEANUP(msgctl_set_failure, tc)
370{
371	cleanup();
372}
373
374
375ATF_TC_WITH_CLEANUP(msgctl_illegal_command);
376ATF_TC_HEAD(msgctl_illegal_command, tc)
377{
378	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
379					"msgctl(2) call for illegal cmd value");
380}
381
382ATF_TC_BODY(msgctl_illegal_command, tc)
383{
384	/* Create a message queue and obtain the corresponding identifier */
385	ATF_REQUIRE((msqid = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR)) != -1);
386
387	const char *regex = "msgctl.*illegal command.*failur.*Invalid argument";
388	FILE *pipefd = setup(fds, auclass);
389	ATF_REQUIRE_EQ(-1, msgctl(msqid, -1, &msgbuff));
390	check_audit(fds, regex, pipefd);
391
392	/* Destroy the message queue with ID = msqid */
393	ATF_REQUIRE_EQ(0, msgctl(msqid, IPC_RMID, NULL));
394}
395
396ATF_TC_CLEANUP(msgctl_illegal_command, tc)
397{
398	cleanup();
399}
400
401
402ATF_TC_WITH_CLEANUP(shmget_success);
403ATF_TC_HEAD(shmget_success, tc)
404{
405	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
406					"shmget(2) call");
407}
408
409ATF_TC_BODY(shmget_success, tc)
410{
411	FILE *pipefd = setup(fds, auclass);
412	ATF_REQUIRE((shmid =
413		shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
414	/* Check the presence of shared memory ID in audit record */
415	snprintf(ipcregex, sizeof(ipcregex), "shmget.*ret.*success,%d", shmid);
416	check_audit(fds, ipcregex, pipefd);
417
418	/* Destroy the shared memory with ID = shmid */
419	ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL));
420}
421
422ATF_TC_CLEANUP(shmget_success, tc)
423{
424	cleanup();
425}
426
427
428ATF_TC_WITH_CLEANUP(shmget_failure);
429ATF_TC_HEAD(shmget_failure, tc)
430{
431	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
432					"shmget(2) call");
433}
434
435ATF_TC_BODY(shmget_failure, tc)
436{
437	const char *regex = "shmget.*return,failure.*No such file or directory";
438	FILE *pipefd = setup(fds, auclass);
439	ATF_REQUIRE_EQ(-1, shmget((key_t)(-1), 0, 0));
440	check_audit(fds, regex, pipefd);
441}
442
443ATF_TC_CLEANUP(shmget_failure, tc)
444{
445	cleanup();
446}
447
448
449ATF_TC_WITH_CLEANUP(shmat_success);
450ATF_TC_HEAD(shmat_success, tc)
451{
452	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
453					"shmat(2) call");
454}
455
456ATF_TC_BODY(shmat_success, tc)
457{
458	void *addr;
459	/* Create a shared memory segment and obtain the identifier */
460	ATF_REQUIRE((shmid =
461		shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
462
463	FILE *pipefd = setup(fds, auclass);
464	ATF_REQUIRE((intptr_t)(addr = shmat(shmid, NULL, 0)) != -1);
465
466	/* Check for shared memory ID and process address in record */
467	snprintf(ipcregex, sizeof(ipcregex), "shmat.*Shared Memory "
468			"IPC.*%d.*return,success", shmid);
469	check_audit(fds, ipcregex, pipefd);
470
471	/* Destroy the shared memory with ID = shmid */
472	ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL));
473}
474
475ATF_TC_CLEANUP(shmat_success, tc)
476{
477	cleanup();
478}
479
480
481ATF_TC_WITH_CLEANUP(shmat_failure);
482ATF_TC_HEAD(shmat_failure, tc)
483{
484	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
485					"shmat(2) call");
486}
487
488ATF_TC_BODY(shmat_failure, tc)
489{
490	const char *regex = "shmat.*Shared Memory IPC.*return,failure";
491	FILE *pipefd = setup(fds, auclass);
492	ATF_REQUIRE_EQ(-1, (intptr_t)shmat(-1, NULL, 0));
493	check_audit(fds, regex, pipefd);
494}
495
496ATF_TC_CLEANUP(shmat_failure, tc)
497{
498	cleanup();
499}
500
501
502ATF_TC_WITH_CLEANUP(shmdt_success);
503ATF_TC_HEAD(shmdt_success, tc)
504{
505	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
506					"shmdt(2) call");
507}
508
509ATF_TC_BODY(shmdt_success, tc)
510{
511	void *addr;
512	pid = getpid();
513	snprintf(ipcregex, sizeof(ipcregex), "shmdt.*%d.*return,success", pid);
514
515	/* Create a shared memory segment and obtain the identifier */
516	ATF_REQUIRE((shmid =
517		shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
518
519	/* Attach the shared memory to calling process's address space */
520	ATF_REQUIRE((intptr_t)(addr = shmat(shmid, NULL, 0)) != -1);
521
522	FILE *pipefd = setup(fds, auclass);
523	ATF_REQUIRE_EQ(0, shmdt(addr));
524	check_audit(fds, ipcregex, pipefd);
525
526	/* Destroy the shared memory with ID = shmid */
527	ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL));
528}
529
530ATF_TC_CLEANUP(shmdt_success, tc)
531{
532	cleanup();
533}
534
535
536ATF_TC_WITH_CLEANUP(shmdt_failure);
537ATF_TC_HEAD(shmdt_failure, tc)
538{
539	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
540					"shmdt(2) call");
541}
542
543ATF_TC_BODY(shmdt_failure, tc)
544{
545	const char *regex = "shmdt.*return,failure : Invalid argument";
546	FILE *pipefd = setup(fds, auclass);
547	ATF_REQUIRE_EQ(-1, shmdt(NULL));
548	check_audit(fds, regex, pipefd);
549}
550
551ATF_TC_CLEANUP(shmdt_failure, tc)
552{
553	cleanup();
554}
555
556
557ATF_TC_WITH_CLEANUP(shmctl_rmid_success);
558ATF_TC_HEAD(shmctl_rmid_success, tc)
559{
560	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
561					"shmctl(2) call for IPC_RMID command");
562}
563
564ATF_TC_BODY(shmctl_rmid_success, tc)
565{
566	/* Create a shared memory segment and obtain the identifier */
567	ATF_REQUIRE((shmid =
568		shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
569
570	FILE *pipefd = setup(fds, auclass);
571	ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL));
572	/* Check the presence of shmid and IPC_RMID in audit record */
573	snprintf(ipcregex, sizeof(ipcregex),
574		"shmctl.*IPC_RMID.*%d.*return,success", shmid);
575	check_audit(fds, ipcregex, pipefd);
576}
577
578ATF_TC_CLEANUP(shmctl_rmid_success, tc)
579{
580	cleanup();
581}
582
583
584ATF_TC_WITH_CLEANUP(shmctl_rmid_failure);
585ATF_TC_HEAD(shmctl_rmid_failure, tc)
586{
587	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
588					"shmctl(2) call for IPC_RMID command");
589}
590
591ATF_TC_BODY(shmctl_rmid_failure, tc)
592{
593	const char *regex = "shmctl.*IPC_RMID.*return,fail.*Invalid argument";
594	FILE *pipefd = setup(fds, auclass);
595	ATF_REQUIRE_EQ(-1, shmctl(-1, IPC_RMID, NULL));
596	check_audit(fds, regex, pipefd);
597}
598
599ATF_TC_CLEANUP(shmctl_rmid_failure, tc)
600{
601	cleanup();
602}
603
604
605ATF_TC_WITH_CLEANUP(shmctl_stat_success);
606ATF_TC_HEAD(shmctl_stat_success, tc)
607{
608	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
609					"shmctl(2) call for IPC_STAT command");
610}
611
612ATF_TC_BODY(shmctl_stat_success, tc)
613{
614	/* Create a shared memory segment and obtain the identifier */
615	ATF_REQUIRE((shmid =
616		shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
617
618	FILE *pipefd = setup(fds, auclass);
619	ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_STAT, &shmbuff));
620	/* Check if shared memory ID and IPC_STAT are present in audit record */
621	snprintf(ipcregex, sizeof(ipcregex),
622		"shmctl.*IPC_STAT.*%d.*return,success", shmid);
623	check_audit(fds, ipcregex, pipefd);
624
625	/* Destroy the shared memory with ID = shmid */
626	ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL));
627}
628
629ATF_TC_CLEANUP(shmctl_stat_success, tc)
630{
631	cleanup();
632}
633
634
635ATF_TC_WITH_CLEANUP(shmctl_stat_failure);
636ATF_TC_HEAD(shmctl_stat_failure, tc)
637{
638	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
639					"shmctl(2) call for IPC_STAT command");
640}
641
642ATF_TC_BODY(shmctl_stat_failure, tc)
643{
644	const char *regex = "shmctl.*IPC_STAT.*return,fail.*Invalid argument";
645	FILE *pipefd = setup(fds, auclass);
646	ATF_REQUIRE_EQ(-1, shmctl(-1, IPC_STAT, &shmbuff));
647	check_audit(fds, regex, pipefd);
648}
649
650ATF_TC_CLEANUP(shmctl_stat_failure, tc)
651{
652	cleanup();
653}
654
655
656ATF_TC_WITH_CLEANUP(shmctl_set_success);
657ATF_TC_HEAD(shmctl_set_success, tc)
658{
659	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
660					"shmctl(2) call for IPC_SET command");
661}
662
663ATF_TC_BODY(shmctl_set_success, tc)
664{
665	/* Create a shared memory segment and obtain the identifier */
666	ATF_REQUIRE((shmid =
667		shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
668	/* Fill up the shmbuff structure to be used with IPC_SET */
669	ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_STAT, &shmbuff));
670
671	FILE *pipefd = setup(fds, auclass);
672	ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_SET, &shmbuff));
673	/* Check the presence of shared memory ID in audit record */
674	snprintf(ipcregex, sizeof(ipcregex),
675		"shmctl.*IPC_SET.*%d.*return,success", msqid);
676	check_audit(fds, ipcregex, pipefd);
677
678	/* Destroy the shared memory with ID = shmid */
679	ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL));
680}
681
682ATF_TC_CLEANUP(shmctl_set_success, tc)
683{
684	cleanup();
685}
686
687
688ATF_TC_WITH_CLEANUP(shmctl_set_failure);
689ATF_TC_HEAD(shmctl_set_failure, tc)
690{
691	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
692					"shmctl(2) call for IPC_SET command");
693}
694
695ATF_TC_BODY(shmctl_set_failure, tc)
696{
697	const char *regex = "shmctl.*IPC_SET.*return,failure.*Invalid argument";
698	FILE *pipefd = setup(fds, auclass);
699	ATF_REQUIRE_EQ(-1, shmctl(-1, IPC_SET, &shmbuff));
700	check_audit(fds, regex, pipefd);
701}
702
703ATF_TC_CLEANUP(shmctl_set_failure, tc)
704{
705	cleanup();
706}
707
708
709ATF_TC_WITH_CLEANUP(shmctl_illegal_command);
710ATF_TC_HEAD(shmctl_illegal_command, tc)
711{
712	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
713					"shmctl(2) call for illegal cmd value");
714}
715
716ATF_TC_BODY(shmctl_illegal_command, tc)
717{
718	/* Create a shared memory segment and obtain the identifier */
719	ATF_REQUIRE((shmid =
720		shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
721
722	const char *regex = "shmctl.*illegal command.*fail.*Invalid argument";
723	FILE *pipefd = setup(fds, auclass);
724	ATF_REQUIRE_EQ(-1, shmctl(shmid, -1, &shmbuff));
725	check_audit(fds, regex, pipefd);
726
727	/* Destroy the shared memory with ID = shmid */
728	ATF_REQUIRE_EQ(0, shmctl(shmid, IPC_RMID, NULL));
729}
730
731ATF_TC_CLEANUP(shmctl_illegal_command, tc)
732{
733	cleanup();
734}
735
736
737ATF_TC_WITH_CLEANUP(semget_success);
738ATF_TC_HEAD(semget_success, tc)
739{
740	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
741					"semget(2) call");
742}
743
744ATF_TC_BODY(semget_success, tc)
745{
746	FILE *pipefd = setup(fds, auclass);
747	ATF_REQUIRE((semid =
748		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
749
750	/* Check the presence of semaphore set ID in audit record */
751	snprintf(ipcregex, sizeof(ipcregex),
752		"semget.*return,success,%d", semid);
753	check_audit(fds, ipcregex, pipefd);
754
755	/* Destroy the semaphore set with ID = semid */
756	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
757}
758
759ATF_TC_CLEANUP(semget_success, tc)
760{
761	cleanup();
762}
763
764
765ATF_TC_WITH_CLEANUP(semget_failure);
766ATF_TC_HEAD(semget_failure, tc)
767{
768	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
769					"semget(2) call");
770}
771
772ATF_TC_BODY(semget_failure, tc)
773{
774	pid = getpid();
775	snprintf(ipcregex, sizeof(ipcregex), "semget.*%d.*return,failure", pid);
776
777	FILE *pipefd = setup(fds, auclass);
778	/* Failure reason: nsems is a negative number */
779	ATF_REQUIRE_EQ(-1, semget(IPC_PRIVATE, -1, 0));
780	check_audit(fds, ipcregex, pipefd);
781}
782
783ATF_TC_CLEANUP(semget_failure, tc)
784{
785	cleanup();
786}
787
788
789ATF_TC_WITH_CLEANUP(semop_success);
790ATF_TC_HEAD(semop_success, tc)
791{
792	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
793					"semop(2) call");
794}
795
796ATF_TC_BODY(semop_success, tc)
797{
798	/* Create a semaphore set and obtain the set identifier */
799	ATF_REQUIRE((semid =
800		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
801
802	/* Initialize a sembuf structure to operate on semaphore set */
803	struct sembuf sop[1] = {{0, 1, 0}};
804	/* Check the presence of semaphore set ID in audit record */
805	snprintf(ipcregex, sizeof(ipcregex),
806		"semop.*Semaphore IPC.*%d.*return,success", semid);
807
808	FILE *pipefd = setup(fds, auclass);
809	ATF_REQUIRE_EQ(0, semop(semid, sop, sizeof(sop)/sizeof(struct sembuf)));
810	check_audit(fds, ipcregex, pipefd);
811
812	/* Destroy the semaphore set with ID = semid */
813	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
814}
815
816ATF_TC_CLEANUP(semop_success, tc)
817{
818	cleanup();
819}
820
821
822ATF_TC_WITH_CLEANUP(semop_failure);
823ATF_TC_HEAD(semop_failure, tc)
824{
825	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
826					"semop(2) call");
827}
828
829ATF_TC_BODY(semop_failure, tc)
830{
831	const char *regex = "semop.*0xffff.*return,failure : Invalid argument";
832	FILE *pipefd = setup(fds, auclass);
833	ATF_REQUIRE_EQ(-1, semop(-1, NULL, 0));
834	check_audit(fds, regex, pipefd);
835}
836
837ATF_TC_CLEANUP(semop_failure, tc)
838{
839	cleanup();
840}
841
842
843ATF_TC_WITH_CLEANUP(semctl_getval_success);
844ATF_TC_HEAD(semctl_getval_success, tc)
845{
846	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
847					"semctl(2) call for GETVAL command");
848}
849
850ATF_TC_BODY(semctl_getval_success, tc)
851{
852	/* Create a semaphore set and obtain the set identifier */
853	ATF_REQUIRE((semid =
854		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
855
856	FILE *pipefd = setup(fds, auclass);
857	ATF_REQUIRE_EQ(0, semctl(semid, 0, GETVAL));
858	/* Check the presence of semaphore ID and GETVAL in audit record */
859	snprintf(ipcregex, sizeof(ipcregex),
860		"semctl.*GETVAL.*%d.*return,success", semid);
861	check_audit(fds, ipcregex, pipefd);
862
863	/* Destroy the semaphore set with ID = semid */
864	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
865}
866
867ATF_TC_CLEANUP(semctl_getval_success, tc)
868{
869	cleanup();
870}
871
872
873ATF_TC_WITH_CLEANUP(semctl_getval_failure);
874ATF_TC_HEAD(semctl_getval_failure, tc)
875{
876	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
877					"semctl(2) call for GETVAL command");
878}
879
880ATF_TC_BODY(semctl_getval_failure, tc)
881{
882	const char *regex = "semctl.*GETVAL.*return,failure : Invalid argument";
883	FILE *pipefd = setup(fds, auclass);
884	ATF_REQUIRE_EQ(-1, semctl(-1, 0, GETVAL));
885	check_audit(fds, regex, pipefd);
886}
887
888ATF_TC_CLEANUP(semctl_getval_failure, tc)
889{
890	cleanup();
891}
892
893
894ATF_TC_WITH_CLEANUP(semctl_setval_success);
895ATF_TC_HEAD(semctl_setval_success, tc)
896{
897	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
898					"semctl(2) call for SETVAL command");
899}
900
901ATF_TC_BODY(semctl_setval_success, tc)
902{
903	/* Create a semaphore set and obtain the set identifier */
904	ATF_REQUIRE((semid =
905		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
906
907	semarg.val = 1;
908	FILE *pipefd = setup(fds, auclass);
909	ATF_REQUIRE_EQ(0, semctl(semid, 0, SETVAL, semarg));
910	/* Check the presence of semaphore ID and SETVAL in audit record */
911	snprintf(ipcregex, sizeof(ipcregex),
912		"semctl.*SETVAL.*%d.*return,success", semid);
913	check_audit(fds, ipcregex, pipefd);
914
915	/* Destroy the semaphore set with ID = semid */
916	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
917}
918
919ATF_TC_CLEANUP(semctl_setval_success, tc)
920{
921	cleanup();
922}
923
924
925ATF_TC_WITH_CLEANUP(semctl_setval_failure);
926ATF_TC_HEAD(semctl_setval_failure, tc)
927{
928	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
929					"semctl(2) call for SETVAL command");
930}
931
932ATF_TC_BODY(semctl_setval_failure, tc)
933{
934	const char *regex = "semctl.*SETVAL.*return,failure : Invalid argument";
935	FILE *pipefd = setup(fds, auclass);
936	ATF_REQUIRE_EQ(-1, semctl(-1, 0, SETVAL, semarg));
937	check_audit(fds, regex, pipefd);
938}
939
940ATF_TC_CLEANUP(semctl_setval_failure, tc)
941{
942	cleanup();
943}
944
945
946ATF_TC_WITH_CLEANUP(semctl_getpid_success);
947ATF_TC_HEAD(semctl_getpid_success, tc)
948{
949	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
950					"semctl(2) call for GETPID command");
951}
952
953ATF_TC_BODY(semctl_getpid_success, tc)
954{
955	/* Create a semaphore set and obtain the set identifier */
956	ATF_REQUIRE((semid =
957		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
958
959	FILE *pipefd = setup(fds, auclass);
960	ATF_REQUIRE_EQ(0, semctl(semid, 0, GETPID));
961	/* Check the presence of semaphore ID and GETVAL in audit record */
962	snprintf(ipcregex, sizeof(ipcregex),
963		"semctl.*GETPID.*%d.*return,success", semid);
964	check_audit(fds, ipcregex, pipefd);
965
966	/* Destroy the semaphore set with ID = semid */
967	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
968}
969
970ATF_TC_CLEANUP(semctl_getpid_success, tc)
971{
972	cleanup();
973}
974
975
976ATF_TC_WITH_CLEANUP(semctl_getpid_failure);
977ATF_TC_HEAD(semctl_getpid_failure, tc)
978{
979	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
980					"semctl(2) call for GETPID command");
981}
982
983ATF_TC_BODY(semctl_getpid_failure, tc)
984{
985	const char *regex = "semctl.*GETPID.*return,failure : Invalid argument";
986	FILE *pipefd = setup(fds, auclass);
987	ATF_REQUIRE_EQ(-1, semctl(-1, 0, GETPID));
988	check_audit(fds, regex, pipefd);
989}
990
991ATF_TC_CLEANUP(semctl_getpid_failure, tc)
992{
993	cleanup();
994}
995
996
997ATF_TC_WITH_CLEANUP(semctl_getncnt_success);
998ATF_TC_HEAD(semctl_getncnt_success, tc)
999{
1000	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1001					"semctl(2) call for GETNCNT command");
1002}
1003
1004ATF_TC_BODY(semctl_getncnt_success, tc)
1005{
1006	/* Create a semaphore set and obtain the set identifier */
1007	ATF_REQUIRE((semid =
1008		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
1009
1010	FILE *pipefd = setup(fds, auclass);
1011	ATF_REQUIRE_EQ(0, semctl(semid, 0, GETNCNT));
1012	/* Check the presence of semaphore ID and GETNCNT in audit record */
1013	snprintf(ipcregex, sizeof(ipcregex),
1014		"semctl.*GETNCNT.*%d.*return,success", semid);
1015	check_audit(fds, ipcregex, pipefd);
1016
1017	/* Destroy the semaphore set with ID = semid */
1018	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
1019}
1020
1021ATF_TC_CLEANUP(semctl_getncnt_success, tc)
1022{
1023	cleanup();
1024}
1025
1026
1027ATF_TC_WITH_CLEANUP(semctl_getncnt_failure);
1028ATF_TC_HEAD(semctl_getncnt_failure, tc)
1029{
1030	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1031					"semctl(2) call for GETNCNT command");
1032}
1033
1034ATF_TC_BODY(semctl_getncnt_failure, tc)
1035{
1036	const char *regex = "semctl.*GETNCNT.*return,failure.*Invalid argument";
1037	FILE *pipefd = setup(fds, auclass);
1038	ATF_REQUIRE_EQ(-1, semctl(-1, 0, GETNCNT));
1039	check_audit(fds, regex, pipefd);
1040}
1041
1042ATF_TC_CLEANUP(semctl_getncnt_failure, tc)
1043{
1044	cleanup();
1045}
1046
1047
1048ATF_TC_WITH_CLEANUP(semctl_getzcnt_success);
1049ATF_TC_HEAD(semctl_getzcnt_success, tc)
1050{
1051	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1052					"semctl(2) call for GETZCNT command");
1053}
1054
1055ATF_TC_BODY(semctl_getzcnt_success, tc)
1056{
1057	/* Create a semaphore set and obtain the set identifier */
1058	ATF_REQUIRE((semid =
1059		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
1060
1061	FILE *pipefd = setup(fds, auclass);
1062	ATF_REQUIRE_EQ(0, semctl(semid, 0, GETZCNT));
1063	/* Check the presence of semaphore ID and GETZCNT in audit record */
1064	snprintf(ipcregex, sizeof(ipcregex),
1065		"semctl.*GETZCNT.*%d.*return,success", semid);
1066	check_audit(fds, ipcregex, pipefd);
1067
1068	/* Destroy the semaphore set with ID = semid */
1069	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
1070}
1071
1072ATF_TC_CLEANUP(semctl_getzcnt_success, tc)
1073{
1074	cleanup();
1075}
1076
1077
1078ATF_TC_WITH_CLEANUP(semctl_getzcnt_failure);
1079ATF_TC_HEAD(semctl_getzcnt_failure, tc)
1080{
1081	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1082					"semctl(2) call for GETZCNT command");
1083}
1084
1085ATF_TC_BODY(semctl_getzcnt_failure, tc)
1086{
1087	const char *regex = "semctl.*GETZCNT.*return,failure.*Invalid argument";
1088	FILE *pipefd = setup(fds, auclass);
1089	ATF_REQUIRE_EQ(-1, semctl(-1, 0, GETZCNT));
1090	check_audit(fds, regex, pipefd);
1091}
1092
1093ATF_TC_CLEANUP(semctl_getzcnt_failure, tc)
1094{
1095	cleanup();
1096}
1097
1098
1099ATF_TC_WITH_CLEANUP(semctl_getall_success);
1100ATF_TC_HEAD(semctl_getall_success, tc)
1101{
1102	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1103					"semctl(2) call for GETALL command");
1104}
1105
1106ATF_TC_BODY(semctl_getall_success, tc)
1107{
1108	/* Create a semaphore set and obtain the set identifier */
1109	ATF_REQUIRE((semid =
1110		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
1111
1112	semarg.array = semvals;
1113	FILE *pipefd = setup(fds, auclass);
1114	ATF_REQUIRE(semctl(semid, 0, GETALL, semarg) != -1);
1115	/* Check the presence of semaphore ID and GETALL in audit record */
1116	snprintf(ipcregex, sizeof(ipcregex),
1117		"semctl.*GETALL.*%d.*return,success", semid);
1118	check_audit(fds, ipcregex, pipefd);
1119
1120	/* Destroy the semaphore set with ID = semid */
1121	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
1122}
1123
1124ATF_TC_CLEANUP(semctl_getall_success, tc)
1125{
1126	cleanup();
1127}
1128
1129
1130ATF_TC_WITH_CLEANUP(semctl_getall_failure);
1131ATF_TC_HEAD(semctl_getall_failure, tc)
1132{
1133	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1134					"semctl(2) call for GETALL command");
1135}
1136
1137ATF_TC_BODY(semctl_getall_failure, tc)
1138{
1139	const char *regex = "semctl.*GETALL.*return,failure : Invalid argument";
1140	FILE *pipefd = setup(fds, auclass);
1141	ATF_REQUIRE_EQ(-1, semctl(-1, 0, GETALL, semarg));
1142	check_audit(fds, regex, pipefd);
1143}
1144
1145ATF_TC_CLEANUP(semctl_getall_failure, tc)
1146{
1147	cleanup();
1148}
1149
1150
1151ATF_TC_WITH_CLEANUP(semctl_setall_success);
1152ATF_TC_HEAD(semctl_setall_success, tc)
1153{
1154	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1155					"semctl(2) call for SETALL command");
1156}
1157
1158ATF_TC_BODY(semctl_setall_success, tc)
1159{
1160	/* Create a semaphore set and obtain the set identifier */
1161	ATF_REQUIRE((semid =
1162		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
1163
1164	semarg.array = semvals;
1165	/* Initialize semvals to be used with SETALL */
1166	ATF_REQUIRE(semctl(semid, 0, GETALL, semarg) != -1);
1167
1168	FILE *pipefd = setup(fds, auclass);
1169	ATF_REQUIRE_EQ(0, semctl(semid, 0, SETALL, semarg));
1170	/* Check the presence of semaphore ID and SETALL in audit record */
1171	snprintf(ipcregex, sizeof(ipcregex),
1172		"semctl.*SETALL.*%d.*return,success", semid);
1173	check_audit(fds, ipcregex, pipefd);
1174
1175	/* Destroy the semaphore set with ID = semid */
1176	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
1177}
1178
1179ATF_TC_CLEANUP(semctl_setall_success, tc)
1180{
1181	cleanup();
1182}
1183
1184
1185ATF_TC_WITH_CLEANUP(semctl_setall_failure);
1186ATF_TC_HEAD(semctl_setall_failure, tc)
1187{
1188	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1189					"semctl(2) call for SETALL command");
1190}
1191
1192ATF_TC_BODY(semctl_setall_failure, tc)
1193{
1194	const char *regex = "semctl.*SETALL.*return,failure : Invalid argument";
1195	FILE *pipefd = setup(fds, auclass);
1196	ATF_REQUIRE_EQ(-1, semctl(-1, 0, SETALL, semarg));
1197	check_audit(fds, regex, pipefd);
1198}
1199
1200ATF_TC_CLEANUP(semctl_setall_failure, tc)
1201{
1202	cleanup();
1203}
1204
1205
1206ATF_TC_WITH_CLEANUP(semctl_stat_success);
1207ATF_TC_HEAD(semctl_stat_success, tc)
1208{
1209	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1210					"semctl(2) call for IPC_STAT command");
1211}
1212
1213ATF_TC_BODY(semctl_stat_success, tc)
1214{
1215	/* Create a semaphore set and obtain the set identifier */
1216	ATF_REQUIRE((semid =
1217		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
1218
1219	semarg.buf = &sembuff;
1220	FILE *pipefd = setup(fds, auclass);
1221	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_STAT, semarg));
1222	/* Check the presence of semaphore ID and IPC_STAT in audit record */
1223	snprintf(ipcregex, sizeof(ipcregex),
1224		"semctl.*IPC_STAT.*%d.*return,success", semid);
1225	check_audit(fds, ipcregex, pipefd);
1226
1227	/* Destroy the semaphore set with ID = semid */
1228	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
1229}
1230
1231ATF_TC_CLEANUP(semctl_stat_success, tc)
1232{
1233	cleanup();
1234}
1235
1236
1237ATF_TC_WITH_CLEANUP(semctl_stat_failure);
1238ATF_TC_HEAD(semctl_stat_failure, tc)
1239{
1240	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1241					"semctl(2) call for IPC_STAT command");
1242}
1243
1244ATF_TC_BODY(semctl_stat_failure, tc)
1245{
1246	const char *regex = "semctl.*IPC_STAT.*return,fail.*Invalid argument";
1247	FILE *pipefd = setup(fds, auclass);
1248	ATF_REQUIRE_EQ(-1, semctl(-1, 0, IPC_STAT, semarg));
1249	check_audit(fds, regex, pipefd);
1250}
1251
1252ATF_TC_CLEANUP(semctl_stat_failure, tc)
1253{
1254	cleanup();
1255}
1256
1257
1258ATF_TC_WITH_CLEANUP(semctl_set_success);
1259ATF_TC_HEAD(semctl_set_success, tc)
1260{
1261	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1262					"semctl(2) call for IPC_SET command");
1263}
1264
1265ATF_TC_BODY(semctl_set_success, tc)
1266{
1267	/* Create a semaphore set and obtain the set identifier */
1268	ATF_REQUIRE((semid =
1269		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
1270
1271	semarg.buf = &sembuff;
1272	/* Fill up the sembuff structure to be used with IPC_SET */
1273	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_STAT, semarg));
1274
1275	FILE *pipefd = setup(fds, auclass);
1276	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_SET, semarg));
1277	/* Check the presence of semaphore ID and IPC_SET in audit record */
1278	snprintf(ipcregex, sizeof(ipcregex),
1279		"semctl.*IPC_SET.*%d.*return,success", semid);
1280	check_audit(fds, ipcregex, pipefd);
1281
1282	/* Destroy the semaphore set with ID = semid */
1283	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
1284}
1285
1286ATF_TC_CLEANUP(semctl_set_success, tc)
1287{
1288	cleanup();
1289}
1290
1291
1292ATF_TC_WITH_CLEANUP(semctl_set_failure);
1293ATF_TC_HEAD(semctl_set_failure, tc)
1294{
1295	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1296					"semctl(2) call for IPC_SET command");
1297}
1298
1299ATF_TC_BODY(semctl_set_failure, tc)
1300{
1301	/* Create a semaphore set and obtain the set identifier */
1302	ATF_REQUIRE((semid =
1303		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
1304
1305	semarg.buf = &sembuff;
1306	/* Fill up the sembuff structure to be used with IPC_SET */
1307	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_STAT, semarg));
1308
1309	const char *regex = "semctl.*IPC_SET.*return,failure.*Invalid argument";
1310	FILE *pipefd = setup(fds, auclass);
1311	ATF_REQUIRE_EQ(-1, semctl(-1, 0, IPC_SET, semarg));
1312	check_audit(fds, regex, pipefd);
1313
1314	/* Destroy the semaphore set with ID = semid */
1315	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
1316}
1317
1318ATF_TC_CLEANUP(semctl_set_failure, tc)
1319{
1320	cleanup();
1321}
1322
1323
1324ATF_TC_WITH_CLEANUP(semctl_rmid_success);
1325ATF_TC_HEAD(semctl_rmid_success, tc)
1326{
1327	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1328					"semctl(2) call for IPC_RMID command");
1329}
1330
1331ATF_TC_BODY(semctl_rmid_success, tc)
1332{
1333	/* Create a semaphore set and obtain the set identifier */
1334	ATF_REQUIRE((semid =
1335		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
1336
1337	FILE *pipefd = setup(fds, auclass);
1338	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID, semarg));
1339	/* Check the presence of semaphore ID and IPC_RMID in audit record */
1340	snprintf(ipcregex, sizeof(ipcregex),
1341		"semctl.*IPC_RMID.*%d.*return,success", semid);
1342	check_audit(fds, ipcregex, pipefd);
1343}
1344
1345ATF_TC_CLEANUP(semctl_rmid_success, tc)
1346{
1347	cleanup();
1348}
1349
1350
1351ATF_TC_WITH_CLEANUP(semctl_rmid_failure);
1352ATF_TC_HEAD(semctl_rmid_failure, tc)
1353{
1354	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1355					"semctl(2) call for IPC_RMID command");
1356}
1357
1358ATF_TC_BODY(semctl_rmid_failure, tc)
1359{
1360	const char *regex = "semctl.*IPC_RMID.*return,fail.*Invalid argument";
1361	FILE *pipefd = setup(fds, auclass);
1362	ATF_REQUIRE_EQ(-1, semctl(-1, 0, IPC_RMID, semarg));
1363	check_audit(fds, regex, pipefd);
1364}
1365
1366ATF_TC_CLEANUP(semctl_rmid_failure, tc)
1367{
1368	cleanup();
1369}
1370
1371
1372ATF_TC_WITH_CLEANUP(semctl_illegal_command);
1373ATF_TC_HEAD(semctl_illegal_command, tc)
1374{
1375	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1376					"semctl(2) call for illegal cmd value");
1377}
1378
1379ATF_TC_BODY(semctl_illegal_command, tc)
1380{
1381	/* Create a semaphore set and obtain the set identifier */
1382	ATF_REQUIRE((semid =
1383		semget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR)) != -1);
1384
1385	const char *regex = "semctl.*illegal command.*fail.*Invalid argument";
1386	FILE *pipefd = setup(fds, auclass);
1387	ATF_REQUIRE_EQ(-1, semctl(semid, 0, -1));
1388	check_audit(fds, regex, pipefd);
1389
1390	/* Destroy the semaphore set with ID = semid */
1391	ATF_REQUIRE_EQ(0, semctl(semid, 0, IPC_RMID));
1392}
1393
1394ATF_TC_CLEANUP(semctl_illegal_command, tc)
1395{
1396	cleanup();
1397}
1398
1399
1400ATF_TC_WITH_CLEANUP(shm_open_success);
1401ATF_TC_HEAD(shm_open_success, tc)
1402{
1403	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1404					"shm_open(2) call");
1405}
1406
1407ATF_TC_BODY(shm_open_success, tc)
1408{
1409	pid = getpid();
1410	snprintf(ipcregex, sizeof(ipcregex), "shm_open.*%d.*ret.*success", pid);
1411
1412	FILE *pipefd = setup(fds, auclass);
1413	ATF_REQUIRE(shm_open(SHM_ANON, O_CREAT | O_TRUNC | O_RDWR, 0600) != -1);
1414	check_audit(fds, ipcregex, pipefd);
1415}
1416
1417ATF_TC_CLEANUP(shm_open_success, tc)
1418{
1419	cleanup();
1420}
1421
1422
1423ATF_TC_WITH_CLEANUP(shm_open_failure);
1424ATF_TC_HEAD(shm_open_failure, tc)
1425{
1426	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1427					"shm_open(2) call");
1428}
1429
1430ATF_TC_BODY(shm_open_failure, tc)
1431{
1432	const char *regex = "shm_open.*fileforaudit.*return,failure";
1433	FILE *pipefd = setup(fds, auclass);
1434	/* Failure reason: File does not exist */
1435	ATF_REQUIRE_EQ(-1, shm_open(path, O_TRUNC | O_RDWR, 0600));
1436	check_audit(fds, regex, pipefd);
1437}
1438
1439ATF_TC_CLEANUP(shm_open_failure, tc)
1440{
1441	cleanup();
1442}
1443
1444
1445ATF_TC_WITH_CLEANUP(shm_unlink_success);
1446ATF_TC_HEAD(shm_unlink_success, tc)
1447{
1448	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1449					"shm_unlink(2) call");
1450}
1451
1452ATF_TC_BODY(shm_unlink_success, tc)
1453{
1454	/* Build an absolute path to a file in the test-case directory */
1455	char dirpath[PATH_MAX];
1456	ATF_REQUIRE(getcwd(dirpath, sizeof(dirpath)) != NULL);
1457	strlcat(dirpath, path, sizeof(dirpath));
1458	ATF_REQUIRE(shm_open(dirpath, O_CREAT | O_TRUNC | O_RDWR, 0600) != -1);
1459
1460	const char *regex = "shm_unlink.*fileforaudit.*return,success";
1461	FILE *pipefd = setup(fds, auclass);
1462	ATF_REQUIRE_EQ(0, shm_unlink(dirpath));
1463	check_audit(fds, regex, pipefd);
1464}
1465
1466ATF_TC_CLEANUP(shm_unlink_success, tc)
1467{
1468	cleanup();
1469}
1470
1471
1472ATF_TC_WITH_CLEANUP(shm_unlink_failure);
1473ATF_TC_HEAD(shm_unlink_failure, tc)
1474{
1475	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1476					"shm_unlink(2) call");
1477}
1478
1479ATF_TC_BODY(shm_unlink_failure, tc)
1480{
1481	const char *regex = "shm_unlink.*fileforaudit.*return,failure";
1482	FILE *pipefd = setup(fds, auclass);
1483	ATF_REQUIRE_EQ(-1, shm_unlink(path));
1484	check_audit(fds, regex, pipefd);
1485}
1486
1487ATF_TC_CLEANUP(shm_unlink_failure, tc)
1488{
1489	cleanup();
1490}
1491
1492
1493ATF_TC_WITH_CLEANUP(pipe_success);
1494ATF_TC_HEAD(pipe_success, tc)
1495{
1496	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1497					"pipe(2) call");
1498}
1499
1500ATF_TC_BODY(pipe_success, tc)
1501{
1502	int filedesc[2];
1503	pid = getpid();
1504	snprintf(ipcregex, sizeof(ipcregex), "pipe.*%d.*return,success", pid);
1505	FILE *pipefd = setup(fds, auclass);
1506	ATF_REQUIRE_EQ(0, pipe(filedesc));
1507	check_audit(fds, ipcregex, pipefd);
1508
1509	close(filedesc[0]);
1510	close(filedesc[1]);
1511}
1512
1513ATF_TC_CLEANUP(pipe_success, tc)
1514{
1515	cleanup();
1516}
1517
1518
1519ATF_TC_WITH_CLEANUP(pipe_failure);
1520ATF_TC_HEAD(pipe_failure, tc)
1521{
1522	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1523					"pipe(2) call");
1524}
1525
1526ATF_TC_BODY(pipe_failure, tc)
1527{
1528	pid = getpid();
1529	snprintf(ipcregex, sizeof(ipcregex), "pipe.*%d.*return.failure", pid);
1530
1531	FILE *pipefd = setup(fds, auclass);
1532	ATF_REQUIRE_EQ(-1, pipe(NULL));
1533	check_audit(fds, ipcregex, pipefd);
1534}
1535
1536ATF_TC_CLEANUP(pipe_failure, tc)
1537{
1538	cleanup();
1539}
1540
1541
1542ATF_TC_WITH_CLEANUP(posix_openpt_success);
1543ATF_TC_HEAD(posix_openpt_success, tc)
1544{
1545	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1546					"posix_openpt(2) call");
1547}
1548
1549ATF_TC_BODY(posix_openpt_success, tc)
1550{
1551	int filedesc;
1552	FILE *pipefd = setup(fds, auclass);
1553	ATF_REQUIRE((filedesc = posix_openpt(O_RDWR | O_NOCTTY)) != -1);
1554	/* Check for the presence of filedesc in the audit record */
1555	snprintf(ipcregex, sizeof(ipcregex),
1556		"posix_openpt.*return,success,%d", filedesc);
1557	check_audit(fds, ipcregex, pipefd);
1558	close(filedesc);
1559}
1560
1561ATF_TC_CLEANUP(posix_openpt_success, tc)
1562{
1563	cleanup();
1564}
1565
1566
1567ATF_TC_WITH_CLEANUP(posix_openpt_failure);
1568ATF_TC_HEAD(posix_openpt_failure, tc)
1569{
1570	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1571					"posix_openpt(2) call");
1572}
1573
1574ATF_TC_BODY(posix_openpt_failure, tc)
1575{
1576	const char *regex = "posix_openpt.*return,failure : Invalid argument";
1577	FILE *pipefd = setup(fds, auclass);
1578	ATF_REQUIRE_EQ(-1, posix_openpt(-1));
1579	check_audit(fds, regex, pipefd);
1580}
1581
1582ATF_TC_CLEANUP(posix_openpt_failure, tc)
1583{
1584	cleanup();
1585}
1586
1587
1588ATF_TP_ADD_TCS(tp)
1589{
1590	ATF_TP_ADD_TC(tp, msgget_success);
1591	ATF_TP_ADD_TC(tp, msgget_failure);
1592	ATF_TP_ADD_TC(tp, msgsnd_success);
1593	ATF_TP_ADD_TC(tp, msgsnd_failure);
1594	ATF_TP_ADD_TC(tp, msgrcv_success);
1595	ATF_TP_ADD_TC(tp, msgrcv_failure);
1596
1597	ATF_TP_ADD_TC(tp, msgctl_rmid_success);
1598	ATF_TP_ADD_TC(tp, msgctl_rmid_failure);
1599	ATF_TP_ADD_TC(tp, msgctl_stat_success);
1600	ATF_TP_ADD_TC(tp, msgctl_stat_failure);
1601	ATF_TP_ADD_TC(tp, msgctl_set_success);
1602	ATF_TP_ADD_TC(tp, msgctl_set_failure);
1603	ATF_TP_ADD_TC(tp, msgctl_illegal_command);
1604
1605	ATF_TP_ADD_TC(tp, shmget_success);
1606	ATF_TP_ADD_TC(tp, shmget_failure);
1607	ATF_TP_ADD_TC(tp, shmat_success);
1608	ATF_TP_ADD_TC(tp, shmat_failure);
1609	ATF_TP_ADD_TC(tp, shmdt_success);
1610	ATF_TP_ADD_TC(tp, shmdt_failure);
1611
1612	ATF_TP_ADD_TC(tp, shmctl_rmid_success);
1613	ATF_TP_ADD_TC(tp, shmctl_rmid_failure);
1614	ATF_TP_ADD_TC(tp, shmctl_stat_success);
1615	ATF_TP_ADD_TC(tp, shmctl_stat_failure);
1616	ATF_TP_ADD_TC(tp, shmctl_set_success);
1617	ATF_TP_ADD_TC(tp, shmctl_set_failure);
1618	ATF_TP_ADD_TC(tp, shmctl_illegal_command);
1619
1620	ATF_TP_ADD_TC(tp, semget_success);
1621	ATF_TP_ADD_TC(tp, semget_failure);
1622	ATF_TP_ADD_TC(tp, semop_success);
1623	ATF_TP_ADD_TC(tp, semop_failure);
1624
1625	ATF_TP_ADD_TC(tp, semctl_getval_success);
1626	ATF_TP_ADD_TC(tp, semctl_getval_failure);
1627	ATF_TP_ADD_TC(tp, semctl_setval_success);
1628	ATF_TP_ADD_TC(tp, semctl_setval_failure);
1629	ATF_TP_ADD_TC(tp, semctl_getpid_success);
1630	ATF_TP_ADD_TC(tp, semctl_getpid_failure);
1631	ATF_TP_ADD_TC(tp, semctl_getncnt_success);
1632	ATF_TP_ADD_TC(tp, semctl_getncnt_failure);
1633	ATF_TP_ADD_TC(tp, semctl_getzcnt_success);
1634	ATF_TP_ADD_TC(tp, semctl_getzcnt_failure);
1635	ATF_TP_ADD_TC(tp, semctl_getall_success);
1636	ATF_TP_ADD_TC(tp, semctl_getall_failure);
1637	ATF_TP_ADD_TC(tp, semctl_setall_success);
1638	ATF_TP_ADD_TC(tp, semctl_setall_failure);
1639	ATF_TP_ADD_TC(tp, semctl_stat_success);
1640	ATF_TP_ADD_TC(tp, semctl_stat_failure);
1641	ATF_TP_ADD_TC(tp, semctl_set_success);
1642	ATF_TP_ADD_TC(tp, semctl_set_failure);
1643	ATF_TP_ADD_TC(tp, semctl_rmid_success);
1644	ATF_TP_ADD_TC(tp, semctl_rmid_failure);
1645	ATF_TP_ADD_TC(tp, semctl_illegal_command);
1646
1647	ATF_TP_ADD_TC(tp, shm_open_success);
1648	ATF_TP_ADD_TC(tp, shm_open_failure);
1649	ATF_TP_ADD_TC(tp, shm_unlink_success);
1650	ATF_TP_ADD_TC(tp, shm_unlink_failure);
1651
1652	ATF_TP_ADD_TC(tp, pipe_success);
1653	ATF_TP_ADD_TC(tp, pipe_failure);
1654	ATF_TP_ADD_TC(tp, posix_openpt_success);
1655	ATF_TP_ADD_TC(tp, posix_openpt_failure);
1656
1657	return (atf_no_error());
1658}
1659