Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 1156d30

Browse files
committed
Bug 856257 - Use a sandbox in nsJSConfigTriggers. r=mrbkap
1 parent 5f26132 commit 1156d30

1 file changed

Lines changed: 42 additions & 131 deletions

File tree

extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp

Lines changed: 42 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -22,147 +22,69 @@
2222
#include "nsContentUtils.h"
2323
#include "nsIScriptSecurityManager.h"
2424
#include "nsJSPrincipals.h"
25+
#include "jswrapper.h"
2526

2627
extern PRLogModuleInfo *MCD;
27-
28-
// Security Manager for new XPCONNECT enabled JS Context
29-
// Right now it allows all access
30-
31-
class AutoConfigSecMan MOZ_FINAL : public nsIXPCSecurityManager
32-
{
33-
public:
34-
NS_DECL_ISUPPORTS
35-
NS_DECL_NSIXPCSECURITYMANAGER
36-
AutoConfigSecMan();
37-
};
38-
39-
NS_IMPL_ISUPPORTS1(AutoConfigSecMan, nsIXPCSecurityManager)
40-
41-
AutoConfigSecMan::AutoConfigSecMan()
42-
{
43-
}
44-
45-
NS_IMETHODIMP
46-
AutoConfigSecMan::CanCreateWrapper(JSContext *aJSContext, const nsIID & aIID,
47-
nsISupports *aObj, nsIClassInfo *aClassInfo,
48-
void **aPolicy)
49-
{
50-
return NS_OK;
51-
}
52-
53-
NS_IMETHODIMP
54-
AutoConfigSecMan::CanCreateInstance(JSContext *aJSContext, const nsCID & aCID)
55-
{
56-
return NS_OK;
57-
}
58-
59-
NS_IMETHODIMP
60-
AutoConfigSecMan::CanGetService(JSContext *aJSContext, const nsCID & aCID)
61-
{
62-
return NS_OK;
63-
}
64-
65-
NS_IMETHODIMP
66-
AutoConfigSecMan::CanAccess(uint32_t aAction,
67-
nsAXPCNativeCallContext *aCallContext,
68-
JSContext *aJSContext, JSObject *aJSObject,
69-
nsISupports *aObj, nsIClassInfo *aClassInfo,
70-
jsid aName, void **aPolicy)
71-
{
72-
return NS_OK;
73-
}
28+
using mozilla::SafeAutoJSContext;
7429

7530
//*****************************************************************************
7631

77-
static JSContext *autoconfig_cx = nullptr;
78-
static JSObject *autoconfig_glob;
79-
80-
static JSClass global_class = {
81-
"autoconfig_global", JSCLASS_GLOBAL_FLAGS,
82-
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
83-
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nullptr
84-
};
85-
86-
static void
87-
autoConfigErrorReporter(JSContext *cx, const char *message,
88-
JSErrorReport *report)
89-
{
90-
NS_ERROR(message);
91-
PR_LOG(MCD, PR_LOG_DEBUG, ("JS error in js from MCD server: %s\n", message));
92-
}
32+
static JSObject *autoconfigSb = nullptr;
9333

9434
nsresult CentralizedAdminPrefManagerInit()
9535
{
9636
nsresult rv;
97-
JSRuntime *rt;
9837

99-
// If autoconfig_cx already created, no need to create it again
100-
if (autoconfig_cx)
38+
// If the sandbox is already created, no need to create it again.
39+
if (autoconfigSb)
10140
return NS_OK;
10241

103-
// We need the XPCONNECT service
42+
// Grab XPConnect.
10443
nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
10544
if (NS_FAILED(rv)) {
10645
return rv;
10746
}
10847

109-
// Get the JS RunTime
110-
nsCOMPtr<nsIJSRuntimeService> rtsvc =
111-
do_GetService("@mozilla.org/js/xpc/RuntimeService;1", &rv);
112-
if (NS_SUCCEEDED(rv))
113-
rv = rtsvc->GetRuntime(&rt);
114-
115-
if (NS_FAILED(rv)) {
116-
NS_ERROR("Couldn't get JS RunTime");
117-
return rv;
118-
}
119-
120-
// Create a new JS context for autoconfig JS script
121-
autoconfig_cx = JS_NewContext(rt, 1024);
122-
if (!autoconfig_cx)
123-
return NS_ERROR_OUT_OF_MEMORY;
124-
125-
JSAutoRequest ar(autoconfig_cx);
126-
127-
JS_SetErrorReporter(autoconfig_cx, autoConfigErrorReporter);
48+
// Grab the system principal.
49+
nsCOMPtr<nsIPrincipal> principal;
50+
nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(principal));
12851

