mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-04 09:43:06 +00:00
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
This commit is contained in:
parent
2668a55688
commit
dde11de008
@ -410,28 +410,24 @@ class File_system::Root : public Root_component<Session_component>
|
|||||||
try {
|
try {
|
||||||
Session_policy policy(label);
|
Session_policy policy(label);
|
||||||
|
|
||||||
/* Determine the session root directory.
|
/* determine policy root offset */
|
||||||
* Defaults to '/' if not specified by session
|
|
||||||
* policy or session arguments.
|
|
||||||
*/
|
|
||||||
try {
|
try {
|
||||||
policy.attribute("root").value(tmp, sizeof(tmp));
|
policy.attribute("root").value(tmp, sizeof(tmp));
|
||||||
session_root.import(tmp, "/");
|
session_root.import(tmp, "/");
|
||||||
} catch (Xml_node::Nonexistent_attribute) { }
|
} 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))
|
if (policy.attribute_value("writeable", false))
|
||||||
writeable = Arg_string::find_arg(args, "writeable").bool_value(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 (...) { }
|
/* apply client's root offset */
|
||||||
|
|
||||||
/*
|
|
||||||
* If no policy matches the client gets
|
|
||||||
* read-only access to the root.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Arg_string::find_arg(args, "root").string(tmp, sizeof(tmp), "/");
|
Arg_string::find_arg(args, "root").string(tmp, sizeof(tmp), "/");
|
||||||
if (Genode::strcmp("/", tmp, sizeof(tmp))) {
|
if (Genode::strcmp("/", tmp, sizeof(tmp))) {
|
||||||
session_root.append("/");
|
session_root.append("/");
|
||||||
|
@ -441,12 +441,12 @@ class File_system::Root : public Root_component<Session_component>
|
|||||||
* the client's label.
|
* the client's label.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Directory *session_root_dir = 0;
|
|
||||||
bool writeable = false;
|
|
||||||
|
|
||||||
enum { ROOT_MAX_LEN = 256 };
|
enum { ROOT_MAX_LEN = 256 };
|
||||||
char root[ROOT_MAX_LEN];
|
Genode::Path<MAX_PATH_LEN> session_root;
|
||||||
root[0] = 0;
|
char tmp[MAX_PATH_LEN];
|
||||||
|
|
||||||
|
Directory *session_root_dir = nullptr;
|
||||||
|
bool writeable = false;
|
||||||
|
|
||||||
Session_label const label = label_from_args(args);
|
Session_label const label = label_from_args(args);
|
||||||
try {
|
try {
|
||||||
@ -454,48 +454,56 @@ class File_system::Root : public Root_component<Session_component>
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine directory that is used as root directory of
|
* Determine directory that is used as root directory of
|
||||||
* the session.
|
* the session. Clients without a specified root are denied.
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
policy.attribute("root").value(root, sizeof(root));
|
policy.attribute("root").value(tmp, sizeof(tmp));
|
||||||
if (strcmp("/", root) == 0) {
|
session_root.import(tmp, "/");
|
||||||
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();
|
|
||||||
}
|
|
||||||
} catch (Xml_node::Nonexistent_attribute) {
|
} catch (Xml_node::Nonexistent_attribute) {
|
||||||
Genode::error("missing \"root\" attribute in policy definition");
|
Genode::error("missing \"root\" attribute in policy definition");
|
||||||
throw Root::Unavailable();
|
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) {
|
} catch (Session_policy::No_policy_defined) {
|
||||||
Genode::error("invalid session request, no matching policy");
|
Genode::error("invalid session request, no matching policy");
|
||||||
throw Root::Unavailable();
|
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 =
|
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 =
|
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) {
|
if (!tx_buf_size) {
|
||||||
Genode::error(label, " requested a session with a zero length transmission buffer");
|
Genode::error(label, " requested a session with a zero length transmission buffer");
|
||||||
|
@ -685,34 +685,31 @@ class Vfs_server::Root :
|
|||||||
try {
|
try {
|
||||||
Session_policy policy(label, _config_rom.xml());
|
Session_policy policy(label, _config_rom.xml());
|
||||||
|
|
||||||
/* Determine the session root directory.
|
/* determine optional session root offset. */
|
||||||
* Defaults to '/' if not specified by session
|
|
||||||
* policy or session arguments.
|
|
||||||
*/
|
|
||||||
try {
|
try {
|
||||||
policy.attribute("root").value(tmp, sizeof(tmp));
|
policy.attribute("root").value(tmp, sizeof(tmp));
|
||||||
session_root.import(tmp, "/");
|
session_root.import(tmp, "/");
|
||||||
} catch (Xml_node::Nonexistent_attribute) { }
|
} 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))
|
if (policy.attribute_value("writeable", false))
|
||||||
writeable = Arg_string::find_arg(args, "writeable").bool_value(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), "/");
|
Arg_string::find_arg(args, "root").string(tmp, sizeof(tmp), "/");
|
||||||
if (Genode::strcmp("/", tmp, sizeof(tmp))) {
|
if (Genode::strcmp("/", tmp, sizeof(tmp))) {
|
||||||
session_root.append("/");
|
session_root.append("/");
|
||||||
session_root.append(tmp);
|
session_root.append(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If no policy matches the client gets
|
|
||||||
* read-only access to the root.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* check if the session root exists */
|
/* check if the session root exists */
|
||||||
if (!((session_root == "/") || _vfs.directory(session_root.base()))) {
|
if (!((session_root == "/") || _vfs.directory(session_root.base()))) {
|
||||||
error("session root '", session_root, "' not found for '", label, "'");
|
error("session root '", session_root, "' not found for '", label, "'");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user