Fix permission checks in EXT2.

This commit is contained in:
Enrico Fraccaroli
2021-12-29 13:16:02 +01:00
parent 1ebc74f31f
commit 81a0abed20
7 changed files with 99 additions and 22 deletions
+2
View File
@@ -79,6 +79,8 @@ add_custom_target(filesystem
COMMAND echo "---------------------------------------------"
COMMAND echo "Creating EXT2 filesystem..."
COMMAND echo "---------------------------------------------"
COMMAND mkdir -p ${CMAKE_SOURCE_DIR}/files/proc
COMMAND mkdir -p ${CMAKE_SOURCE_DIR}/files/dev
COMMAND mke2fs -L 'rootfs' -N 0 -d ${CMAKE_SOURCE_DIR}/files -m 5 -r 1 -t ext2 -v -F ${CMAKE_BINARY_DIR}/rootfs.img 32M
COMMAND echo "---------------------------------------------"
COMMAND echo "Done!"
+5
View File
@@ -15,6 +15,11 @@ char *strerror(int errnum)
case 0:
strcpy(error, "Success");
break;
#ifdef EPERM
case EPERM:
strcpy(error, "Operation not permitted");
break;
#endif
#ifdef ENOENT
case ENOENT:
strcpy(error, "No such file or directory");
+45 -2
View File
@@ -461,6 +461,44 @@ static const char *time_to_string(uint32_t time)
return s;
}
/// @brief Checks if the requests in flags are valid.
/// @param flags the flags to check.
/// @param mask the mask to check against.
/// @param uid the uid of the owner.
/// @param gid the gid of the owner.
/// @return true on success, false otherwise.
static bool_t ext2_valid_permissions(int flags, mode_t mask, uid_t uid, gid_t gid)
{
// Check the permissions.
task_struct *task = scheduler_get_current_process();
// The current task is the owner.
if (task->uid == uid) {
if (!bitmask_check(mask, S_IRUSR))
return false;
if (bitmask_check(flags, O_WRONLY) && !bitmask_check(mask, S_IWUSR))
return false;
if (bitmask_check(flags, O_RDWR) && (!bitmask_check(mask, S_IRUSR) || !bitmask_check(mask, S_IWUSR)))
return false;
}
if (task->gid == gid) {
if (!bitmask_check(mask, S_IRGRP))
return false;
if (bitmask_check(flags, O_WRONLY) && !bitmask_check(mask, S_IWGRP))
return false;
if (bitmask_check(flags, O_RDWR) && (!bitmask_check(mask, S_IRGRP) || !bitmask_check(mask, S_IWGRP)))
return false;
}
if ((task->uid != uid) && (task->gid != gid)) {
if (!bitmask_check(mask, S_IROTH))
return false;
if (bitmask_check(flags, O_WRONLY) && !bitmask_check(mask, S_IWOTH))
return false;
if (bitmask_check(flags, O_RDWR) && (!bitmask_check(mask, S_IROTH) || !bitmask_check(mask, S_IWOTH)))
return false;
}
return true;
}
/// @brief Dumps on debugging output the superblock.
/// @param sb the object to dump.
static void ext2_dump_superblock(ext2_superblock_t *sb)
@@ -2254,6 +2292,7 @@ static vfs_file_t *ext2_open(const char *path, int flags, mode_t mode)
return ext2_creat(path, mode);
} else {
pr_err("The file does not exist `%s`.\n", absolute_path);
errno = ENOENT;
return NULL;
}
}
@@ -2265,6 +2304,12 @@ static vfs_file_t *ext2_open(const char *path, int flags, mode_t mode)
pr_err("Failed to read the inode of `%s`.\n", direntry.name);
return NULL;
}
if (!ext2_valid_permissions(flags, inode.mode, inode.uid, inode.gid)) {
errno = EACCES;
return NULL;
}
vfs_file_t *file = ext2_find_vfs_file_with_inode(fs, direntry.inode);
if (file == NULL) {
// Allocate the memory for the file.
@@ -2280,8 +2325,6 @@ static vfs_file_t *ext2_open(const char *path, int flags, mode_t mode)
// Add the vfs_file to the list of associated files.
list_head_add_tail(&file->siblings, &fs->opened_files);
}
pr_debug("ext2_open(path: \"%s\", flags: %d, mode: %d) -> file(ino: %d, name: \"%s\")\n",
path, flags, mode, file->ino, file->name);
return file;
}
+1 -1
View File
@@ -143,7 +143,7 @@ vfs_file_t *vfs_open(const char *path, int flags, mode_t mode)
// Retrieve the file.
vfs_file_t *file = sb_root->fs_operations->open_f(absolute_path, flags, mode);
if (file == NULL) {
pr_err("vfs_open(%s): Cannot find the given file (%s)!\n", path, strerror(errno));
pr_debug("vfs_open(%s): Filesystem open returned NULL file (errno: %d, %s)!\n", path, errno, strerror(errno));
return NULL;
}
// Increment file reference counter.
+5
View File
@@ -15,6 +15,11 @@ char *strerror(int errnum)
case 0:
strcpy(error, "Success");
break;
#ifdef EPERM
case EPERM:
strcpy(error, "Operation not permitted");
break;
#endif
#ifdef ENOENT
case ENOENT:
strcpy(error, "No such file or directory");
+39 -17
View File
@@ -9,32 +9,54 @@
#include <string.h>
#include <sys/unistd.h>
#include <strerror.h>
#include <sys/stat.h>
int main(int argc, char **argv)
{
if (argc != 2) {
printf("%s: missing operand.\n", argv[0]);
printf("Try '%s --help' for more information.\n\n", argv[0]);
if (argc < 2) {
printf("cat: missing operand.\n");
printf("Try 'cat --help' for more information.\n\n");
return 1;
}
if (strcmp(argv[1], "--help") == 0) {
printf("Prints the content of the given file.\n");
printf("Usage:\n");
printf(" %s <file>\n\n", argv[0]);
return 0;
}
int fd = open(argv[1], O_RDONLY, 42);
if (fd < 0) {
printf("%s: %s: %s\n\n", argv[0], strerror(errno), argv[1]);
return 1;
// Check if `--help` is provided.
for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--help") == 0) {
printf("Prints the content of the given file.\n");
printf("Usage:\n");
printf(" cat <file>\n\n");
return 0;
}
}
// Prepare the buffer for reading.
char buffer[BUFSIZ];
// Put on the standard output the characters.
while (read(fd, buffer, BUFSIZ) > 0) {
puts(buffer);
// Iterate the arguments.
for (int i = 1; i < argc; ++i) {
int fd = open(argv[i], O_RDONLY, 42);
if (fd < 0) {
printf("cat: %s: %s\n\n", argv[i], strerror(errno));
continue;
}
stat_t statbuf;
if (fstat(fd, &statbuf) == -1) {
printf("cat: %s: %s\n\n", argv[i], strerror(errno));
// Close the file descriptor.
close(fd);
continue;
}
if (S_ISDIR(statbuf.st_mode)) {
printf("cat: %s: %s\n\n", argv[i], strerror(EISDIR));
// Close the file descriptor.
close(fd);
continue;
}
// Put on the standard output the characters.
while (read(fd, buffer, BUFSIZ) > 0) {
puts(buffer);
}
// Close the file descriptor.
close(fd);
}
putchar('\n');
putchar('\n');
close(fd);
return 0;
}
+2 -2
View File
@@ -145,7 +145,7 @@ int main(int argc, char *argv[])
no_directory = false;
int fd = open(argv[i], O_RDONLY | O_DIRECTORY, 0);
if (fd == -1) {
printf("%s: cannot access '%s': %s\n\n", argv[0], argv[i], strerror(errno));
printf("ls: cannot access '%s': %s\n\n", argv[i], strerror(errno));
} else {
printf("%s:\n", argv[i]);
print_ls(fd, argv[i], flags);
@@ -157,7 +157,7 @@ int main(int argc, char *argv[])
getcwd(cwd, PATH_MAX);
int fd = open(cwd, O_RDONLY | O_DIRECTORY, 0);
if (fd == -1) {
printf("%s: cannot access '%s': %s\n\n", argv[0], cwd, strerror(errno));
printf("ls: cannot access '%s': %s\n\n", cwd, strerror(errno));
} else {
print_ls(fd, cwd, flags);
close(fd);