1 /*
2 * Copyright (c) 1993 Ulrich Pegelow <pegelow@moorea.uni-muenster.de>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 2003-2006 Roland McGrath <roland@redhat.com>
7 * Copyright (c) 2006-2015 Dmitry V. Levin <ldv@strace.io>
8 * Copyright (c) 2015-2021 The strace developers.
9 * All rights reserved.
10 *
11 * SPDX-License-Identifier: LGPL-2.1-or-later
12 */
13
14 #include "defs.h"
15
16 #include DEF_MPERS_TYPE(msqid_ds_t)
17
18 #include "ipc_defs.h"
19
20 #include MSG_H_PROVIDER
21 typedef struct NAME_OF_STRUCT_MSQID_DS msqid_ds_t;
22
23 #include MPERS_DEFS
24
25 #include "xlat/msgctl_flags.h"
26
27 #define key NAME_OF_STRUCT_IPC_PERM_KEY
28
29 static void
30 print_ipc_perm(const typeof_field(msqid_ds_t, msg_perm) *const p,
31 const unsigned int cmd)
32 {
33 tprint_struct_begin();
34 PRINT_FIELD_ID(*p, uid);
35 tprint_struct_next();
36 PRINT_FIELD_ID(*p, gid);
37 tprint_struct_next();
38 PRINT_FIELD_OBJ_U(*p, mode, print_numeric_ll_umode_t);
39 if (cmd != IPC_SET) {
40 tprint_struct_next();
41 PRINT_FIELD_U(*p, key);
42 tprint_struct_next();
43 PRINT_FIELD_ID(*p, cuid);
44 tprint_struct_next();
45 PRINT_FIELD_ID(*p, cgid);
46 }
47 tprint_struct_end();
48 }
49
50 static void
51 print_msqid_ds(struct tcb *const tcp, const kernel_ulong_t addr,
52 const unsigned int cmd)
53 {
54 msqid_ds_t msqid_ds;
55
56 if (umove_or_printaddr(tcp, addr, &msqid_ds))
57 return;
58
59 tprint_struct_begin();
60 PRINT_FIELD_OBJ_PTR(msqid_ds, msg_perm, print_ipc_perm, cmd);
61 if (cmd != IPC_SET) {
62 tprint_struct_next();
63 PRINT_FIELD_U(msqid_ds, msg_stime);
64 tprint_struct_next();
65 PRINT_FIELD_U(msqid_ds, msg_rtime);
66 tprint_struct_next();
67 PRINT_FIELD_U(msqid_ds, msg_ctime);
68 tprint_struct_next();
69 PRINT_FIELD_U(msqid_ds, msg_qnum);
70 }
71 tprint_struct_next();
72 PRINT_FIELD_U(msqid_ds, msg_qbytes);
73 if (cmd != IPC_SET) {
74 tprint_struct_next();
75 PRINT_FIELD_D(msqid_ds, msg_lspid);
76 tprint_struct_next();
77 PRINT_FIELD_D(msqid_ds, msg_lrpid);
78 }
79 tprint_struct_end();
80 }
81
82 static void
83 print_msginfo(struct tcb *const tcp, const kernel_ulong_t addr,
84 const unsigned int cmd)
85 {
86 struct msginfo info;
87
88 if (umove_or_printaddr(tcp, addr, &info))
89 return;
90
91 tprint_struct_begin();
92 PRINT_FIELD_D(info, msgpool);
93 tprint_struct_next();
94 PRINT_FIELD_D(info, msgmap);
95 tprint_struct_next();
96 PRINT_FIELD_D(info, msgmax);
97 tprint_struct_next();
98 PRINT_FIELD_D(info, msgmnb);
99 tprint_struct_next();
100 PRINT_FIELD_D(info, msgmni);
101 tprint_struct_next();
102 PRINT_FIELD_D(info, msgssz);
103 tprint_struct_next();
104 PRINT_FIELD_D(info, msgtql);
105 tprint_struct_next();
106 PRINT_FIELD_U(info, msgseg);
107 tprint_struct_end();
108 }
109
110 SYS_FUNC(msgctl)
111 {
112 const kernel_ulong_t addr = tcp->u_arg[indirect_ipccall(tcp) ? 3 : 2];
113 unsigned int cmd = tcp->u_arg[1];
114
115 /* TODO: We don't properly decode old compat ipc calls. */
116 if (cmd & IPC_64)
117 cmd &= ~IPC_64;
118
119 if (entering(tcp)) {
120 /* msqid */
121 PRINT_VAL_D((int) tcp->u_arg[0]);
122 tprint_arg_next();
123
124 /* cmd */
125 PRINTCTL(msgctl_flags, tcp->u_arg[1], "MSG_???");
126 tprint_arg_next();
127
128 switch (cmd) {
129 case IPC_SET:
130 /* buf */
131 print_msqid_ds(tcp, addr, cmd);
132 return RVAL_DECODED;
133
134 case IPC_STAT:
135 case MSG_STAT:
136 case MSG_STAT_ANY:
137 case IPC_INFO:
138 case MSG_INFO:
139 /* decode on exiting */
140 break;
141
142 default:
143 /* buf */
144 printaddr(addr);
145 return RVAL_DECODED;
146 }
147 } else {
148 switch (cmd) {
149 case IPC_STAT:
150 case MSG_STAT:
151 case MSG_STAT_ANY:
152 /* buf */
153 print_msqid_ds(tcp, addr, cmd);
154 break;
155
156 case IPC_INFO:
157 case MSG_INFO:
158 /* buf */
159 print_msginfo(tcp, addr, cmd);
160 break;
161 }
162 }
163 return 0;
164 }