[vm] Prevent reinterpreting object null as a send port capability.

Also ensure that allocated port ids and well-formed object pointers are disjoint.

Bug: https://github.com/dart-lang/sdk/issues/37234
Change-Id: I15328c1ba34f2995089f084e8889b110507c4dbf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107223
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
This commit is contained in:
Ryan Macnak 2019-06-26 00:17:04 +00:00 committed by commit-bot@chromium.org
parent 4628f3e086
commit 523aa97ea1
2 changed files with 17 additions and 5 deletions

View file

@ -197,6 +197,10 @@ class _RawReceivePortImpl implements RawReceivePort {
@pragma("vm:entry-point")
class _SendPortImpl implements SendPort {
factory _SendPortImpl._uninstantiable() {
throw "Unreachable";
}
/*--- public interface ---*/
@pragma("vm:entry-point", "call")
void send(var message) {

View file

@ -4,6 +4,8 @@
#include "vm/port.h"
#include <utility>
#include "platform/utils.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
@ -82,14 +84,20 @@ const char* PortMap::PortStateString(PortState kind) {
}
Dart_Port PortMap::AllocatePort() {
const Dart_Port kMASK = 0x3fffffff;
Dart_Port result = prng_->NextUInt32() & kMASK;
Dart_Port result;
// Keep getting new values while we have an illegal port number or the port
// number is already in use.
while ((result == 0) || (FindPort(result) >= 0)) {
result = prng_->NextUInt32() & kMASK;
}
do {
// Ensure port ids are representable in JavaScript for the benefit of
// vm-service clients such as Observatory.
const Dart_Port kMask1 = 0xFFFFFFFFFFFFF;
// Ensure port ids are never valid object pointers so that reinterpreting
// an object pointer as a port id never produces a used port id.
const Dart_Port kMask2 = 0x3;
result = (prng_->NextUInt64() & kMask1) | kMask2;
ASSERT(!reinterpret_cast<RawObject*>(result)->IsWellFormed());
} while (FindPort(result) >= 0);
ASSERT(result != 0);
ASSERT(FindPort(result) < 0);