diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-02-21 16:37:41 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-02-21 16:37:41 +0100 |
commit | a624fe06b8f1b632a82b30a6deeaa1982c602a40 (patch) | |
tree | 0a13298b0982a107769410ab7370d83467baf6cd /Kernel | |
parent | f0a869ea504af0adb3f03c11deeeab997f304dc7 (diff) | |
download | serenity-a624fe06b8f1b632a82b30a6deeaa1982c602a40.zip |
Kernel: Add file permission checks to utime() syscall.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Process.cpp | 15 | ||||
-rw-r--r-- | Kernel/VirtualFileSystem.cpp | 23 | ||||
-rw-r--r-- | Kernel/VirtualFileSystem.h | 1 |
3 files changed, 27 insertions, 12 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 814177116e..f39a8d4680 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1125,14 +1125,6 @@ int Process::sys$utime(const char* pathname, const utimbuf* buf) return -EFAULT; if (buf && !validate_read_typed(buf)) return -EFAULT; - String path(pathname); - int error; - auto descriptor = VFS::the().open(move(path), error, 0, 0, cwd_inode()); - if (!descriptor) - return error; - auto& inode = *descriptor->inode(); - if (inode.fs().is_readonly()) - return -EROFS; time_t atime; time_t mtime; if (buf) { @@ -1143,11 +1135,10 @@ int Process::sys$utime(const char* pathname, const utimbuf* buf) mtime = now; atime = now; } - error = inode.set_atime(atime); - if (error) + int error; + if (!VFS::the().utime(String(pathname), error, cwd_inode(), atime, mtime)) return error; - error = inode.set_mtime(mtime); - return error; + return 0; } int Process::sys$access(const char* pathname, int mode) diff --git a/Kernel/VirtualFileSystem.cpp b/Kernel/VirtualFileSystem.cpp index 27c0c6d652..4490a208da 100644 --- a/Kernel/VirtualFileSystem.cpp +++ b/Kernel/VirtualFileSystem.cpp @@ -131,6 +131,29 @@ RetainPtr<FileDescriptor> VFS::open(RetainPtr<Device>&& device, int& error, int return FileDescriptor::create(move(device)); } +bool VFS::utime(const String& path, int& error, Inode& base, time_t atime, time_t mtime) +{ + auto descriptor = VFS::the().open(move(path), error, 0, 0, base); + if (!descriptor) + return false; + auto& inode = *descriptor->inode(); + if (inode.fs().is_readonly()) { + error = -EROFS; + return false; + } + if (inode.metadata().uid != current->euid()) { + error = -EACCES; + return false; + } + error = inode.set_atime(atime); + if (error) + return false; + error = inode.set_mtime(mtime); + if (error) + return false; + return true; +} + bool VFS::stat(const String& path, int& error, int options, Inode& base, struct stat& statbuf) { auto inode_id = resolve_path(path, base.identifier(), error, options); diff --git a/Kernel/VirtualFileSystem.h b/Kernel/VirtualFileSystem.h index c90aa85b80..b7e9529443 100644 --- a/Kernel/VirtualFileSystem.h +++ b/Kernel/VirtualFileSystem.h @@ -70,6 +70,7 @@ public: bool rmdir(const String& path, Inode& base, int& error); bool chmod(const String& path, mode_t, Inode& base, int& error); bool stat(const String& path, int& error, int options, Inode& base, struct stat&); + bool utime(const String& path, int& error, Inode& base, time_t atime, time_t mtime); void register_device(Device&); void unregister_device(Device&); |