From ee64e29e7713644231dc9014d8ad1ff0753c2d60 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 21 Nov 2019 11:52:11 +0100 Subject: [PATCH] vfs server: tie writeable bit to session policy This patch let the VFS server reflect the session policy via the writeable bit in directory entries instead of merely forwarding the bit from the respective VFS plugin. This way, all files originating from a read-only file-system session automatically appear in directory listings as read-only files. Related to issue #3507 --- repos/os/src/server/vfs/main.cc | 25 ++++++++++++++----------- repos/os/src/server/vfs/node.h | 19 ++++++++++++++----- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/repos/os/src/server/vfs/main.cc b/repos/os/src/server/vfs/main.cc index 0f9ee4304..6764b5a73 100644 --- a/repos/os/src/server/vfs/main.cc +++ b/repos/os/src/server/vfs/main.cc @@ -119,7 +119,7 @@ class Vfs_server::Session_component : private Session_resources, Genode::Session_label const _label; - bool const _writable; + bool const _writeable; /**************************** @@ -446,7 +446,7 @@ class Vfs_server::Session_component : private Session_resources, Session_queue &active_sessions, Io_progress_handler &io_progress_handler, char const *root_path, - bool writable) + bool writeable) : Session_resources(env.pd(), env.rm(), ram_quota, cap_quota, tx_buf_size), Session_rpc_object(_packet_ds.cap(), env.rm(), env.ep().rpc_ep()), @@ -456,7 +456,7 @@ class Vfs_server::Session_component : private Session_resources, _active_sessions(active_sessions), _root_path(root_path), _label(label), - _writable(writable) + _writeable(writeable) { _tx.sigh_packet_avail(_packet_stream_handler); _tx.sigh_ready_to_ack(_packet_stream_handler); @@ -490,7 +490,7 @@ class Vfs_server::Session_component : private Session_resources, Dir_handle dir(::File_system::Path const &path, bool create) override { - if (create && (!_writable)) + if (create && (!_writeable)) throw Permission_denied(); char const *path_str = path.string(); @@ -507,8 +507,11 @@ class Vfs_server::Session_component : private Session_resources, if (!create && !_vfs.directory(path_str)) throw Lookup_failed(); + typedef Directory::Session_writeable Writeable; + Directory &dir = *new (_alloc) - Directory(_node_space, _vfs, _alloc, path_str, create); + Directory(_node_space, _vfs, _alloc, path_str, create, + _writeable ? Writeable::WRITEABLE : Writeable::READ_ONLY); if (create) _io_progress_handler.handle_io_progress(); @@ -519,7 +522,7 @@ class Vfs_server::Session_component : private Session_resources, File_handle file(Dir_handle dir_handle, Name const &name, Mode fs_mode, bool create) override { - if ((create || (fs_mode & WRITE_ONLY)) && (!_writable)) + if ((create || (fs_mode & WRITE_ONLY)) && (!_writeable)) throw Permission_denied(); return _apply(dir_handle, [&] (Directory &dir) { @@ -534,7 +537,7 @@ class Vfs_server::Session_component : private Session_resources, Symlink_handle symlink(Dir_handle dir_handle, Name const &name, bool create) override { - if (create && !_writable) throw Permission_denied(); + if (create && !_writeable) throw Permission_denied(); return _apply(dir_handle, [&] (Directory &dir) { char const *name_str = name.string(); @@ -542,7 +545,7 @@ class Vfs_server::Session_component : private Session_resources, return Symlink_handle { dir.symlink(_node_space, _vfs, _alloc, name_str, - _writable ? READ_WRITE : READ_ONLY, create).value + _writeable ? READ_WRITE : READ_ONLY, create).value }; }); } @@ -669,7 +672,7 @@ class Vfs_server::Session_component : private Session_resources, .type = fs_node_type(vfs_stat.type), .rwx = { .readable = vfs_stat.rwx.readable, - .writeable = vfs_stat.rwx.writeable, + .writeable = vfs_stat.rwx.writeable && _writeable, .executable = vfs_stat.rwx.executable }, .inode = vfs_stat.inode, @@ -682,7 +685,7 @@ class Vfs_server::Session_component : private Session_resources, void unlink(Dir_handle dir_handle, Name const &name) override { - if (!_writable) throw Permission_denied(); + if (!_writeable) throw Permission_denied(); _apply(dir_handle, [&] (Directory &dir) { char const *name_str = name.string(); @@ -711,7 +714,7 @@ class Vfs_server::Session_component : private Session_resources, void move(Dir_handle from_dir_handle, Name const &from_name, Dir_handle to_dir_handle, Name const &to_name) override { - if (!_writable) + if (!_writeable) throw Permission_denied(); char const *from_str = from_name.string(); diff --git a/repos/os/src/server/vfs/node.h b/repos/os/src/server/vfs/node.h index ba64b8d92..80d3e1598 100644 --- a/repos/os/src/server/vfs/node.h +++ b/repos/os/src/server/vfs/node.h @@ -859,8 +859,14 @@ class Vfs_server::File : public Io_node struct Vfs_server::Directory : Io_node { + public: + + enum class Session_writeable { READ_ONLY, WRITEABLE }; + private: + Session_writeable const _writeable; + typedef Directory_service::Dirent Vfs_dirent; typedef File_system::Directory_entry Fs_dirent; @@ -878,7 +884,7 @@ struct Vfs_server::Directory : Io_node return true; } - static Fs_dirent _convert_dirent(Vfs_dirent from) + static Fs_dirent _convert_dirent(Vfs_dirent from, Session_writeable writeable) { from.sanitize(); @@ -908,7 +914,8 @@ struct Vfs_server::Directory : Io_node .type = fs_dirent_type(from.type), .rwx = { .readable = from.rwx.readable, - .writeable = from.rwx.writeable, + .writeable = (writeable == Session_writeable::WRITEABLE) + ? from.rwx.writeable : false, .executable = from.rwx.executable }, .name = { from.name.buf } }; @@ -939,7 +946,7 @@ struct Vfs_server::Directory : Io_node if (vfs_dirent.type == Vfs::Directory_service::Dirent_type::END) break; - fs_dirent = _convert_dirent(vfs_dirent); + fs_dirent = _convert_dirent(vfs_dirent, _writeable); converted_length += step; } @@ -961,9 +968,11 @@ struct Vfs_server::Directory : Io_node Vfs::File_system &vfs, Genode::Allocator &alloc, char const *path, - bool create) + bool create, + Session_writeable writeable) : - Io_node(space, path, READ_ONLY, _open(vfs, alloc, path, create)) + Io_node(space, path, READ_ONLY, _open(vfs, alloc, path, create)), + _writeable(writeable) { } /**