1 /* 2 * Copyright (c) 2015 Elvira Khabirova <lineprinter0 (at) gmail.com> 3 * Copyright (c) 2015-2016 Dmitry V. Levin <ldv (at) altlinux.org> 4 * Copyright (c) 2015-2018 The strace developers. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "tests.h" 31 #include <errno.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <sys/shm.h> 35 36 #ifndef SHM_HUGE_SHIFT 37 # define SHM_HUGE_SHIFT 26 38 #endif 39 40 #ifndef SHM_HUGE_MASK 41 # define SHM_HUGE_MASK 0x3f 42 #endif 43 44 #ifndef SHM_STAT_ANY 45 # define SHM_STAT_ANY 15 46 #endif 47 48 #include "xlat.h" 49 #include "xlat/shm_resource_flags.h" 50 51 #if XLAT_RAW 52 # define str_ipc_flags "0x2ce1e00" 53 # define str_shm_huge "21<<26" 54 # define str_ipc_private "0" 55 # define str_ipc_rmid "0" 56 # define str_ipc_set "0x1" 57 # define str_ipc_stat "0x2" 58 # define str_shm_stat "0xd" 59 # define str_shm_info "0xe" 60 # define str_shm_stat_any "0xf" 61 # define str_ipc_64 "0x100" 62 # define str_bogus_cmd "0xdefaced2" 63 #elif XLAT_VERBOSE 64 # define str_ipc_flags \ 65 "0x2ce1e00 /\\* IPC_CREAT\\|IPC_EXCL\\|SHM_HUGETLB\\|SHM_NORESERVE" \ 66 "\\|0x2ce0000 \\*/" 67 # define str_shm_huge "21<<26 /\\* SHM_HUGE_SHIFT \\*/" 68 # define str_ipc_private "0 /\\* IPC_PRIVATE \\*/" 69 # define str_ipc_rmid "0 /\\* IPC_RMID \\*/" 70 # define str_ipc_set "0x1 /\\* IPC_SET \\*/" 71 # define str_ipc_stat "0x2 /\\* IPC_STAT \\*/" 72 # define str_shm_stat "0xd /\\* SHM_STAT \\*/" 73 # define str_shm_info "0xe /\\* SHM_INFO \\*/" 74 # define str_shm_stat_any "0xf /\\* SHM_STAT_ANY \\*/" 75 # define str_ipc_64 "0x100 /\\* IPC_64 \\*/" 76 # define str_bogus_cmd "0xdefaced2 /\\* SHM_\\?\\?\\? \\*/" 77 #else 78 # define str_ipc_flags \ 79 "IPC_CREAT\\|IPC_EXCL\\|SHM_HUGETLB\\|SHM_NORESERVE\\|0x2ce0000" 80 # define str_shm_huge "21<<SHM_HUGE_SHIFT" 81 # define str_ipc_private "IPC_PRIVATE" 82 # define str_ipc_rmid "IPC_RMID" 83 # define str_ipc_set "IPC_SET" 84 # define str_ipc_stat "IPC_STAT" 85 # define str_shm_stat "SHM_STAT" 86 # define str_shm_info "SHM_INFO" 87 # define str_shm_stat_any "SHM_STAT_ANY" 88 # define str_ipc_64 "IPC_64" 89 # define str_bogus_cmd "0xdefaced2 /\\* SHM_\\?\\?\\? \\*/" 90 #endif 91 92 static int id = -1; 93 94 static void 95 cleanup(void) 96 { 97 shmctl(id, IPC_RMID, NULL); 98 printf("shmctl\\(%d, (%s\\|)?%s, NULL\\) = 0\n", 99 id, str_ipc_64, str_ipc_rmid); 100 id = -1; 101 } 102 103 int 104 main(void) 105 { 106 static const key_t private_key = 107 (key_t) (0xffffffff00000000ULL | IPC_PRIVATE); 108 static const key_t bogus_key = (key_t) 0xeca86420fdb97531ULL; 109 static const int bogus_id = 0xdefaced1; 110 static const int bogus_cmd = 0xdefaced2; 111 static void * const bogus_addr = (void *) -1L; 112 static const size_t bogus_size = 113 /* 114 * musl sets size to SIZE_MAX if size argument is greater than 115 * PTRDIFF_MAX - musl/src/ipc/shmget.c 116 */ 117 #ifdef __GLIBC__ 118 (size_t) 0xdec0ded1dec0ded2ULL; 119 #else 120 (size_t) 0x1e55c0de5dec0dedULL; 121 #endif 122 static const unsigned int bogus_ipc_shm_flags = 123 IPC_CREAT | IPC_EXCL | SHM_HUGETLB | SHM_NORESERVE; 124 static const unsigned int huge_mask = SHM_HUGE_MASK << SHM_HUGE_SHIFT; 125 static const unsigned int huge_flags = 21 << SHM_HUGE_SHIFT; 126 int bogus_flags; 127 int rc; 128 struct shmid_ds ds; 129 130 rc = shmget(bogus_key, bogus_size, 0); 131 printf("shmget\\(%#llx, %zu, 000\\) = %s\n", 132 zero_extend_signed_to_ull(bogus_key), bogus_size, 133 sprintrc_grep(rc)); 134 135 rc = shmget(bogus_key, bogus_size, huge_flags); 136 printf("shmget\\(%#llx, %zu, %s\\|%#03o\\) = %s\n", 137 zero_extend_signed_to_ull(bogus_key), bogus_size, 138 str_shm_huge, 0, sprintrc_grep(rc)); 139 140 bogus_flags = 0xface1e55 & ~(bogus_ipc_shm_flags | huge_mask); 141 rc = shmget(bogus_key, bogus_size, bogus_flags); 142 printf("shmget\\(%#llx, %zu, %#x\\|%#03o\\) = %s\n", 143 zero_extend_signed_to_ull(bogus_key), bogus_size, 144 bogus_flags & ~0777, 145 bogus_flags & 0777, sprintrc_grep(rc)); 146 147 bogus_flags |= bogus_ipc_shm_flags; 148 rc = shmget(bogus_key, bogus_size, bogus_flags); 149 printf("shmget\\(%#llx, %zu, %s\\|%#03o\\) = %s\n", 150 zero_extend_signed_to_ull(bogus_key), bogus_size, 151 str_ipc_flags, 152 bogus_flags & 0777, sprintrc_grep(rc)); 153 154 bogus_flags |= huge_flags; 155 rc = shmget(bogus_key, bogus_size, bogus_flags); 156 printf("shmget\\(%#llx, %zu, %s\\|%s\\|%#03o\\) = %s\n", 157 zero_extend_signed_to_ull(bogus_key), bogus_size, 158 str_ipc_flags, str_shm_huge, 159 bogus_flags & 0777, sprintrc_grep(rc)); 160 161 bogus_flags &= ~bogus_ipc_shm_flags; 162 rc = shmget(bogus_key, bogus_size, bogus_flags); 163 printf("shmget\\(%#llx, %zu, %#x\\|%s\\|%#03o\\) = %s\n", 164 zero_extend_signed_to_ull(bogus_key), bogus_size, 165 bogus_flags & ~(0777 | huge_mask), 166 str_shm_huge, 167 bogus_flags & 0777, sprintrc_grep(rc)); 168 169 id = shmget(private_key, 1, 0600); 170 if (id < 0) 171 perror_msg_and_skip("shmget"); 172 printf("shmget\\(%s, 1, 0600\\) = %d\n", str_ipc_private, id); 173 atexit(cleanup); 174 175 rc = shmctl(bogus_id, bogus_cmd, NULL); 176 printf("shmctl\\(%d, (%s\\|)?%s, NULL\\) = %s\n", 177 bogus_id, str_ipc_64, str_bogus_cmd, sprintrc_grep(rc)); 178 179 rc = shmctl(bogus_id, IPC_STAT, bogus_addr); 180 printf("shmctl\\(%d, (%s\\|)?%s, %p\\) = %s\n", 181 bogus_id, str_ipc_64, str_ipc_stat, bogus_addr, 182 sprintrc_grep(rc)); 183 184 if (shmctl(id, IPC_STAT, &ds)) 185 perror_msg_and_skip("shmctl IPC_STAT"); 186 printf("shmctl\\(%d, (%s\\|)?%s, \\{shm_perm=\\{uid=%u, gid=%u, " 187 "mode=%#o, key=%u, cuid=%u, cgid=%u\\}, shm_segsz=%u, shm_cpid=%u, " 188 "shm_lpid=%u, shm_nattch=%u, shm_atime=%u, shm_dtime=%u, " 189 "shm_ctime=%u\\}\\) = 0\n", 190 id, str_ipc_64, str_ipc_stat, 191 (unsigned) ds.shm_perm.uid, (unsigned) ds.shm_perm.gid, 192 (unsigned) ds.shm_perm.mode, (unsigned) ds.shm_perm.__key, 193 (unsigned) ds.shm_perm.cuid, (unsigned) ds.shm_perm.cgid, 194 (unsigned) ds.shm_segsz, (unsigned) ds.shm_cpid, 195 (unsigned) ds.shm_lpid, (unsigned) ds.shm_nattch, 196 (unsigned) ds.shm_atime, (unsigned) ds.shm_dtime, 197 (unsigned) ds. shm_ctime); 198 199 if (shmctl(id, IPC_SET, &ds)) 200 perror_msg_and_skip("shmctl IPC_SET"); 201 printf("shmctl\\(%d, (%s\\|)?%s, \\{shm_perm=\\{uid=%u, gid=%u" 202 ", mode=%#o\\}, ...\\}\\) = 0\n", 203 id, str_ipc_64, str_ipc_set, 204 (unsigned) ds.shm_perm.uid, (unsigned) ds.shm_perm.gid, 205 (unsigned) ds.shm_perm.mode); 206 207 rc = shmctl(0, SHM_INFO, &ds); 208 printf("shmctl\\(0, (%s\\|)?%s, %p\\) = %s\n", 209 str_ipc_64, str_shm_info, &ds, sprintrc_grep(rc)); 210 211 rc = shmctl(id, SHM_STAT, &ds); 212 printf("shmctl\\(%d, (%s\\|)?%s, %p\\) = %s\n", 213 id, str_ipc_64, str_shm_stat, &ds, sprintrc_grep(rc)); 214 215 rc = shmctl(id, SHM_STAT_ANY, &ds); 216 printf("shmctl\\(%d, (%s\\|)?%s, %p\\) = %s\n", 217 id, str_ipc_64, str_shm_stat_any, &ds, sprintrc_grep(rc)); 218 219 return 0; 220 } 221