Serenity Operating System
at master 103 lines 2.4 kB view raw
1/* 2 * Copyright (c) 2020-2021, the SerenityOS developers. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/DeprecatedString.h> 8#include <LibCore/DeprecatedFile.h> 9#include <LibTest/TestCase.h> 10#include <fcntl.h> 11#include <stdio.h> 12#include <stdlib.h> 13#include <string.h> 14#include <sys/stat.h> 15#include <sys/types.h> 16#include <unistd.h> 17 18TEST_CASE(test_change_file_contents) 19{ 20 char path[] = "/tmp/suid.XXXXXX"; 21 auto fd = mkstemp(path); 22 EXPECT(fd != -1); 23 ftruncate(fd, 0); 24 EXPECT(fchmod(fd, 06755) != -1); 25 26 char buffer[8] {}; 27 write(fd, buffer, sizeof(buffer)); 28 29 struct stat s; 30 EXPECT(fstat(fd, &s) != -1); 31 close(fd); 32 unlink(path); 33 34 EXPECT(!(s.st_mode & S_ISUID)); 35 EXPECT(!(s.st_mode & S_ISGID)); 36} 37 38TEST_CASE(test_change_file_ownership) 39{ 40 char path[] = "/tmp/suid.XXXXXX"; 41 auto fd = mkstemp(path); 42 EXPECT(fd != -1); 43 ftruncate(fd, 0); 44 EXPECT(fchmod(fd, 06755) != -1); 45 46 fchown(fd, getuid(), getgid()); 47 48 struct stat s; 49 EXPECT(fstat(fd, &s) != -1); 50 close(fd); 51 unlink(path); 52 53 EXPECT(!(s.st_mode & S_ISUID)); 54 EXPECT(!(s.st_mode & S_ISGID)); 55} 56 57TEST_CASE(test_change_file_permissions) 58{ 59 char path[] = "/tmp/suid.XXXXXX"; 60 auto fd = mkstemp(path); 61 EXPECT(fd != -1); 62 ftruncate(fd, 0); 63 EXPECT(fchmod(fd, 06755) != -1); 64 65 fchmod(fd, 0755); 66 67 struct stat s; 68 EXPECT(fstat(fd, &s) != -1); 69 close(fd); 70 unlink(path); 71 72 EXPECT(!(s.st_mode & S_ISUID)); 73 EXPECT(!(s.st_mode & S_ISGID)); 74} 75 76TEST_CASE(test_change_file_location) 77{ 78 char path[] = "/tmp/suid.XXXXXX"; 79 auto fd = mkstemp(path); 80 EXPECT(fd != -1); 81 ftruncate(fd, 0); 82 EXPECT(fchmod(fd, 06755) != -1); 83 84 auto suid_path_or_error = Core::DeprecatedFile::read_link(DeprecatedString::formatted("/proc/{}/fd/{}", getpid(), fd)); 85 EXPECT(!suid_path_or_error.is_error()); 86 87 auto suid_path = suid_path_or_error.release_value(); 88 EXPECT(suid_path.characters()); 89 auto new_path = DeprecatedString::formatted("{}.renamed", suid_path); 90 91 rename(suid_path.characters(), new_path.characters()); 92 93 struct stat s; 94 EXPECT(lstat(new_path.characters(), &s) != -1); 95 close(fd); 96 unlink(path); 97 98 // Renamed file should retain set-uid/set-gid permissions 99 EXPECT(s.st_mode & S_ISUID); 100 EXPECT(s.st_mode & S_ISGID); 101 102 unlink(new_path.characters()); 103}