1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) International Business Machines Corp., 2001 4 */ 5 6 /* 7 * Test Name: chmod07 8 * 9 * Test Description: 10 * Verify that, chmod(2) will succeed to change the mode of a file/directory 11 * and sets the sticky bit on it if invoked by root (uid = 0) process with 12 * the following constraints, 13 * - the process is not the owner of the file/directory. 14 * - the effective group ID or one of the supplementary group ID's of the 15 * process is equal to the group ID of the file/directory. 16 * 17 * Expected Result: 18 * chmod() should return value 0 on success and succeeds to set sticky bit 19 * on the specified file. 20 */ 21 22 #include <stdio.h> 23 #include <sys/types.h> 24 #include <sys/stat.h> 25 #include <fcntl.h> 26 #include <errno.h> 27 #include <string.h> 28 #include <signal.h> 29 #include <grp.h> 30 #include <pwd.h> 31 32 #include "tst_test.h" 33 34 #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) 35 #define PERMS 01777 /* Permissions with sticky bit set. */ 36 #define TESTFILE "testfile" 37 38 void test_chmod(void) 39 { 40 struct stat stat_buf; 41 42 /* 43 * Call chmod(2) with specified mode argument 44 * (sticky-bit set) on testfile. 45 */ 46 TEST(chmod(TESTFILE, PERMS)); 47 if (TST_RET == -1) { 48 tst_brk(TFAIL | TTERRNO, "chmod(%s, %#o) failed", 49 TESTFILE, PERMS); 50 } 51 52 if (stat(TESTFILE, &stat_buf) == -1) { 53 tst_brk(TFAIL | TTERRNO, "stat failed"); 54 } 55 56 /* Check for expected mode permissions */ 57 if ((stat_buf.st_mode & PERMS) == PERMS) { 58 tst_res(TPASS, "Functionality of chmod(%s, %#o) successful", 59 TESTFILE, PERMS); 60 } else { 61 tst_res(TFAIL, "%s: Incorrect modes 0%03o; expected 0%03o", 62 TESTFILE, stat_buf.st_mode, PERMS); 63 } 64 } 65 66 void setup(void) 67 { 68 struct passwd *ltpuser; 69 struct group *ltpgroup; 70 int fd; 71 gid_t group1_gid; 72 uid_t user1_uid; 73 74 ltpuser = SAFE_GETPWNAM("nobody"); 75 user1_uid = ltpuser->pw_uid; 76 77 ltpgroup = SAFE_GETGRNAM_FALLBACK("users", "daemon"); 78 group1_gid = ltpgroup->gr_gid; 79 80 fd = SAFE_OPEN(TESTFILE, O_RDWR | O_CREAT, FILE_MODE); 81 SAFE_CLOSE(fd); 82 SAFE_CHOWN(TESTFILE, user1_uid, group1_gid); 83 SAFE_SETGID(group1_gid); 84 } 85 86 static struct tst_test test = { 87 .needs_root = 1, 88 .needs_tmpdir = 1, 89 .setup = setup, 90 .test_all = test_chmod, 91 }; 92