1 /* Application Data Integrity (ADI) test in sparc64. 2 3 Copyright 2017-2020 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <errno.h> 23 #include <pthread.h> 24 #include <sys/types.h> 25 #include <sys/wait.h> 26 #include <unistd.h> 27 #include <sys/errno.h> 28 #include <sys/utsname.h> 29 #include <sys/param.h> 30 #include <malloc.h> 31 #include <string.h> 32 #include <signal.h> 33 #include <sys/shm.h> 34 #include <errno.h> 35 #include <sys/mman.h> 36 #include <sys/stat.h> 37 #include <fcntl.h> 38 #include <poll.h> 39 #include <setjmp.h> 40 #include "adi.h" 41 42 #define ONEKB 1024 43 #define PAT 0xdeadbeaf 44 45 #define MAPSIZE 8192 46 #define SHMSIZE 102400 47 #ifndef PROT_ADI 48 #define PROT_ADI 0x10 49 #endif 50 51 static int 52 memory_fill (char *addr, size_t size, int pattern) 53 { 54 long *aligned_addr = (long *) addr; 55 long i; 56 for (i = 0; i < size / sizeof (long); i += ONEKB) 57 { 58 *aligned_addr = pattern; 59 aligned_addr = aligned_addr + ONEKB; 60 } 61 return (0); 62 } 63 64 int main () 65 { 66 char *haddr; 67 caddr_t vaddr; 68 int version; 69 70 /* Test ISM. */ 71 int shmid = shmget (IPC_PRIVATE, SHMSIZE, IPC_CREAT | 0666); 72 if (shmid == -1) 73 exit(1); 74 char *shmaddr = (char *)shmat (shmid, NULL, 0x666 | SHM_RND); 75 if (shmaddr == (char *)-1) 76 { 77 shmctl (shmid, IPC_RMID, NULL); 78 exit(1); 79 } 80 /* Enable ADI on ISM segment. */ 81 if (mprotect (shmaddr, SHMSIZE, PROT_READ|PROT_WRITE|PROT_ADI)) 82 { 83 perror ("mprotect failed"); 84 goto err_out; 85 } 86 if (memory_fill (shmaddr, SHMSIZE, PAT) != 0) /* line breakpoint here */ 87 { 88 exit(1); 89 } 90 adi_clr_version (shmaddr, SHMSIZE); 91 caddr_t vshmaddr = adi_set_version (shmaddr, SHMSIZE, 0x8); 92 if (vshmaddr == 0) 93 exit(1); 94 /* Test mmap. */ 95 int fd = open ("/dev/zero", O_RDWR); 96 if (fd < 0) 97 exit(1); 98 char *maddr = (char *)mmap (NULL, MAPSIZE, PROT_READ|PROT_WRITE, 99 MAP_PRIVATE, fd, 0); 100 if (maddr == (char *)-1) 101 exit(1); 102 /* Enable ADI. */ 103 if (mprotect (shmaddr, MAPSIZE, PROT_READ|PROT_WRITE|PROT_ADI)) 104 { 105 perror ("mprotect failed"); 106 goto err_out; 107 108 } 109 if (memory_fill (maddr, MAPSIZE, PAT) != 0) 110 exit(1); 111 caddr_t vmaddr = adi_set_version (maddr, MAPSIZE, 0x8); 112 113 /* Test heap. */ 114 haddr = (char*) memalign (MAPSIZE, MAPSIZE); 115 /* Enable ADI. */ 116 if (mprotect (shmaddr, MAPSIZE, PROT_READ|PROT_WRITE|PROT_ADI)) 117 { 118 perror ("mprotect failed"); 119 goto err_out; 120 } 121 122 if (memory_fill (haddr, MAPSIZE, PAT) != 0) 123 exit(1); 124 adi_clr_version (haddr, MAPSIZE); 125 /* Set some ADP version number. */ 126 caddr_t vaddr1, vaddr2, vaddr3, vaddr4; 127 vaddr = adi_set_version (haddr, 64*2, 0x8); 128 vaddr1 = adi_set_version (haddr+64*2, 64*2, 0x9); 129 vaddr2 = adi_clr_version (haddr+64*4, 64*2); 130 vaddr3 = adi_set_version (haddr+64*6, 64*2, 0xa); 131 vaddr4 = adi_set_version (haddr+64*8, 64*10, 0x3); 132 if (vaddr == 0) 133 exit(1); 134 char *versioned_p = vaddr; 135 *versioned_p = 'a'; 136 char *uvp = haddr; // unversioned pointer 137 *uvp = 'b'; // version mismatch trap 138 139 return (0); 140 err_out: 141 if (shmdt ((const void *)shmaddr) != 0) 142 perror ("Detach failure"); 143 shmctl (shmid, IPC_RMID, NULL); 144 exit (1); 145 } 146