From 3aaed7188fcc66b881a8be56eebd17f0d169f386 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 21 Nov 2019 12:24:35 +0100 Subject: [PATCH] ram_fs: tie writeable bit to session policy Related to issue #3507 --- repos/os/src/server/ram_fs/directory.h | 19 +++++++-------- repos/os/src/server/ram_fs/file.h | 16 ++++++------- repos/os/src/server/ram_fs/main.cc | 32 ++++++++++++++------------ repos/os/src/server/ram_fs/node.h | 10 ++++++-- repos/os/src/server/ram_fs/symlink.h | 16 ++++++------- 5 files changed, 51 insertions(+), 42 deletions(-) diff --git a/repos/os/src/server/ram_fs/directory.h b/repos/os/src/server/ram_fs/directory.h index c07835c9c..8b4919b92 100644 --- a/repos/os/src/server/ram_fs/directory.h +++ b/repos/os/src/server/ram_fs/directory.h @@ -181,7 +181,8 @@ class Ram_fs::Directory : public Node return static_cast(lookup(path, true)); } - size_t read(char *dst, size_t len, seek_off_t seek_offset) override + size_t read(char *dst, size_t len, seek_off_t seek_offset, + Session_writeable writeable) override { using File_system::Directory_entry; @@ -218,7 +219,7 @@ class Ram_fs::Directory : public Node .inode = node->inode(), .type = type(), .rwx = { .readable = true, - .writeable = true, + .writeable = writeable == Session_writeable::WRITEABLE, .executable = true }, .name = { node->name() } }; @@ -232,15 +233,15 @@ class Ram_fs::Directory : public Node return 0; } - Status status() override + Status status(Session_writeable writeable) override { return { - .size = _num_entries * sizeof(File_system::Directory_entry), - .type = File_system::Node_type::DIRECTORY, - .rwx = { .readable = true, - .writeable = true, - .executable = true }, - .inode = inode(), + .size = _num_entries * sizeof(File_system::Directory_entry), + .type = File_system::Node_type::DIRECTORY, + .rwx = { .readable = true, + .writeable = (writeable == Session_writeable::WRITEABLE), + .executable = true }, + .inode = inode(), .modification_time = modification_time() }; } diff --git a/repos/os/src/server/ram_fs/file.h b/repos/os/src/server/ram_fs/file.h index 1c8ee2dfe..507be0eec 100644 --- a/repos/os/src/server/ram_fs/file.h +++ b/repos/os/src/server/ram_fs/file.h @@ -51,7 +51,7 @@ class Ram_fs::File : public Node File(Allocator &alloc, char const *name) : _chunk(alloc, 0), _length(0) { Node::name(name); } - size_t read(char *dst, size_t len, seek_off_t seek_offset) override + size_t read(char *dst, size_t len, seek_off_t seek_offset, Session_writeable) override { file_size_t const chunk_used_size = _chunk.used_size(); @@ -110,15 +110,15 @@ class Ram_fs::File : public Node return len; } - Status status() override + Status status(Session_writeable writeable) override { return { - .size = _length, - .type = File_system::Node_type::CONTINUOUS_FILE, - .rwx = { .readable = true, - .writeable = true, - .executable = true }, - .inode = inode(), + .size = _length, + .type = File_system::Node_type::CONTINUOUS_FILE, + .rwx = { .readable = true, + .writeable = (writeable == Session_writeable::WRITEABLE), + .executable = true }, + .inode = inode(), .modification_time = modification_time() }; } diff --git a/repos/os/src/server/ram_fs/main.cc b/repos/os/src/server/ram_fs/main.cc index f7e744d8b..54adfc9de 100644 --- a/repos/os/src/server/ram_fs/main.cc +++ b/repos/os/src/server/ram_fs/main.cc @@ -51,7 +51,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object Genode::Allocator &_alloc; Directory &_root; Id_space _open_node_registry { }; - bool _writable; + Session_writeable const _writeable; Signal_handler _process_packet_handler; @@ -81,10 +81,10 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object if (!node.valid()) break; res_length = node->read((char *)tx_sink()->packet_content(packet), - length, packet.position()); + length, packet.position(), _writeable); /* read data or EOF is a success */ - succeeded = res_length || (packet.position() >= node->status().size); + succeeded = res_length || (packet.position() >= node->status(_writeable).size); } break; @@ -208,14 +208,14 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object Session_component(size_t tx_buf_size, Genode::Entrypoint &ep, Genode::Ram_allocator &ram, Genode::Region_map &rm, Genode::Allocator &alloc, - Directory &root, bool writable) + Directory &root, Session_writeable writeable) : Session_rpc_object(ram.alloc(tx_buf_size), rm, ep.rpc_ep()), _ep(ep), _ram(ram), _alloc(alloc), _root(root), - _writable(writable), + _writeable(writeable), _process_packet_handler(_ep, *this, &Session_component::_process_packets) { /* @@ -253,13 +253,13 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object if (!dir.valid()) throw Unavailable(); - if (!_writable) + if (_writeable == Session_writeable::READ_ONLY) if (mode != STAT_ONLY && mode != READ_ONLY) throw Permission_denied(); if (create) { - if (!_writable) + if (_writeable == Session_writeable::READ_ONLY) throw Permission_denied(); if (dir->has_sub_node_unsynchronized(name.string())) @@ -305,7 +305,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object if (create) { - if (!_writable) + if (_writeable == Session_writeable::READ_ONLY) throw Permission_denied(); if (dir->has_sub_node_unsynchronized(name.string())) @@ -348,7 +348,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object if (create) { - if (!_writable) + if (_writeable == Session_writeable::READ_ONLY) throw Permission_denied(); if (!path.valid_string()) @@ -424,8 +424,8 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object auto status_fn = [&] (Open_node &open_node) { Locked_ptr node { open_node.node() }; if (!node.valid()) - throw Unavailable(); - return node->status(); + throw Unavailable(); + return node->status(_writeable); }; try { @@ -442,7 +442,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object if (!valid_name(name.string())) throw Invalid_name(); - if (!_writable) + if (_writeable == Session_writeable::READ_ONLY) throw Permission_denied(); auto unlink_fn = [&] (Open_node &open_node) { @@ -468,7 +468,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object void truncate(File_handle file_handle, file_size_t size) override { - if (!_writable) + if (_writeable == Session_writeable::READ_ONLY) throw Permission_denied(); auto truncate_fn = [&] (Open_node &open_node) { @@ -489,7 +489,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object 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 == Session_writeable::READ_ONLY) throw Permission_denied(); if (!valid_name(from_name.string())) @@ -642,7 +642,9 @@ class Ram_fs::Root : public Root_component } return new (md_alloc()) Session_component(tx_buf_size, _ep, _ram, _rm, _alloc, - *session_root_dir, writeable); + *session_root_dir, + writeable ? Session_writeable::WRITEABLE + : Session_writeable::READ_ONLY); } public: diff --git a/repos/os/src/server/ram_fs/node.h b/repos/os/src/server/ram_fs/node.h index e2905f270..d044a6a72 100644 --- a/repos/os/src/server/ram_fs/node.h +++ b/repos/os/src/server/ram_fs/node.h @@ -27,6 +27,8 @@ namespace Ram_fs { class Node; class File; class Symlink; + + enum class Session_writeable { READ_ONLY, WRITEABLE }; } @@ -86,10 +88,14 @@ class Ram_fs::Node : public File_system::Node_base, Timestamp modification_time() const { return _modification_time; } - virtual size_t read(char *dst, size_t len, seek_off_t) = 0; + /* + * 'Session_writeable' is supplied to the 'read' method to reflect the + * writeability in directory entries read from 'Directory' nodes. + */ + virtual size_t read(char *dst, size_t len, seek_off_t, Session_writeable) = 0; virtual size_t write(char const *src, size_t len, seek_off_t) = 0; - virtual Status status() = 0; + virtual Status status(Session_writeable) = 0; /* File functionality */ diff --git a/repos/os/src/server/ram_fs/symlink.h b/repos/os/src/server/ram_fs/symlink.h index 23689a4ff..099afe7d1 100644 --- a/repos/os/src/server/ram_fs/symlink.h +++ b/repos/os/src/server/ram_fs/symlink.h @@ -31,7 +31,7 @@ class Ram_fs::Symlink : public Node Symlink(char const *name): _len(0) { Node::name(name); } - size_t read(char *dst, size_t len, seek_off_t seek_offset) override + size_t read(char *dst, size_t len, seek_off_t seek_offset, Session_writeable) override { size_t count = min(len, _len-seek_offset); Genode::memcpy(dst, _link_to+seek_offset, count); @@ -65,15 +65,15 @@ class Ram_fs::Symlink : public Node return consumed_len; } - Status status() override + Status status(Session_writeable writeable) override { return { - .size = _len, - .type = File_system::Node_type::SYMLINK, - .rwx = { .readable = true, - .writeable = true, - .executable = true }, - .inode = inode(), + .size = _len, + .type = File_system::Node_type::SYMLINK, + .rwx = { .readable = true, + .writeable = (writeable == Session_writeable::WRITEABLE), + .executable = true }, + .inode = inode(), .modification_time = modification_time() }; }