1/* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License version 2. 4 * 5 * This program is distributed in the hope that it will be useful, 6 * but WITHOUT ANY WARRANTY; without even the implied warranty of 7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8 * GNU General Public License for more details. 9 * 10 * Test that the named shared memory object is not changed by this function 11 * call when the process does not have permission to unlink the name. 12 * 13 * Steps: 14 * 1. Create a shared memory object. 15 * 2. Set his effective user id to an other user id which is not root. 16 * 3. Try to unlink the name. 17 * If it fail: set the effective user id to real user id and unlink. 18 * In most case this test will be unresolved if not run by root. 19 */ 20 21/* getpwent() is part of XSI option */ 22#define _XOPEN_SOURCE 600 23 24#include <stdio.h> 25#include <sys/mman.h> 26#include <sys/stat.h> 27#include <unistd.h> 28#include <fcntl.h> 29#include <errno.h> 30#include <pwd.h> 31#include <string.h> 32#include "posixtest.h" 33 34#define SHM_NAME "posixtest_9-1" 35#define BUF_SIZE 8 36 37 38int main() { 39 int fd, result; 40 struct passwd *pw; 41 struct stat stat_before, stat_after; 42 43 fd = shm_open(SHM_NAME, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); 44 if(fd == -1) { 45 perror("An error occurs when calling shm_open()"); 46 return PTS_UNRESOLVED; 47 } 48 49 if(ftruncate(fd, BUF_SIZE) != 0) { 50 perror("An error occurs when calling ftruncate()"); 51 shm_unlink(SHM_NAME); 52 return PTS_UNRESOLVED; 53 } 54 55 if(fstat(fd, &stat_before) != 0) { 56 perror("An error occurs when calling fstat()"); 57 shm_unlink(SHM_NAME); 58 return PTS_UNRESOLVED; 59 } 60 61 /* search for the first user which is non root and which is not the 62 current user */ 63 while((pw = getpwent()) != NULL) 64 if(strcmp(pw->pw_name, "root") && pw->pw_uid != getuid()) 65 break; 66 67 if(pw == NULL) { 68 printf("There is no other user than current and root.\n"); 69 return PTS_UNRESOLVED; 70 } 71 72 if(seteuid(pw->pw_uid) != 0) { 73 if(errno == EPERM) { 74 printf("You don't have permission to change your UID.\nTry to rerun this test as root.\n"); 75 return PTS_UNRESOLVED; 76 } 77 perror("An error occurs when calling seteuid()"); 78 return PTS_UNRESOLVED; 79 } 80 81 printf("Testing with user '%s' (uid: %i)\n", 82 pw->pw_name, pw->pw_uid); 83 84 result = shm_unlink(SHM_NAME); 85 if(result == 0) { 86 printf("shm_unlink() success.\n"); 87 return PTS_UNRESOLVED; 88 } 89 90 seteuid(getuid()); 91 92 if(fstat(fd, &stat_after) != 0) { 93 perror("An error occurs when calling fstat()"); 94 shm_unlink(SHM_NAME); 95 return PTS_UNRESOLVED; 96 } 97 98 if(stat_after.st_uid != stat_before.st_uid || 99 stat_after.st_gid != stat_before.st_gid || 100 stat_after.st_size != stat_before.st_size || 101 stat_after.st_mode != stat_before.st_mode) { 102 printf("The shared memory object has changed.\n"); 103 return PTS_FAIL; 104 } 105 106 printf("Test PASSED\n"); 107 return PTS_PASS; 108 109} 110