ladybird/Tests/Kernel/TestKernelFilePermissions.cpp
Kenneth Myhra 4a57be824c Userland+Tests: Convert File::read_link() from String to ErrorOr<String>
This converts the return value of File::read_link() from String to
ErrorOr<String>.

The rest of the change is to support the potential of an Error being
returned and subsequent release of the value when no Error is returned.
Unfortunately at this stage none of the places affected can utililize
our TRY() macro.
2022-03-24 11:57:51 +01:00

103 lines
2.3 KiB
C++

/*
* Copyright (c) 2020-2021, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/String.h>
#include <LibCore/File.h>
#include <LibTest/TestCase.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
TEST_CASE(test_change_file_contents)
{
char path[] = "/tmp/suid.XXXXXX";
auto fd = mkstemp(path);
EXPECT(fd != -1);
ftruncate(fd, 0);
EXPECT(fchmod(fd, 06755) != -1);
char buffer[8] {};
write(fd, buffer, sizeof(buffer));
struct stat s;
EXPECT(fstat(fd, &s) != -1);
close(fd);
unlink(path);
EXPECT(!(s.st_mode & S_ISUID));
EXPECT(!(s.st_mode & S_ISGID));
}
TEST_CASE(test_change_file_ownership)
{
char path[] = "/tmp/suid.XXXXXX";
auto fd = mkstemp(path);
EXPECT(fd != -1);
ftruncate(fd, 0);
EXPECT(fchmod(fd, 06755) != -1);
fchown(fd, getuid(), getgid());
struct stat s;
EXPECT(fstat(fd, &s) != -1);
close(fd);
unlink(path);
EXPECT(!(s.st_mode & S_ISUID));
EXPECT(!(s.st_mode & S_ISGID));
}
TEST_CASE(test_change_file_permissions)
{
char path[] = "/tmp/suid.XXXXXX";
auto fd = mkstemp(path);
EXPECT(fd != -1);
ftruncate(fd, 0);
EXPECT(fchmod(fd, 06755) != -1);
fchmod(fd, 0755);
struct stat s;
EXPECT(fstat(fd, &s) != -1);
close(fd);
unlink(path);
EXPECT(!(s.st_mode & S_ISUID));
EXPECT(!(s.st_mode & S_ISGID));
}
TEST_CASE(test_change_file_location)
{
char path[] = "/tmp/suid.XXXXXX";
auto fd = mkstemp(path);
EXPECT(fd != -1);
ftruncate(fd, 0);
EXPECT(fchmod(fd, 06755) != -1);
auto suid_path_or_error = Core::File::read_link(String::formatted("/proc/{}/fd/{}", getpid(), fd));
EXPECT(!suid_path_or_error.is_error());
auto suid_path = suid_path_or_error.release_value();
EXPECT(suid_path.characters());
auto new_path = String::formatted("{}.renamed", suid_path);
rename(suid_path.characters(), new_path.characters());
struct stat s;
EXPECT(lstat(new_path.characters(), &s) != -1);
close(fd);
unlink(path);
// Renamed file should retain set-uid/set-gid permissions
EXPECT(s.st_mode & S_ISUID);
EXPECT(s.st_mode & S_ISGID);
unlink(new_path.characters());
}