From 30b71330084498e9496e1da3788953f57bb9f3d2 Mon Sep 17 00:00:00 2001 From: Daeyeon Jeong Date: Sun, 7 May 2023 18:58:25 +0900 Subject: [PATCH] src: clarify the parameter name in `Permission::Apply` This fixes confusing parameter names. They are references to set allow-permission. Signed-off-by: Daeyeon Jeong PR-URL: https://github.com/nodejs/node/pull/47874 Reviewed-By: Rafael Gonzaga Reviewed-By: Debadree Chatterjee --- src/permission/child_process_permission.cc | 23 +++++++ src/permission/child_process_permission.h | 28 +++++++++ src/permission/fs_permission.h | 2 +- src/permission/permission.h | 71 ++++++++++++++++++++++ src/permission/permission_base.h | 49 +++++++++++++++ src/permission/worker_permission.cc | 22 +++++++ src/permission/worker_permission.h | 28 +++++++++ 7 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 src/permission/child_process_permission.cc create mode 100644 src/permission/child_process_permission.h create mode 100644 src/permission/permission.h create mode 100644 src/permission/permission_base.h create mode 100644 src/permission/worker_permission.cc create mode 100644 src/permission/worker_permission.h diff --git a/src/permission/child_process_permission.cc b/src/permission/child_process_permission.cc new file mode 100644 index 00000000000000..7151eb15f90da2 --- /dev/null +++ b/src/permission/child_process_permission.cc @@ -0,0 +1,23 @@ +#include "child_process_permission.h" + +#include +#include + +namespace node { + +namespace permission { + +// Currently, ChildProcess manage a single state +// Once denied, it's always denied +void ChildProcessPermission::Apply(const std::string& allow, + PermissionScope scope) { + deny_all_ = true; +} + +bool ChildProcessPermission::is_granted(PermissionScope perm, + const std::string_view& param) { + return deny_all_ == false; +} + +} // namespace permission +} // namespace node diff --git a/src/permission/child_process_permission.h b/src/permission/child_process_permission.h new file mode 100644 index 00000000000000..b67169f1c4e180 --- /dev/null +++ b/src/permission/child_process_permission.h @@ -0,0 +1,28 @@ +#ifndef SRC_PERMISSION_CHILD_PROCESS_PERMISSION_H_ +#define SRC_PERMISSION_CHILD_PROCESS_PERMISSION_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include +#include "permission/permission_base.h" + +namespace node { + +namespace permission { + +class ChildProcessPermission final : public PermissionBase { + public: + void Apply(const std::string& allow, PermissionScope scope) override; + bool is_granted(PermissionScope perm, + const std::string_view& param = "") override; + + private: + bool deny_all_; +}; + +} // namespace permission + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS +#endif // SRC_PERMISSION_CHILD_PROCESS_PERMISSION_H_ diff --git a/src/permission/fs_permission.h b/src/permission/fs_permission.h index f393c6a042e662..7ac987c7118ca1 100644 --- a/src/permission/fs_permission.h +++ b/src/permission/fs_permission.h @@ -16,7 +16,7 @@ namespace permission { class FSPermission final : public PermissionBase { public: - void Apply(const std::string& deny, PermissionScope scope) override; + void Apply(const std::string& allow, PermissionScope scope) override; bool is_granted(PermissionScope perm, const std::string_view& param) override; // For debugging purposes, use the gist function to print the whole tree diff --git a/src/permission/permission.h b/src/permission/permission.h new file mode 100644 index 00000000000000..61341ab29134f2 --- /dev/null +++ b/src/permission/permission.h @@ -0,0 +1,71 @@ +#ifndef SRC_PERMISSION_PERMISSION_H_ +#define SRC_PERMISSION_PERMISSION_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "debug_utils.h" +#include "node_options.h" +#include "permission/child_process_permission.h" +#include "permission/fs_permission.h" +#include "permission/permission_base.h" +#include "permission/worker_permission.h" +#include "v8.h" + +#include +#include + +namespace node { + +class Environment; + +namespace permission { + +#define THROW_IF_INSUFFICIENT_PERMISSIONS(env, perm_, resource_, ...) \ + do { \ + if (UNLIKELY(!(env)->permission()->is_granted(perm_, resource_))) { \ + node::permission::Permission::ThrowAccessDenied( \ + (env), perm_, resource_); \ + return __VA_ARGS__; \ + } \ + } while (0) + +class Permission { + public: + Permission(); + + FORCE_INLINE bool is_granted(const PermissionScope permission, + const std::string_view& res = "") const { + if (LIKELY(!enabled_)) return true; + return is_scope_granted(permission, res); + } + + static PermissionScope StringToPermission(const std::string& perm); + static const char* PermissionToString(PermissionScope perm); + static void ThrowAccessDenied(Environment* env, + PermissionScope perm, + const std::string_view& res); + + // CLI Call + void Apply(const std::string& allow, PermissionScope scope); + void EnablePermissions(); + + private: + COLD_NOINLINE bool is_scope_granted(const PermissionScope permission, + const std::string_view& res = "") const { + auto perm_node = nodes_.find(permission); + if (perm_node != nodes_.end()) { + return perm_node->second->is_granted(permission, res); + } + return false; + } + + std::unordered_map> nodes_; + bool enabled_; +}; + +} // namespace permission + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS +#endif // SRC_PERMISSION_PERMISSION_H_ diff --git a/src/permission/permission_base.h b/src/permission/permission_base.h new file mode 100644 index 00000000000000..86fefa06e65c57 --- /dev/null +++ b/src/permission/permission_base.h @@ -0,0 +1,49 @@ +#ifndef SRC_PERMISSION_PERMISSION_BASE_H_ +#define SRC_PERMISSION_PERMISSION_BASE_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include +#include +#include +#include "v8.h" + +namespace node { + +namespace permission { + +#define FILESYSTEM_PERMISSIONS(V) \ + V(FileSystem, "fs", PermissionsRoot) \ + V(FileSystemRead, "fs.read", FileSystem) \ + V(FileSystemWrite, "fs.write", FileSystem) + +#define CHILD_PROCESS_PERMISSIONS(V) V(ChildProcess, "child", PermissionsRoot) + +#define WORKER_THREADS_PERMISSIONS(V) \ + V(WorkerThreads, "worker", PermissionsRoot) + +#define PERMISSIONS(V) \ + FILESYSTEM_PERMISSIONS(V) \ + CHILD_PROCESS_PERMISSIONS(V) \ + WORKER_THREADS_PERMISSIONS(V) + +#define V(name, _, __) k##name, +enum class PermissionScope { + kPermissionsRoot = -1, + PERMISSIONS(V) kPermissionsCount +}; +#undef V + +class PermissionBase { + public: + virtual void Apply(const std::string& allow, PermissionScope scope) = 0; + virtual bool is_granted(PermissionScope perm, + const std::string_view& param = "") = 0; +}; + +} // namespace permission + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS +#endif // SRC_PERMISSION_PERMISSION_BASE_H_ diff --git a/src/permission/worker_permission.cc b/src/permission/worker_permission.cc new file mode 100644 index 00000000000000..69c89a4a4fea87 --- /dev/null +++ b/src/permission/worker_permission.cc @@ -0,0 +1,22 @@ +#include "permission/worker_permission.h" + +#include +#include + +namespace node { + +namespace permission { + +// Currently, PolicyDenyWorker manage a single state +// Once denied, it's always denied +void WorkerPermission::Apply(const std::string& allow, PermissionScope scope) { + deny_all_ = true; +} + +bool WorkerPermission::is_granted(PermissionScope perm, + const std::string_view& param) { + return deny_all_ == false; +} + +} // namespace permission +} // namespace node diff --git a/src/permission/worker_permission.h b/src/permission/worker_permission.h new file mode 100644 index 00000000000000..71681a4485a82f --- /dev/null +++ b/src/permission/worker_permission.h @@ -0,0 +1,28 @@ +#ifndef SRC_PERMISSION_WORKER_PERMISSION_H_ +#define SRC_PERMISSION_WORKER_PERMISSION_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include +#include "permission/permission_base.h" + +namespace node { + +namespace permission { + +class WorkerPermission final : public PermissionBase { + public: + void Apply(const std::string& allow, PermissionScope scope) override; + bool is_granted(PermissionScope perm, + const std::string_view& param = "") override; + + private: + bool deny_all_; +}; + +} // namespace permission + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS +#endif // SRC_PERMISSION_WORKER_PERMISSION_H_