From: Gunnar Beutner Date: Mon, 26 Oct 2015 09:41:00 +0000 (+0100) Subject: Don't allow scripts to access FANoUserView attributes in sandbox mode X-Git-Tag: v2.4.0~138 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=de847d0b6f475d35c76abc508a9a14cd79cf802c;p=icinga2 Don't allow scripts to access FANoUserView attributes in sandbox mode fixes #10457 --- diff --git a/lib/config/expression.cpp b/lib/config/expression.cpp index 1c4dcea29..5290a9897 100644 --- a/lib/config/expression.cpp +++ b/lib/config/expression.cpp @@ -99,7 +99,7 @@ ExpressionResult VariableExpression::DoEvaluate(ScriptFrame& frame, DebugHint *d if (frame.Locals && frame.Locals->Get(m_Variable, &value)) return value; else if (frame.Self.IsObject() && frame.Locals != static_cast(frame.Self) && VMOps::HasField(frame.Self, m_Variable)) - return VMOps::GetField(frame.Self, m_Variable, m_DebugInfo); + return VMOps::GetField(frame.Self, m_Variable, frame.Sandboxed, m_DebugInfo); else return ScriptGlobal::Get(m_Variable); } @@ -391,7 +391,7 @@ ExpressionResult FunctionCallExpression::DoEvaluate(ScriptFrame& frame, DebugHin String index; if (m_FName->GetReference(frame, false, &self, &index)) - vfunc = VMOps::GetField(self, index, m_DebugInfo); + vfunc = VMOps::GetField(self, index, frame.Sandboxed, m_DebugInfo); else { ExpressionResult vfuncres = m_FName->Evaluate(frame); CHECK_RESULT(vfuncres); @@ -504,7 +504,7 @@ ExpressionResult SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) CHECK_RESULT(operand2); if (m_Op != OpSetLiteral) { - Value object = VMOps::GetField(parent, index, m_DebugInfo); + Value object = VMOps::GetField(parent, index, frame.Sandboxed, m_DebugInfo); switch (m_Op) { case OpSetAdd: @@ -606,7 +606,7 @@ ExpressionResult IndexerExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dh ExpressionResult operand2 = m_Operand2->Evaluate(frame, dhint); CHECK_RESULT(operand2); - return VMOps::GetField(operand1.GetValue(), operand2.GetValue(), m_DebugInfo); + return VMOps::GetField(operand1.GetValue(), operand2.GetValue(), frame.Sandboxed, m_DebugInfo); } bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const @@ -624,13 +624,13 @@ bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value * if (m_Operand1->GetReference(frame, init_dict, &vparent, &vindex, &psdhint)) { if (init_dict) { - Value old_value = VMOps::GetField(vparent, vindex, m_Operand1->GetDebugInfo()); + Value old_value = VMOps::GetField(vparent, vindex, frame.Sandboxed, m_Operand1->GetDebugInfo()); if (old_value.IsEmpty() && !old_value.IsString()) VMOps::SetField(vparent, vindex, new Dictionary(), m_Operand1->GetDebugInfo()); } - *parent = VMOps::GetField(vparent, vindex, m_DebugInfo); + *parent = VMOps::GetField(vparent, vindex, frame.Sandboxed, m_DebugInfo); free_psd = true; } else { ExpressionResult operand1 = m_Operand1->Evaluate(frame); @@ -706,7 +706,7 @@ ExpressionResult ImportExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhi if (frame.Sandboxed) BOOST_THROW_EXCEPTION(ScriptError("Imports are not allowed in sandbox mode.", m_DebugInfo)); - String type = VMOps::GetField(frame.Self, "type", m_DebugInfo); + String type = VMOps::GetField(frame.Self, "type", frame.Sandboxed, m_DebugInfo); ExpressionResult nameres = m_Name->Evaluate(frame); CHECK_RESULT(nameres); Value name = nameres.GetValue(); diff --git a/lib/config/vmops.hpp b/lib/config/vmops.hpp index 0027a12d2..760c5708a 100644 --- a/lib/config/vmops.hpp +++ b/lib/config/vmops.hpp @@ -50,7 +50,7 @@ public: if (frame.Locals && frame.Locals->Get(name, &value)) return value; else if (frame.Self.IsObject() && frame.Locals != static_cast(frame.Self) && HasField(frame.Self, name)) - return GetField(frame.Self, name, debugInfo); + return GetField(frame.Self, name, frame.Sandboxed, debugInfo); else return ScriptGlobal::Get(name); } @@ -219,7 +219,7 @@ public: Object::Ptr object = type->GetPrototype(); if (object && HasField(object, field)) - return GetField(object, field, debugInfo); + return GetField(object, field, false, debugInfo); type = type->GetBaseType(); } while (type); @@ -230,7 +230,7 @@ public: return Empty; } - static inline Value GetField(const Value& context, const String& field, const DebugInfo& debugInfo = DebugInfo()) + static inline Value GetField(const Value& context, const String& field, bool sandboxed = false, const DebugInfo& debugInfo = DebugInfo()) { if (context.IsEmpty() && !context.IsString()) return Empty; @@ -277,6 +277,13 @@ public: if (fid == -1) return GetPrototypeField(context, field, true, debugInfo); + if (sandboxed) { + Field fieldInfo = type->GetFieldInfo(fid); + + if (fieldInfo.Attributes & FANoUserView) + BOOST_THROW_EXCEPTION(ScriptError("Accessing the field '" + field + "' for type '" + type->GetName() + "' is not allowed in sandbox mode.")); + } + return object->GetField(fid); }