1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) International Business Machines Corp., 2001 4 * 03/2001 - Written by Wayne Boyer 5 * Copyright (c) 2018 Cyril Hrubis <chrubis@suse.cz> 6 */ 7 8/* 9 * Test that IPC_STAT command succeeds and the buffer is filled with 10 * correct data. 11 */ 12#include <errno.h> 13 14#include "tst_test.h" 15#include "tst_safe_sysv_ipc.h" 16#include "libnewipc.h" 17 18static int msg_id = -1; 19static time_t creat_time; 20static key_t msgkey; 21static uid_t uid; 22static gid_t gid; 23unsigned short mode = 0660; 24 25static void verify_msgctl(void) 26{ 27 struct msqid_ds buf; 28 29 memset(&buf, 'a', sizeof(buf)); 30 TEST(msgctl(msg_id, IPC_STAT, &buf)); 31 32 if (TST_RET != 0) { 33 tst_res(TFAIL | TTERRNO, "msgctl() returned %li", TST_RET); 34 return; 35 } 36 37 tst_res(TPASS, "msgctl(IPC_STAT)"); 38 39 if (buf.msg_stime == 0) 40 tst_res(TPASS, "msg_stime = 0"); 41 else 42 tst_res(TFAIL, "msg_stime = %lu", (unsigned long)buf.msg_stime); 43 44 if (buf.msg_rtime == 0) 45 tst_res(TPASS, "msg_rtime = 0"); 46 else 47 tst_res(TFAIL, "msg_rtime = %lu", (unsigned long)buf.msg_rtime); 48 49 if (buf.msg_ctime <= creat_time && buf.msg_ctime >= creat_time - 2) { 50 tst_res(TPASS, "msg_ctime = %lu, expected %lu", 51 (unsigned long)buf.msg_ctime, (unsigned long)creat_time); 52 } else { 53 tst_res(TFAIL, "msg_ctime = %lu, expected %lu", 54 (unsigned long)buf.msg_ctime, (unsigned long)creat_time); 55 } 56 57 if (buf.msg_qnum == 0) 58 tst_res(TPASS, "msg_qnum = 0"); 59 else 60 tst_res(TFAIL, "msg_qnum = %li", (long)buf.msg_qnum); 61 62 if (buf.msg_qbytes > 0) 63 tst_res(TPASS, "msg_qbytes = %li", (long)buf.msg_qbytes); 64 else 65 tst_res(TFAIL, "msg_qbytes = %li", (long)buf.msg_qbytes); 66 67 if (buf.msg_lspid == 0) 68 tst_res(TPASS, "msg_lspid = 0"); 69 else 70 tst_res(TFAIL, "msg_lspid = %u", (unsigned)buf.msg_lspid); 71 72 if (buf.msg_lrpid == 0) 73 tst_res(TPASS, "msg_lrpid = 0"); 74 else 75 tst_res(TFAIL, "msg_lrpid = %u", (unsigned)buf.msg_lrpid); 76 77 if (buf.msg_perm.__key == msgkey) { 78 tst_res(TPASS, "msg_perm.__key == %u", (unsigned)msgkey); 79 } else { 80 tst_res(TFAIL, "msg_perm.__key == %u, expected %u", 81 (unsigned)buf.msg_perm.__key, (unsigned)msgkey); 82 } 83 84 if (buf.msg_perm.uid == uid) { 85 tst_res(TPASS, "msg_perm.uid = %u", (unsigned)uid); 86 } else { 87 tst_res(TFAIL, "msg_perm.uid = %u, expected %u", 88 (unsigned)buf.msg_perm.uid, (unsigned)uid); 89 } 90 91 if (buf.msg_perm.gid == gid) { 92 tst_res(TPASS, "msg_perm.gid = %u", (unsigned)gid); 93 } else { 94 tst_res(TFAIL, "msg_perm.gid = %u, expected %u", 95 (unsigned)buf.msg_perm.gid, (unsigned)gid); 96 } 97 98 if (buf.msg_perm.cuid == uid) { 99 tst_res(TPASS, "msg_perm.cuid = %u", (unsigned)uid); 100 } else { 101 tst_res(TFAIL, "msg_perm.cuid = %u, expected %u", 102 (unsigned)buf.msg_perm.cuid, (unsigned)uid); 103 } 104 105 if (buf.msg_perm.cgid == gid) { 106 tst_res(TPASS, "msg_perm.cgid = %u", (unsigned)gid); 107 } else { 108 tst_res(TFAIL, "msg_perm.cgid = %u, expected %u", 109 (unsigned)buf.msg_perm.cgid, (unsigned)gid); 110 } 111 112 if ((buf.msg_perm.mode & MODE_MASK) == (mode & MODE_MASK)) { 113 tst_res(TPASS, "msg_perm.mode = 0%ho", mode & MODE_MASK); 114 } else { 115 tst_res(TFAIL, "msg_perm.mode = 0%ho, expected %hx", 116 buf.msg_perm.mode, (mode & MODE_MASK)); 117 } 118} 119 120static void setup(void) 121{ 122 msgkey = GETIPCKEY(); 123 124 msg_id = SAFE_MSGGET(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW | mode); 125 time(&creat_time); 126 127 uid = geteuid(); 128 gid = getegid(); 129} 130 131static void cleanup(void) 132{ 133 if (msg_id >= 0) 134 SAFE_MSGCTL(msg_id, IPC_RMID, NULL); 135} 136 137static struct tst_test test = { 138 .setup = setup, 139 .cleanup = cleanup, 140 .test_all = verify_msgctl, 141 .needs_tmpdir = 1 142}; 143