From dde11de00820a7594e744331290979958c55e8fa Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Mon, 3 Apr 2017 12:24:19 -0500 Subject: [PATCH] Unify client policy across File_system servers File_system servers shall deny clients not matching a defined policy. Servers shall also apply session root offset policy followed by a client offset. Fix #2365 --- repos/dde_rump/src/server/rump_fs/main.cc | 22 +++----- repos/os/src/server/ram_fs/main.cc | 68 +++++++++++++---------- repos/os/src/server/vfs/main.cc | 21 +++---- 3 files changed, 56 insertions(+), 55 deletions(-) diff --git a/repos/dde_rump/src/server/rump_fs/main.cc b/repos/dde_rump/src/server/rump_fs/main.cc index 577c4600df..6009ad42b4 100644 --- a/repos/dde_rump/src/server/rump_fs/main.cc +++ b/repos/dde_rump/src/server/rump_fs/main.cc @@ -410,28 +410,24 @@ class File_system::Root : public Root_component try { Session_policy policy(label); - /* Determine the session root directory. - * Defaults to '/' if not specified by session - * policy or session arguments. - */ + /* determine policy root offset */ try { policy.attribute("root").value(tmp, sizeof(tmp)); session_root.import(tmp, "/"); } catch (Xml_node::Nonexistent_attribute) { } - /* Determine if the session is writeable. - * Policy overrides arguments, both default to false. + /* + * Determine if the session is writeable. + * Policy overrides client argument, both default to false. */ if (policy.attribute_value("writeable", false)) writeable = Arg_string::find_arg(args, "writeable").bool_value(false); + } catch (Session_policy::No_policy_defined) { + /* missing policy - deny request */ + throw Root::Unavailable(); + } - } catch (...) { } - - /* - * If no policy matches the client gets - * read-only access to the root. - */ - + /* apply client's root offset */ Arg_string::find_arg(args, "root").string(tmp, sizeof(tmp), "/"); if (Genode::strcmp("/", tmp, sizeof(tmp))) { session_root.append("/"); diff --git a/repos/os/src/server/ram_fs/main.cc b/repos/os/src/server/ram_fs/main.cc index 89a4cc01f5..653d363be0 100644 --- a/repos/os/src/server/ram_fs/main.cc +++ b/repos/os/src/server/ram_fs/main.cc @@ -441,12 +441,12 @@ class File_system::Root : public Root_component * the client's label. */ - Directory *session_root_dir = 0; - bool writeable = false; - enum { ROOT_MAX_LEN = 256 }; - char root[ROOT_MAX_LEN]; - root[0] = 0; + Genode::Path session_root; + char tmp[MAX_PATH_LEN]; + + Directory *session_root_dir = nullptr; + bool writeable = false; Session_label const label = label_from_args(args); try { @@ -454,48 +454,56 @@ class File_system::Root : public Root_component /* * Determine directory that is used as root directory of - * the session. + * the session. Clients without a specified root are denied. */ try { - policy.attribute("root").value(root, sizeof(root)); - if (strcmp("/", root) == 0) { - session_root_dir = &_root_dir; - } else { - - /* - * Make sure the root path is specified with a - * leading path delimiter. For performing the - * lookup, we skip the first character. - */ - if (root[0] != '/') - throw Lookup_failed(); - - session_root_dir = _root_dir.lookup_and_lock_dir(root + 1); - session_root_dir->unlock(); - } + policy.attribute("root").value(tmp, sizeof(tmp)); + session_root.import(tmp, "/"); } catch (Xml_node::Nonexistent_attribute) { Genode::error("missing \"root\" attribute in policy definition"); throw Root::Unavailable(); - } catch (Lookup_failed) { - Genode::error("session root directory \"", - Genode::Cstring(root), "\" does not exist"); - throw Root::Unavailable(); } /* - * Determine if write access is permitted for the session. + * Determine if the session is writeable. + * Policy overrides client argument, both default to false. */ - writeable = policy.attribute_value("writeable", false); + if (policy.attribute_value("writeable", false)) + writeable = Arg_string::find_arg(args, "writeable").bool_value(false); } catch (Session_policy::No_policy_defined) { Genode::error("invalid session request, no matching policy"); throw Root::Unavailable(); } + /* apply client's root offset */ + Arg_string::find_arg(args, "root").string(tmp, sizeof(tmp), "/"); + if (Genode::strcmp("/", tmp, sizeof(tmp))) { + session_root.append("/"); + session_root.append(tmp); + } + session_root.remove_trailing('/'); + if (session_root == "/") { + session_root_dir = &_root_dir; + } else { + try { + /* + * The root path is specified with a leading path + * delimiter. For performing the lookup, we skip the first + * character. + */ + session_root_dir = _root_dir.lookup_and_lock_dir( + session_root.base() + 1); + session_root_dir->unlock(); + } catch (Lookup_failed) { + throw Root::Unavailable(); + } + } + size_t ram_quota = - Arg_string::find_arg(args, "ram_quota" ).ulong_value(0); + Arg_string::find_arg(args, "ram_quota" ).aligned_size(); size_t tx_buf_size = - Arg_string::find_arg(args, "tx_buf_size").ulong_value(0); + Arg_string::find_arg(args, "tx_buf_size").aligned_size(); if (!tx_buf_size) { Genode::error(label, " requested a session with a zero length transmission buffer"); diff --git a/repos/os/src/server/vfs/main.cc b/repos/os/src/server/vfs/main.cc index 1bfd9fe668..2eee9ac5d4 100644 --- a/repos/os/src/server/vfs/main.cc +++ b/repos/os/src/server/vfs/main.cc @@ -685,34 +685,31 @@ class Vfs_server::Root : try { Session_policy policy(label, _config_rom.xml()); - /* Determine the session root directory. - * Defaults to '/' if not specified by session - * policy or session arguments. - */ + /* determine optional session root offset. */ try { policy.attribute("root").value(tmp, sizeof(tmp)); session_root.import(tmp, "/"); } catch (Xml_node::Nonexistent_attribute) { } - /* Determine if the session is writeable. - * Policy overrides arguments, both default to false. + /* + * Determine if the session is writeable. + * Policy overrides client argument, both default to false. */ if (policy.attribute_value("writeable", false)) writeable = Arg_string::find_arg(args, "writeable").bool_value(false); - } catch (Session_policy::No_policy_defined) { } + } catch (Session_policy::No_policy_defined) { + /* missing policy - deny request */ + throw Root::Unavailable(); + } + /* apply client's root offset. */ Arg_string::find_arg(args, "root").string(tmp, sizeof(tmp), "/"); if (Genode::strcmp("/", tmp, sizeof(tmp))) { session_root.append("/"); session_root.append(tmp); } - /* - * If no policy matches the client gets - * read-only access to the root. - */ - /* check if the session root exists */ if (!((session_root == "/") || _vfs.directory(session_root.base()))) { error("session root '", session_root, "' not found for '", label, "'");