Home | History | Annotate | Download | only in shm_unlink
      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 int main(void)
     38 {
     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
     75 			    ("You don't have permission to change your UID.\nTry to rerun this test as root.\n");
     76 			return PTS_UNRESOLVED;
     77 		}
     78 		perror("An error occurs when calling seteuid()");
     79 		return PTS_UNRESOLVED;
     80 	}
     81 
     82 	printf("Testing with user '%s' (uid: %i)\n", 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