Bug 1065811 - Clean up ObjectId handling with static type checking. r=billm

While adding the CPOW flag for xray waivers, I discovered a bunch of
inconsistency and sloppiness with respect to our handling of object ids,
and a general lack of clarity about when the id included flags or not. Given
the fact that I'm removing static callability for CPOWs, we _could_ just get
rid of the flags, and store the xray waiver state on the answer-side only. But
I eventually decided that these kinds of flags (which are accessible to both
the Answer _and_ the Owner) had enough potential utility that they were worth
cleaning up.

It's worth noting that that utility comes with the large caveat that the flags
can't be trusted for security-sensitive decisions (at least in the parent->child
case), since they could be forged by a compromised child.
This commit is contained in:
Bobby Holley
2014-09-25 13:13:29 +02:00
parent c504a51772
commit 4088e55174
6 changed files with 140 additions and 105 deletions

View File

@@ -38,8 +38,8 @@ WrapperOwner::idOfUnchecked(JSObject *obj)
Value v = GetProxyExtra(obj, 1);
MOZ_ASSERT(v.isDouble());
ObjectId objId = BitwiseCast<uint64_t>(v.toDouble());
MOZ_ASSERT(objId);
ObjectId objId = ObjectId::deserialize(BitwiseCast<uint64_t>(v.toDouble()));
MOZ_ASSERT(!objId.isNull());
return objId;
}
@@ -872,13 +872,13 @@ WrapperOwner::toObjectVariant(JSContext *cx, JSObject *objArg, ObjectVariant *ob
// in findObjectById.
obj = js::UncheckedUnwrap(obj, false);
if (obj && IsCPOW(obj) && OwnerOf(obj) == this) {
*objVarp = LocalObject(idOf(obj));
*objVarp = LocalObject(idOf(obj).serialize());
return true;
}
ObjectId id = objectIds_.find(obj);
if (id) {
*objVarp = RemoteObject(id);
if (!id.isNull()) {
*objVarp = RemoteObject(id.serialize());
return true;
}
@@ -887,22 +887,13 @@ WrapperOwner::toObjectVariant(JSContext *cx, JSObject *objArg, ObjectVariant *ob
if (mozilla::dom::IsDOMObject(obj))
mozilla::dom::TryPreserveWrapper(obj);
id = ++lastId_;
if (id > MAX_CPOW_IDS) {
JS_ReportError(cx, "CPOW id limit reached");
return false;
}
id <<= OBJECT_EXTRA_BITS;
if (JS::IsCallable(obj))
id |= OBJECT_IS_CALLABLE;
id = ObjectId(nextSerialNumber_++, JS::IsCallable(obj));
if (!objects_.add(id, obj))
return false;
if (!objectIds_.add(cx, obj, id))
return false;
*objVarp = RemoteObject(id);
*objVarp = RemoteObject(id.serialize());
return true;
}
@@ -919,14 +910,9 @@ WrapperOwner::fromObjectVariant(JSContext *cx, ObjectVariant objVar)
JSObject *
WrapperOwner::fromRemoteObjectVariant(JSContext *cx, RemoteObject objVar)
{
ObjectId objId = objVar.id();
ObjectId objId = ObjectId::deserialize(objVar.serializedId());
RootedObject obj(cx, findCPOWById(objId));
if (!obj) {
// If we didn't find an existing CPOW, we need to create one.
if (objId > MAX_CPOW_IDS) {
JS_ReportError(cx, "unusable CPOW id");
return nullptr;
}
// All CPOWs live in the privileged junk scope.
RootedObject junkScope(cx, xpc::PrivilegedJunkScope());
@@ -947,7 +933,7 @@ WrapperOwner::fromRemoteObjectVariant(JSContext *cx, RemoteObject objVar)
incref();
SetProxyExtra(obj, 0, PrivateValue(this));
SetProxyExtra(obj, 1, DoubleValue(BitwiseCast<double>(objId)));
SetProxyExtra(obj, 1, DoubleValue(BitwiseCast<double>(objId.serialize())));
}
if (!JS_WrapObject(cx, &obj))
@@ -958,7 +944,7 @@ WrapperOwner::fromRemoteObjectVariant(JSContext *cx, RemoteObject objVar)
JSObject *
WrapperOwner::fromLocalObjectVariant(JSContext *cx, LocalObject objVar)
{
ObjectId id = objVar.id();
ObjectId id = ObjectId::deserialize(objVar.serializedId());
Rooted<JSObject*> obj(cx, findObjectById(cx, id));
if (!obj)
return nullptr;