summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-02-21 16:37:41 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-02-21 16:37:41 +0100
commita624fe06b8f1b632a82b30a6deeaa1982c602a40 (patch)
tree0a13298b0982a107769410ab7370d83467baf6cd /Kernel
parentf0a869ea504af0adb3f03c11deeeab997f304dc7 (diff)
downloadserenity-a624fe06b8f1b632a82b30a6deeaa1982c602a40.zip
Kernel: Add file permission checks to utime() syscall.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Process.cpp15
-rw-r--r--Kernel/VirtualFileSystem.cpp23
-rw-r--r--Kernel/VirtualFileSystem.h1
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&);