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 owner is unchanged when O_TRUNC is set, the shared memory 11 * object exists and it is successfully opened O_RDWR. 12 * 13 * In most case this test will be unresolved if not run by root. 14 * Steps: 15 * 1. Create a shared memory object. 16 * 2. Set a non zero size for this object (to force the modification of the 17 * object when it will be reopen with O_TRUNC set). 18 * 3. Set his effective user id to an other user id which is not root. 19 * 4. Call shm_open with O_TRUNC set. 20 * 5. Check that the owner is unchanged. 21 */ 22 23/* getpwent() is part of XSI option */ 24#define _XOPEN_SOURCE 600 25 26#include <sys/mman.h> 27#include <sys/stat.h> 28#include <fcntl.h> 29#include <pwd.h> 30#include <unistd.h> 31#include <errno.h> 32#include <string.h> 33#include <stdio.h> 34#include "posixtest.h" 35 36#define BUF_SIZE 8 37#define SHM_NAME "posixtest_26-2" 38 39int main(void) 40{ 41 int fd; 42 struct stat stat_buf; 43 struct passwd *pw; 44 uid_t old_uid; 45 gid_t old_gid; 46 47 umask(0); 48 fd = shm_open(SHM_NAME, O_RDWR | O_CREAT, 49 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | 50 S_IWOTH); 51 52 if (fd == -1) { 53 perror("An error occurs when calling shm_open()"); 54 return PTS_UNRESOLVED; 55 } 56 57 if (ftruncate(fd, BUF_SIZE) != 0) { 58 perror("An error occurs when calling ftruncate()"); 59 shm_unlink(SHM_NAME); 60 return PTS_UNRESOLVED; 61 } 62 63 if (fstat(fd, &stat_buf) != 0) { 64 perror("An error occurs when calling fstat()"); 65 shm_unlink(SHM_NAME); 66 return PTS_UNRESOLVED; 67 } 68 old_uid = stat_buf.st_uid; 69 old_gid = stat_buf.st_gid; 70 71 /* search for the first user which is non root and which is not the 72 current user */ 73 while ((pw = getpwent()) != NULL) 74 if (strcmp(pw->pw_name, "root") && pw->pw_uid != getuid()) 75 break; 76 77 if (pw == NULL) { 78 printf("There is no other user than current and root.\n"); 79 shm_unlink(SHM_NAME); 80 return PTS_UNRESOLVED; 81 } 82 83 if (seteuid(pw->pw_uid) != 0) { 84 if (errno == EPERM) { 85 printf 86 ("You don't have permission to change your UID.\nTry to rerun this test as root.\n"); 87 } else { 88 perror("An error occurs when calling seteuid()"); 89 } 90 shm_unlink(SHM_NAME); 91 return PTS_UNRESOLVED; 92 } 93 94 printf("Testing with user '%s' (uid: %i)\n", pw->pw_name, pw->pw_uid); 95 96 fd = shm_open(SHM_NAME, O_RDWR | O_TRUNC, 0); 97 if (fd == -1) { 98 perror("An error occurs when calling shm_open()"); 99 seteuid(getuid()); 100 shm_unlink(SHM_NAME); 101 return PTS_UNRESOLVED; 102 } 103 104 if (fstat(fd, &stat_buf) != 0) { 105 perror("An error occurs when calling fstat()"); 106 seteuid(getuid()); 107 shm_unlink(SHM_NAME); 108 return PTS_UNRESOLVED; 109 } 110 111 seteuid(getuid()); 112 shm_unlink(SHM_NAME); 113 114 if (stat_buf.st_uid == old_uid && stat_buf.st_gid == old_gid) { 115 printf("Test PASSED\n"); 116 return PTS_PASS; 117 } 118 119 if (stat_buf.st_uid != old_uid) 120 printf("The user ID has changed.\n"); 121 if (stat_buf.st_gid != old_gid) 122 printf("The group ID has changed.\n"); 123 return PTS_FAIL; 124} 125