From 1090815c8dd70aa4aa855881369776b1b0897769 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 3 Jun 2023 11:55:10 +0200 Subject: [PATCH] kernel: Honor the sticky bit --- kernel/src/fs/VFS.cpp | 5 +++++ kernel/src/fs/VFS.h | 1 + kernel/src/sys/link.cpp | 11 ++++++----- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/kernel/src/fs/VFS.cpp b/kernel/src/fs/VFS.cpp index 6c0aacb9..739b90e9 100644 --- a/kernel/src/fs/VFS.cpp +++ b/kernel/src/fs/VFS.cpp @@ -168,6 +168,11 @@ namespace VFS return inode->mode() & S_ISGID; } + bool is_sticky(SharedPtr inode) + { + return inode->mode() & S_ISVTX; + } + bool is_seekable(SharedPtr inode) { return inode->type() != InodeType::FIFO && inode->type() != InodeType::CharacterDevice; diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h index 0f9ca990..d47aafe2 100644 --- a/kernel/src/fs/VFS.h +++ b/kernel/src/fs/VFS.h @@ -290,6 +290,7 @@ namespace VFS bool can_write(SharedPtr inode, Credentials auth); bool is_setuid(SharedPtr inode); bool is_setgid(SharedPtr inode); + bool is_sticky(SharedPtr inode); bool is_seekable(SharedPtr inode); diff --git a/kernel/src/sys/link.cpp b/kernel/src/sys/link.cpp index 4828ca75..293c6145 100644 --- a/kernel/src/sys/link.cpp +++ b/kernel/src/sys/link.cpp @@ -25,11 +25,12 @@ Result sys_unlinkat(Registers*, SyscallArgs args) auto inode = TRY(current->resolve_atfile(dirfd, dirname, false, false)); if (!VFS::can_write(inode, current->auth)) return err(EACCES); - if (flags > 0) - { - auto child = TRY(inode->find(basename.chars())); - if (child->type() != VFS::InodeType::Directory) return err(ENOTDIR); - } + auto child = TRY(inode->find(basename.chars())); + if (flags == AT_REMOVEDIR && child->type() != VFS::InodeType::Directory) return err(ENOTDIR); + + if (current->auth.euid != 0 && VFS::is_sticky(inode) && current->auth.euid != inode->uid() && + current->auth.euid != child->uid()) + return err(EACCES); TRY(inode->remove_entry(basename.chars()));