129-
// Create a new Security Manger and set it for the new JS context
130-
nsCOMPtr<nsIXPCSecurityManager> secman =
131-
static_cast<nsIXPCSecurityManager*>(new AutoConfigSecMan());
132-
xpc->SetSecurityManagerForJSContext(autoconfig_cx, secman, 0);
13352

53+
// Create a sandbox.
54+
SafeAutoJSContext cx;
55+
JSAutoRequest ar(cx);
56+
nsCOMPtr<nsIXPConnectJSObjectHolder> sandbox;
57+
rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(sandbox));
58+
NS_ENSURE_SUCCESS(rv, rv);
13459

135-
nsCOMPtr<nsIPrincipal> principal;
136-
nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(principal));
137-
autoconfig_glob = JS_NewGlobalObject(autoconfig_cx, &global_class, nsJSPrincipals::get(principal));
138-
if (autoconfig_glob) {
139-
JSAutoCompartment ac(autoconfig_cx, autoconfig_glob);
140-
if (JS_InitStandardClasses(autoconfig_cx, autoconfig_glob)) {
141-
// XPCONNECT enable this JS context
142-
rv = xpc->InitClasses(autoconfig_cx, autoconfig_glob);
143-
if (NS_SUCCEEDED(rv))
144-
return NS_OK;
145-
}
146-
}
60+
// Unwrap, store and root the sandbox.
61+
rv = sandbox->GetJSObject(&autoconfigSb);
62+
NS_ENSURE_SUCCESS(rv, rv);
63+
autoconfigSb = js::UnwrapObject(autoconfigSb);
64+
JSAutoCompartment ac(cx, autoconfigSb);
65+
if (!JS_AddNamedObjectRoot(cx, &autoconfigSb, "AutoConfig Sandbox"))
66+
return NS_ERROR_FAILURE;
14767

148-
// failue exit... clean up the JS context
149-
JS_DestroyContext(autoconfig_cx);
150-
autoconfig_cx = nullptr;
151-
return NS_ERROR_FAILURE;
68+
return NS_OK;
15269
}
15370

15471
nsresult CentralizedAdminPrefManagerFinish()
15572
{
156-
if (autoconfig_cx)
157-
JS_DestroyContext(autoconfig_cx);
73+
if (autoconfigSb) {
74+
SafeAutoJSContext cx;
75+
JSAutoRequest ar(cx);
76+
JSAutoCompartment(cx, autoconfigSb);
77+
JS_RemoveObjectRoot(cx, &autoconfigSb);
78+
JS_MaybeGC(cx);
79+
}
15880
return NS_OK;
15981
}
16082

16183
nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
16284
const char *filename, bool bGlobalContext,
16385
bool bCallbacks, bool skipFirstLine)
16486
{
165-
JSBool ok;
87+
nsresult rv = NS_OK;
16688

16789
if (skipFirstLine) {
16890
/* In order to protect the privacy of the JavaScript preferences file
@@ -186,33 +108,22 @@ nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
186108
js_buffer += i;
187109
}
188110

189-
nsresult rv;
190-
nsCOMPtr<nsIJSContextStack> cxstack =
191-
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
192-
rv = cxstack->Push(autoconfig_cx);
111+
// Grab XPConnect.
112+
nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
193113
if (NS_FAILED(rv)) {
194-
NS_ERROR("coudn't push the context on the stack");
195114
return rv;
196115
}
197116

198-
JS_BeginRequest(autoconfig_cx);
199-
nsCOMPtr<nsIPrincipal> principal;
200-
nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(principal));
201-
JS::CompileOptions options(autoconfig_cx);
202-
options.setPrincipals(nsJSPrincipals::get(principal))
203-
.setFileAndLine(filename, 1);
204-
JS::RootedObject glob(autoconfig_cx, autoconfig_glob);
205-
ok = JS::Evaluate(autoconfig_cx, glob, options, js_buffer, length, nullptr);
206-
JS_EndRequest(autoconfig_cx);
207-
208-
JS_MaybeGC(autoconfig_cx);
117+
SafeAutoJSContext cx;
118+
JSAutoRequest ar(cx);
119+
JSAutoCompartment ac(cx, autoconfigSb);
209120

210-
JSContext *cx;
211-
cxstack->Pop(&cx);
212-
NS_ASSERTION(cx == autoconfig_cx, "AutoConfig JS contexts didn't match");
121+
nsAutoCString script(js_buffer, length);
122+
JS::RootedValue v(cx);
123+
rv = xpc->EvalInSandboxObject(NS_ConvertASCIItoUTF16(script), filename, cx, autoconfigSb,
124+
/* returnStringOnly = */ false, v.address());
125+
NS_ENSURE_SUCCESS(rv, rv);
213126

214-
if (ok)
215-
return NS_OK;
216-
return NS_ERROR_FAILURE;
127+
return NS_OK;
217128
}
218129

0 commit comments

Comments
 (0)