1/* 2 * Copyright (c) 2015 Elvira Khabirova <lineprinter0@gmail.com> 3 * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org> 4 * Copyright (c) 2015-2017 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#include "xlat.h" 45#include "xlat/shm_resource_flags.h" 46 47static int id = -1; 48 49static void 50cleanup(void) 51{ 52 shmctl(id, IPC_RMID, NULL); 53 printf("shmctl\\(%d, (IPC_64\\|)?IPC_RMID, NULL\\) += 0\n", id); 54 id = -1; 55} 56 57int 58main(void) 59{ 60 static const key_t private_key = 61 (key_t) (0xffffffff00000000ULL | IPC_PRIVATE); 62 static const key_t bogus_key = (key_t) 0xeca86420fdb97531ULL; 63 static const int bogus_id = 0xdefaced1; 64 static const int bogus_cmd = 0xdefaced2; 65 static void * const bogus_addr = (void *) -1L; 66 static const size_t bogus_size = 67 /* 68 * musl sets size to SIZE_MAX if size argument is greater than 69 * PTRDIFF_MAX - musl/src/ipc/shmget.c 70 */ 71 #ifdef __GLIBC__ 72 (size_t) 0xdec0ded1dec0ded2ULL; 73 #else 74 (size_t) 0x1e55c0de5dec0dedULL; 75 #endif 76 static const unsigned int bogus_ipc_shm_flags = 77 IPC_CREAT | IPC_EXCL | SHM_HUGETLB | SHM_NORESERVE; 78 static const unsigned int huge_mask = SHM_HUGE_MASK << SHM_HUGE_SHIFT; 79 static const unsigned int huge_flags = 21 << SHM_HUGE_SHIFT; 80 int bogus_flags; 81 int rc; 82 struct shmid_ds ds; 83 84 rc = shmget(bogus_key, bogus_size, 0); 85 printf("shmget\\(%#llx, %zu, 000\\) += %s\n", 86 zero_extend_signed_to_ull(bogus_key), bogus_size, 87 sprintrc_grep(rc)); 88 89 rc = shmget(bogus_key, bogus_size, huge_flags); 90 printf("shmget\\(%#llx, %zu, %s\\|%#03o\\) += %s\n", 91 zero_extend_signed_to_ull(bogus_key), bogus_size, 92 "21<<SHM_HUGE_SHIFT", 0, sprintrc_grep(rc)); 93 94 bogus_flags = 0xface1e55 & ~(bogus_ipc_shm_flags | huge_mask); 95 rc = shmget(bogus_key, bogus_size, bogus_flags); 96 printf("shmget\\(%#llx, %zu, %#x\\|%#03o\\) += %s\n", 97 zero_extend_signed_to_ull(bogus_key), bogus_size, 98 bogus_flags & ~0777, 99 bogus_flags & 0777, sprintrc_grep(rc)); 100 101 bogus_flags |= bogus_ipc_shm_flags; 102 rc = shmget(bogus_key, bogus_size, bogus_flags); 103 printf("shmget\\(%#llx, %zu, %s\\|%#x\\|%#03o\\) += %s\n", 104 zero_extend_signed_to_ull(bogus_key), bogus_size, 105 "IPC_CREAT\\|IPC_EXCL\\|SHM_HUGETLB\\|SHM_NORESERVE", 106 bogus_flags & ~(0777 | bogus_ipc_shm_flags), 107 bogus_flags & 0777, sprintrc_grep(rc)); 108 109 bogus_flags |= huge_flags; 110 rc = shmget(bogus_key, bogus_size, bogus_flags); 111 printf("shmget\\(%#llx, %zu, %s\\|%#x\\|%s\\|%#03o\\) += %s\n", 112 zero_extend_signed_to_ull(bogus_key), bogus_size, 113 "IPC_CREAT\\|IPC_EXCL\\|SHM_HUGETLB\\|SHM_NORESERVE", 114 bogus_flags & ~(0777 | bogus_ipc_shm_flags | huge_mask), 115 "21<<SHM_HUGE_SHIFT", 116 bogus_flags & 0777, sprintrc_grep(rc)); 117 118 bogus_flags &= ~bogus_ipc_shm_flags; 119 rc = shmget(bogus_key, bogus_size, bogus_flags); 120 printf("shmget\\(%#llx, %zu, %#x\\|%s\\|%#03o\\) += %s\n", 121 zero_extend_signed_to_ull(bogus_key), bogus_size, 122 bogus_flags & ~(0777 | huge_mask), 123 "21<<SHM_HUGE_SHIFT", 124 bogus_flags & 0777, sprintrc_grep(rc)); 125 126 id = shmget(private_key, 1, 0600); 127 if (id < 0) 128 perror_msg_and_skip("shmget"); 129 printf("shmget\\(IPC_PRIVATE, 1, 0600\\) += %d\n", id); 130 atexit(cleanup); 131 132 rc = shmctl(bogus_id, bogus_cmd, NULL); 133 printf("shmctl\\(%d, (IPC_64\\|)?%#x /\\* SHM_\\?\\?\\? \\*/, NULL\\)" 134 " += %s\n", bogus_id, bogus_cmd, sprintrc_grep(rc)); 135 136 rc = shmctl(bogus_id, IPC_STAT, bogus_addr); 137 printf("shmctl\\(%d, (IPC_64\\|)?IPC_STAT, %p\\) += %s\n", 138 bogus_id, bogus_addr, sprintrc_grep(rc)); 139 140 if (shmctl(id, IPC_STAT, &ds)) 141 perror_msg_and_skip("shmctl IPC_STAT"); 142 printf("shmctl\\(%d, (IPC_64\\|)?IPC_STAT, \\{shm_perm=\\{uid=%u, gid=%u, " 143 "mode=%#o, key=%u, cuid=%u, cgid=%u\\}, shm_segsz=%u, shm_cpid=%u, " 144 "shm_lpid=%u, shm_nattch=%u, shm_atime=%u, shm_dtime=%u, " 145 "shm_ctime=%u\\}\\) += 0\n", 146 id, (unsigned) ds.shm_perm.uid, (unsigned) ds.shm_perm.gid, 147 (unsigned) ds.shm_perm.mode, (unsigned) ds.shm_perm.__key, 148 (unsigned) ds.shm_perm.cuid, (unsigned) ds.shm_perm.cgid, 149 (unsigned) ds.shm_segsz, (unsigned) ds.shm_cpid, 150 (unsigned) ds.shm_lpid, (unsigned) ds.shm_nattch, 151 (unsigned) ds.shm_atime, (unsigned) ds.shm_dtime, 152 (unsigned) ds. shm_ctime); 153 154 if (shmctl(id, IPC_SET, &ds)) 155 perror_msg_and_skip("shmctl IPC_SET"); 156 printf("shmctl\\(%d, (IPC_64\\|)?IPC_SET, \\{shm_perm=\\{uid=%u, gid=%u" 157 ", mode=%#o\\}, ...\\}\\) += 0\n", 158 id, (unsigned) ds.shm_perm.uid, (unsigned) ds.shm_perm.gid, 159 (unsigned) ds.shm_perm.mode); 160 161 rc = shmctl(0, SHM_INFO, &ds); 162 printf("shmctl\\(0, (IPC_64\\|)?SHM_INFO, %p\\) += %s\n", 163 &ds, sprintrc_grep(rc)); 164 165 rc = shmctl(id, SHM_STAT, &ds); 166 printf("shmctl\\(%d, (IPC_64\\|)?SHM_STAT, %p\\) += %s\n", 167 id, &ds, sprintrc_grep(rc)); 168 169 return 0; 170} 171