Add thunks for MojoDuplicateHandle[WithReducedRights]().
R=azani@chromium.org
Review URL: https://codereview.chromium.org/2000253002 .
diff --git a/mojo/edk/embedder/entrypoints.cc b/mojo/edk/embedder/entrypoints.cc
index b500f6b..260eae0 100644
--- a/mojo/edk/embedder/entrypoints.cc
+++ b/mojo/edk/embedder/entrypoints.cc
@@ -31,6 +31,19 @@
return g_core->GetRights(handle, MakeUserPointer(rights));
}
+MojoResult MojoDuplicateHandleWithReducedRights(
+ MojoHandle handle,
+ MojoHandleRights rights_to_remove,
+ MojoHandle* new_handle) {
+ return g_core->DuplicateHandleWithReducedRights(handle, rights_to_remove,
+ MakeUserPointer(new_handle));
+}
+
+MojoResult MojoDuplicateHandle(MojoHandle handle, MojoHandle* new_handle) {
+ return g_core->DuplicateHandleWithReducedRights(
+ handle, MOJO_HANDLE_RIGHT_NONE, MakeUserPointer(new_handle));
+}
+
MojoResult MojoWait(MojoHandle handle,
MojoHandleSignals signals,
MojoDeadline deadline,
diff --git a/mojo/edk/embedder/system_impl_private_entrypoints.cc b/mojo/edk/embedder/system_impl_private_entrypoints.cc
index 0f1b18d..fb705c4 100644
--- a/mojo/edk/embedder/system_impl_private_entrypoints.cc
+++ b/mojo/edk/embedder/system_impl_private_entrypoints.cc
@@ -100,6 +100,26 @@
return core->GetRights(handle, MakeUserPointer(rights));
}
+MojoResult MojoSystemImplDuplicateHandleWithReducedRights(
+ MojoSystemImpl system,
+ MojoHandle handle,
+ MojoHandleRights rights_to_remove,
+ MojoHandle* new_handle) {
+ mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
+ DCHECK(core);
+ return core->DuplicateHandleWithReducedRights(handle, rights_to_remove,
+ MakeUserPointer(new_handle));
+}
+
+MojoResult MojoSystemImplDuplicateHandle(MojoSystemImpl system,
+ MojoHandle handle,
+ MojoHandle* new_handle) {
+ mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
+ DCHECK(core);
+ return core->DuplicateHandleWithReducedRights(handle, MOJO_HANDLE_RIGHT_NONE,
+ MakeUserPointer(new_handle));
+}
+
MojoResult MojoSystemImplWait(MojoSystemImpl system,
MojoHandle handle,
MojoHandleSignals signals,
diff --git a/mojo/nacl/nonsfi/irt_mojo_nonsfi.cc b/mojo/nacl/nonsfi/irt_mojo_nonsfi.cc
index 7ccdc84..9d9668b 100644
--- a/mojo/nacl/nonsfi/irt_mojo_nonsfi.cc
+++ b/mojo/nacl/nonsfi/irt_mojo_nonsfi.cc
@@ -25,6 +25,8 @@
MojoGetTimeTicksNow,
MojoClose,
MojoGetRights,
+ MojoDuplicateHandleWithReducedRights,
+ MojoDuplicateHandle,
MojoWait,
MojoWaitMany,
MojoCreateMessagePipe,
diff --git a/mojo/nacl/sfi/nacl_bindings/mojo_irt.c b/mojo/nacl/sfi/nacl_bindings/mojo_irt.c
index 41c8c49..9e653ce 100644
--- a/mojo/nacl/sfi/nacl_bindings/mojo_irt.c
+++ b/mojo/nacl/sfi/nacl_bindings/mojo_irt.c
@@ -70,6 +70,34 @@
return result;
};
+static MojoResult irt_MojoDuplicateHandleWithReducedRights(
+ MojoHandle handle,
+ MojoHandleRights rights_to_remove,
+ MojoHandle* new_handle) {
+ uint32_t params[5];
+ MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+ params[0] = 4;
+ params[1] = (uint32_t)(&handle);
+ params[2] = (uint32_t)(&rights_to_remove);
+ params[3] = (uint32_t)(new_handle);
+ params[4] = (uint32_t)(&result);
+ DoMojoCall(params, sizeof(params));
+ return result;
+};
+
+static MojoResult irt_MojoDuplicateHandle(
+ MojoHandle handle,
+ MojoHandle* new_handle) {
+ uint32_t params[4];
+ MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
+ params[0] = 5;
+ params[1] = (uint32_t)(&handle);
+ params[2] = (uint32_t)(new_handle);
+ params[3] = (uint32_t)(&result);
+ DoMojoCall(params, sizeof(params));
+ return result;
+};
+
static MojoResult irt_MojoWait(
MojoHandle handle,
MojoHandleSignals signals,
@@ -77,7 +105,7 @@
struct MojoHandleSignalsState* signals_state) {
uint32_t params[6];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 4;
+ params[0] = 6;
params[1] = (uint32_t)(&handle);
params[2] = (uint32_t)(&signals);
params[3] = (uint32_t)(&deadline);
@@ -96,7 +124,7 @@
struct MojoHandleSignalsState* signals_states) {
uint32_t params[8];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 5;
+ params[0] = 7;
params[1] = (uint32_t)(handles);
params[2] = (uint32_t)(signals);
params[3] = (uint32_t)(&num_handles);
@@ -114,7 +142,7 @@
MojoHandle* message_pipe_handle1) {
uint32_t params[5];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 6;
+ params[0] = 8;
params[1] = (uint32_t)(options);
params[2] = (uint32_t)(message_pipe_handle0);
params[3] = (uint32_t)(message_pipe_handle1);
@@ -132,7 +160,7 @@
MojoWriteMessageFlags flags) {
uint32_t params[8];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 7;
+ params[0] = 9;
params[1] = (uint32_t)(&message_pipe_handle);
params[2] = (uint32_t)(bytes);
params[3] = (uint32_t)(&num_bytes);
@@ -153,7 +181,7 @@
MojoReadMessageFlags flags) {
uint32_t params[8];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 8;
+ params[0] = 10;
params[1] = (uint32_t)(&message_pipe_handle);
params[2] = (uint32_t)(bytes);
params[3] = (uint32_t)(num_bytes);
@@ -171,7 +199,7 @@
MojoHandle* data_pipe_consumer_handle) {
uint32_t params[5];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 9;
+ params[0] = 11;
params[1] = (uint32_t)(options);
params[2] = (uint32_t)(data_pipe_producer_handle);
params[3] = (uint32_t)(data_pipe_consumer_handle);
@@ -185,7 +213,7 @@
const struct MojoDataPipeProducerOptions* options) {
uint32_t params[4];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 10;
+ params[0] = 12;
params[1] = (uint32_t)(&data_pipe_producer_handle);
params[2] = (uint32_t)(options);
params[3] = (uint32_t)(&result);
@@ -199,7 +227,7 @@
uint32_t options_num_bytes) {
uint32_t params[5];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 11;
+ params[0] = 13;
params[1] = (uint32_t)(&data_pipe_producer_handle);
params[2] = (uint32_t)(options);
params[3] = (uint32_t)(&options_num_bytes);
@@ -215,7 +243,7 @@
MojoWriteDataFlags flags) {
uint32_t params[6];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 12;
+ params[0] = 14;
params[1] = (uint32_t)(&data_pipe_producer_handle);
params[2] = (uint32_t)(elements);
params[3] = (uint32_t)(num_bytes);
@@ -232,7 +260,7 @@
MojoWriteDataFlags flags) {
uint32_t params[6];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 13;
+ params[0] = 15;
params[1] = (uint32_t)(&data_pipe_producer_handle);
params[2] = (uint32_t)(buffer);
params[3] = (uint32_t)(buffer_num_bytes);
@@ -247,7 +275,7 @@
uint32_t num_bytes_written) {
uint32_t params[4];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 14;
+ params[0] = 16;
params[1] = (uint32_t)(&data_pipe_producer_handle);
params[2] = (uint32_t)(&num_bytes_written);
params[3] = (uint32_t)(&result);
@@ -260,7 +288,7 @@
const struct MojoDataPipeConsumerOptions* options) {
uint32_t params[4];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 15;
+ params[0] = 17;
params[1] = (uint32_t)(&data_pipe_consumer_handle);
params[2] = (uint32_t)(options);
params[3] = (uint32_t)(&result);
@@ -274,7 +302,7 @@
uint32_t options_num_bytes) {
uint32_t params[5];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 16;
+ params[0] = 18;
params[1] = (uint32_t)(&data_pipe_consumer_handle);
params[2] = (uint32_t)(options);
params[3] = (uint32_t)(&options_num_bytes);
@@ -290,7 +318,7 @@
MojoReadDataFlags flags) {
uint32_t params[6];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 17;
+ params[0] = 19;
params[1] = (uint32_t)(&data_pipe_consumer_handle);
params[2] = (uint32_t)(elements);
params[3] = (uint32_t)(num_bytes);
@@ -307,7 +335,7 @@
MojoReadDataFlags flags) {
uint32_t params[6];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 18;
+ params[0] = 20;
params[1] = (uint32_t)(&data_pipe_consumer_handle);
params[2] = (uint32_t)(buffer);
params[3] = (uint32_t)(buffer_num_bytes);
@@ -322,7 +350,7 @@
uint32_t num_bytes_read) {
uint32_t params[4];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 19;
+ params[0] = 21;
params[1] = (uint32_t)(&data_pipe_consumer_handle);
params[2] = (uint32_t)(&num_bytes_read);
params[3] = (uint32_t)(&result);
@@ -336,7 +364,7 @@
MojoHandle* shared_buffer_handle) {
uint32_t params[5];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 20;
+ params[0] = 22;
params[1] = (uint32_t)(options);
params[2] = (uint32_t)(&num_bytes);
params[3] = (uint32_t)(shared_buffer_handle);
@@ -351,7 +379,7 @@
MojoHandle* new_buffer_handle) {
uint32_t params[5];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 21;
+ params[0] = 23;
params[1] = (uint32_t)(&buffer_handle);
params[2] = (uint32_t)(options);
params[3] = (uint32_t)(new_buffer_handle);
@@ -366,7 +394,7 @@
uint32_t info_num_bytes) {
uint32_t params[5];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 22;
+ params[0] = 24;
params[1] = (uint32_t)(&buffer_handle);
params[2] = (uint32_t)(info);
params[3] = (uint32_t)(&info_num_bytes);
@@ -383,7 +411,7 @@
MojoMapBufferFlags flags) {
uint32_t params[7];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 23;
+ params[0] = 25;
params[1] = (uint32_t)(&buffer_handle);
params[2] = (uint32_t)(&offset);
params[3] = (uint32_t)(&num_bytes);
@@ -397,7 +425,7 @@
static MojoResult irt_MojoUnmapBuffer(void* buffer) {
uint32_t params[3];
MojoResult result = MOJO_RESULT_INVALID_ARGUMENT;
- params[0] = 24;
+ params[0] = 26;
params[1] = (uint32_t)(&buffer);
params[2] = (uint32_t)(&result);
DoMojoCall(params, sizeof(params));
@@ -409,6 +437,8 @@
&irt_MojoGetTimeTicksNow,
&irt_MojoClose,
&irt_MojoGetRights,
+ &irt_MojoDuplicateHandleWithReducedRights,
+ &irt_MojoDuplicateHandle,
&irt_MojoWait,
&irt_MojoWaitMany,
&irt_MojoCreateMessagePipe,
diff --git a/mojo/nacl/sfi/nacl_bindings/mojo_syscall.cc b/mojo/nacl/sfi/nacl_bindings/mojo_syscall.cc
index cbc89d8..acbd8ea 100644
--- a/mojo/nacl/sfi/nacl_bindings/mojo_syscall.cc
+++ b/mojo/nacl/sfi/nacl_bindings/mojo_syscall.cc
@@ -164,6 +164,79 @@
return 0;
}
case 4: {
+ if (num_params != 5) {
+ return -1;
+ }
+ MojoHandle handle_value;
+ MojoHandleRights rights_to_remove_value;
+ MojoHandle volatile* new_handle_ptr;
+ MojoHandle new_handle_value;
+ MojoResult volatile* result_ptr;
+ MojoResult result_value;
+ {
+ ScopedCopyLock copy_lock(nap);
+ if (!ConvertScalarInput(nap, params[1], &handle_value)) {
+ return -1;
+ }
+ if (!ConvertScalarInput(nap, params[2], &rights_to_remove_value)) {
+ return -1;
+ }
+ if (!ConvertScalarInOut(nap, params[3], false, &new_handle_value,
+ &new_handle_ptr)) {
+ return -1;
+ }
+ if (!ConvertScalarOutput(nap, params[4], false, &result_ptr)) {
+ return -1;
+ }
+ }
+
+ result_value = MojoSystemImplDuplicateHandleWithReducedRights(
+ g_mojo_system, handle_value, rights_to_remove_value,
+ &new_handle_value);
+
+ {
+ ScopedCopyLock copy_lock(nap);
+ *new_handle_ptr = new_handle_value;
+ *result_ptr = result_value;
+ }
+
+ return 0;
+ }
+ case 5: {
+ if (num_params != 4) {
+ return -1;
+ }
+ MojoHandle handle_value;
+ MojoHandle volatile* new_handle_ptr;
+ MojoHandle new_handle_value;
+ MojoResult volatile* result_ptr;
+ MojoResult result_value;
+ {
+ ScopedCopyLock copy_lock(nap);
+ if (!ConvertScalarInput(nap, params[1], &handle_value)) {
+ return -1;
+ }
+ if (!ConvertScalarInOut(nap, params[2], false, &new_handle_value,
+ &new_handle_ptr)) {
+ return -1;
+ }
+ if (!ConvertScalarOutput(nap, params[3], false, &result_ptr)) {
+ return -1;
+ }
+ }
+
+ result_value = MojoSystemImplDuplicateHandle(g_mojo_system, handle_value,
+ &new_handle_value);
+
+ {
+ ScopedCopyLock copy_lock(nap);
+ *new_handle_ptr = new_handle_value;
+ *result_ptr = result_value;
+ }
+
+ return 0;
+ }
+ case 6: {
if (num_params != 6) {
return -1;
}
@@ -208,7 +281,7 @@
return 0;
}
- case 5: {
+ case 7: {
if (num_params != 8) {
return -1;
}
@@ -264,7 +337,7 @@
return 0;
}
- case 6: {
+ case 8: {
if (num_params != 5) {
return -1;
}
@@ -308,7 +381,7 @@
return 0;
}
- case 7: {
+ case 9: {
if (num_params != 8) {
return -1;
}
@@ -357,7 +430,7 @@
return 0;
}
- case 8: {
+ case 10: {
if (num_params != 8) {
return -1;
}
@@ -417,7 +490,7 @@
return 0;
}
- case 9: {
+ case 11: {
if (num_params != 5) {
return -1;
}
@@ -461,7 +534,7 @@
return 0;
}
- case 10: {
+ case 12: {
if (num_params != 4) {
return -1;
}
@@ -493,7 +566,7 @@
return 0;
}
- case 11: {
+ case 13: {
if (num_params != 5) {
return -1;
}
@@ -531,7 +604,7 @@
return 0;
}
- case 12: {
+ case 14: {
if (num_params != 6) {
return -1;
}
@@ -576,10 +649,10 @@
return 0;
}
- case 13:
+ case 15:
fprintf(stderr, "MojoBeginWriteData not implemented\n");
return -1;
- case 14: {
+ case 16: {
if (num_params != 4) {
return -1;
}
@@ -612,7 +685,7 @@
return 0;
}
- case 15: {
+ case 17: {
if (num_params != 4) {
return -1;
}
@@ -644,7 +717,7 @@
return 0;
}
- case 16: {
+ case 18: {
if (num_params != 5) {
return -1;
}
@@ -682,7 +755,7 @@
return 0;
}
- case 17: {
+ case 19: {
if (num_params != 6) {
return -1;
}
@@ -727,10 +800,10 @@
return 0;
}
- case 18:
+ case 20:
fprintf(stderr, "MojoBeginReadData not implemented\n");
return -1;
- case 19: {
+ case 21: {
if (num_params != 4) {
return -1;
}
@@ -762,7 +835,7 @@
return 0;
}
- case 20: {
+ case 22: {
if (num_params != 5) {
return -1;
}
@@ -801,7 +874,7 @@
return 0;
}
- case 21: {
+ case 23: {
if (num_params != 5) {
return -1;
}
@@ -840,7 +913,7 @@
return 0;
}
- case 22: {
+ case 24: {
if (num_params != 5) {
return -1;
}
@@ -876,10 +949,10 @@
return 0;
}
- case 23:
+ case 25:
fprintf(stderr, "MojoMapBuffer not implemented\n");
return -1;
- case 24:
+ case 26:
fprintf(stderr, "MojoUnmapBuffer not implemented\n");
return -1;
}
diff --git a/mojo/nacl/sfi/nacl_bindings_generator/interface.py b/mojo/nacl/sfi/nacl_bindings_generator/interface.py
index 725f118..84ad256 100644
--- a/mojo/nacl/sfi/nacl_bindings_generator/interface.py
+++ b/mojo/nacl/sfi/nacl_bindings_generator/interface.py
@@ -24,6 +24,15 @@
f.Param('handle').In('MojoHandle')
f.Param('rights').Out('MojoHandleRights')
+ f = mojo.Func('MojoDuplicateHandleWithReducedRights', 'MojoResult')
+ f.Param('handle').In('MojoHandle')
+ f.Param('rights_to_remove').In('MojoHandleRights')
+ f.Param('new_handle').Out('MojoHandle')
+
+ f = mojo.Func('MojoDuplicateHandle', 'MojoResult')
+ f.Param('handle').In('MojoHandle')
+ f.Param('new_handle').Out('MojoHandle')
+
f = mojo.Func('MojoWait', 'MojoResult')
f.Param('handle').In('MojoHandle')
f.Param('signals').In('MojoHandleSignals')
diff --git a/mojo/public/c/system/tests/core_unittest.cc b/mojo/public/c/system/tests/core_unittest.cc
index 4e36860..aeba1ee 100644
--- a/mojo/public/c/system/tests/core_unittest.cc
+++ b/mojo/public/c/system/tests/core_unittest.cc
@@ -63,6 +63,19 @@
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
MojoGetRights(MOJO_HANDLE_INVALID, &rights));
+ // DuplicateHandleWithReducedRights:
+ MojoHandle new_handle = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+ MojoDuplicateHandleWithReducedRights(
+ MOJO_HANDLE_INVALID, MOJO_HANDLE_RIGHT_DUPLICATE, &new_handle));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, new_handle);
+
+ // DuplicateHandle:
+ new_handle = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+ MojoDuplicateHandle(MOJO_HANDLE_INVALID, &new_handle));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, new_handle);
+
// Wait:
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
MojoWait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE, 1000000u,
@@ -160,6 +173,18 @@
EXPECT_EQ(MOJO_RESULT_OK, MojoGetRights(h1, &rights));
EXPECT_EQ(kDefaultMessagePipeHandleRights, rights);
+ // Shouldn't be able to duplicate either handle (just test "with reduced
+ // rights" on one, and without on the other).
+ MojoHandle handle_denied = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ MojoDuplicateHandleWithReducedRights(
+ h0, MOJO_HANDLE_RIGHT_DUPLICATE, &handle_denied));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, handle_denied);
+ handle_denied = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ MojoDuplicateHandle(h1, &handle_denied));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, handle_denied);
+
// Shouldn't be readable, we haven't written anything.
MojoHandleSignalsState state;
EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
@@ -265,6 +290,18 @@
EXPECT_EQ(MOJO_RESULT_OK, MojoGetRights(hc, &rights));
EXPECT_EQ(kDefaultDataPipeConsumerHandleRights, rights);
+ // Shouldn't be able to duplicate either handle (just test "with reduced
+ // rights" on one, and without on the other).
+ MojoHandle handle_denied = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ MojoDuplicateHandleWithReducedRights(
+ hp, MOJO_HANDLE_RIGHT_DUPLICATE, &handle_denied));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, handle_denied);
+ handle_denied = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ MojoDuplicateHandle(hc, &handle_denied));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, handle_denied);
+
// The consumer |hc| shouldn't be readable.
MojoHandleSignalsState state;
EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
@@ -614,11 +651,9 @@
#define MAYBE_BasicSharedBuffer BasicSharedBuffer
#endif
TEST(CoreTest, MAYBE_BasicSharedBuffer) {
- MojoHandle h0, h1;
- void* pointer;
// Create a shared buffer (|h0|).
- h0 = MOJO_HANDLE_INVALID;
+ MojoHandle h0 = MOJO_HANDLE_INVALID;
EXPECT_EQ(MOJO_RESULT_OK, MojoCreateSharedBuffer(nullptr, 100, &h0));
EXPECT_NE(h0, MOJO_HANDLE_INVALID);
@@ -636,16 +671,17 @@
EXPECT_EQ(100u, info.num_bytes);
// Map everything.
- pointer = nullptr;
+ void* pointer = nullptr;
EXPECT_EQ(MOJO_RESULT_OK,
MojoMapBuffer(h0, 0, 100, &pointer, MOJO_MAP_BUFFER_FLAG_NONE));
ASSERT_TRUE(pointer);
static_cast<char*>(pointer)[50] = 'x';
// Duplicate |h0| to |h1|.
- h1 = MOJO_HANDLE_INVALID;
- EXPECT_EQ(MOJO_RESULT_OK, MojoDuplicateBufferHandle(h0, nullptr, &h1));
+ MojoHandle h1 = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_OK, MojoDuplicateHandle(h0, &h1));
EXPECT_NE(h1, MOJO_HANDLE_INVALID);
+ EXPECT_NE(h1, h0);
// The new handle should have the correct rights.
rights = MOJO_HANDLE_RIGHT_NONE;
@@ -681,7 +717,24 @@
// Unmap it.
EXPECT_EQ(MOJO_RESULT_OK, MojoUnmapBuffer(pointer));
+ // Test duplication with reduced rights.
+ MojoHandle h2 = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_OK, MojoDuplicateHandleWithReducedRights(
+ h1, MOJO_HANDLE_RIGHT_DUPLICATE, &h2));
+ EXPECT_NE(h2, MOJO_HANDLE_INVALID);
+ EXPECT_NE(h2, h1);
+ // |h2| should have the correct rights.
+ rights = MOJO_HANDLE_RIGHT_NONE;
+ EXPECT_EQ(MOJO_RESULT_OK, MojoGetRights(h2, &rights));
+ EXPECT_EQ(kDefaultSharedBufferHandleRights & ~MOJO_HANDLE_RIGHT_DUPLICATE,
+ rights);
+ // Trying to duplicate |h2| should fail.
+ MojoHandle h3 = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED, MojoDuplicateHandle(h2, &h3));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, h3);
+
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1));
+ EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2));
}
// This checks that things actually work in C (not C++).
diff --git a/mojo/public/platform/nacl/libmojo.cc b/mojo/public/platform/nacl/libmojo.cc
index 716877c..c25aff2 100644
--- a/mojo/public/platform/nacl/libmojo.cc
+++ b/mojo/public/platform/nacl/libmojo.cc
@@ -60,6 +60,24 @@
return irt_mojo->MojoGetRights(handle, rights);
}
+MojoResult MojoDuplicateHandleWithReducedRights(
+ MojoHandle handle,
+ MojoHandleRights rights_to_remove,
+ MojoHandle* new_handle) {
+ struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+ if (!irt_mojo)
+ abort();
+ return irt_mojo->MojoDuplicateHandleWithReducedRights(
+ handle, rights_to_remove, new_handle);
+}
+
+MojoResult MojoDuplicateHandle(MojoHandle handle, MojoHandle* new_handle) {
+ struct nacl_irt_mojo* irt_mojo = get_irt_mojo();
+ if (!irt_mojo)
+ abort();
+ return irt_mojo->MojoDuplicateHandle(handle, new_handle);
+}
+
MojoResult MojoWait(MojoHandle handle,
MojoHandleSignals signals,
MojoDeadline deadline,
diff --git a/mojo/public/platform/nacl/mojo_irt.h b/mojo/public/platform/nacl/mojo_irt.h
index 4a7edc3..90c767b 100644
--- a/mojo/public/platform/nacl/mojo_irt.h
+++ b/mojo/public/platform/nacl/mojo_irt.h
@@ -22,6 +22,11 @@
MojoTimeTicks (*MojoGetTimeTicksNow)();
MojoResult (*MojoClose)(MojoHandle handle);
MojoResult (*MojoGetRights)(MojoHandle handle, MojoHandleRights* rights);
+ MojoResult (*MojoDuplicateHandleWithReducedRights)(
+ MojoHandle handle,
+ MojoHandleRights rights_to_remove,
+ MojoHandle* new_handle);
+ MojoResult (*MojoDuplicateHandle)(MojoHandle handle, MojoHandle* new_handle);
MojoResult (*MojoWait)(MojoHandle handle,
MojoHandleSignals signals,
MojoDeadline deadline,
diff --git a/mojo/public/platform/native/system_impl_private.h b/mojo/public/platform/native/system_impl_private.h
index 58b3560..3596172 100644
--- a/mojo/public/platform/native/system_impl_private.h
+++ b/mojo/public/platform/native/system_impl_private.h
@@ -54,6 +54,14 @@
MojoResult MojoSystemImplGetRights(MojoSystemImpl system,
MojoHandle handle,
MojoHandleRights* rights);
+MojoResult MojoSystemImplDuplicateHandleWithReducedRights(
+ MojoSystemImpl system,
+ MojoHandle handle,
+ MojoHandleRights rights_to_remove,
+ MojoHandle* new_handle);
+MojoResult MojoSystemImplDuplicateHandle(MojoSystemImpl system,
+ MojoHandle handle,
+ MojoHandle* new_handle);
MojoResult MojoSystemImplWait(MojoSystemImpl system,
MojoHandle handle,
MojoHandleSignals signals,
diff --git a/mojo/public/platform/native/system_impl_private_thunks.c b/mojo/public/platform/native/system_impl_private_thunks.c
index 82f2ac1..fb75504 100644
--- a/mojo/public/platform/native/system_impl_private_thunks.c
+++ b/mojo/public/platform/native/system_impl_private_thunks.c
@@ -48,6 +48,23 @@
return g_system_impl_thunks.GetRights(system, handle, rights);
}
+MojoResult MojoSystemImplDuplicateHandleWithReducedRights(
+ MojoSystemImpl system,
+ MojoHandle handle,
+ MojoHandleRights rights_to_remove,
+ MojoHandle* new_handle) {
+ assert(g_system_impl_thunks.DuplicateHandleWithReducedRights);
+ return g_system_impl_thunks.DuplicateHandleWithReducedRights(
+ system, handle, rights_to_remove, new_handle);
+}
+
+MojoResult MojoSystemImplDuplicateHandle(MojoSystemImpl system,
+ MojoHandle handle,
+ MojoHandle* new_handle) {
+ assert(g_system_impl_thunks.DuplicateHandle);
+ return g_system_impl_thunks.DuplicateHandle(system, handle, new_handle);
+}
+
MojoResult MojoSystemImplWait(MojoSystemImpl system,
MojoHandle handle,
MojoHandleSignals signals,
diff --git a/mojo/public/platform/native/system_impl_private_thunks.h b/mojo/public/platform/native/system_impl_private_thunks.h
index e29fc8e..296cb21 100644
--- a/mojo/public/platform/native/system_impl_private_thunks.h
+++ b/mojo/public/platform/native/system_impl_private_thunks.h
@@ -37,6 +37,14 @@
MojoResult (*GetRights)(MojoSystemImpl system,
MojoHandle handle,
MojoHandleRights* rights);
+ MojoResult (*DuplicateHandleWithReducedRights)(
+ MojoSystemImpl system,
+ MojoHandle handle,
+ MojoHandleRights rights_to_remove,
+ MojoHandle* new_handle);
+ MojoResult (*DuplicateHandle)(MojoSystemImpl system,
+ MojoHandle handle,
+ MojoHandle* new_handle);
MojoResult (*Wait)(MojoSystemImpl system,
MojoHandle handle,
MojoHandleSignals signals,
@@ -157,6 +165,8 @@
MojoSystemImplGetTimeTicksNow,
MojoSystemImplClose,
MojoSystemImplGetRights,
+ MojoSystemImplDuplicateHandleWithReducedRights,
+ MojoSystemImplDuplicateHandle,
MojoSystemImplWait,
MojoSystemImplWaitMany,
MojoSystemImplCreateMessagePipe,
diff --git a/mojo/public/platform/native/system_impl_private_unittest.cc b/mojo/public/platform/native/system_impl_private_unittest.cc
index 215ccd4..03fcafd 100644
--- a/mojo/public/platform/native/system_impl_private_unittest.cc
+++ b/mojo/public/platform/native/system_impl_private_unittest.cc
@@ -63,6 +63,18 @@
EXPECT_EQ(MOJO_RESULT_OK, MojoSystemImplGetRights(sys0, h1, &rights));
EXPECT_EQ(kDefaultMessagePipeHandleRights, rights);
+ // Shouldn't be able to duplicate either handle (just test "with reduced
+ // rights" on one, and without on the other).
+ MojoHandle handle_denied = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ MojoSystemImplDuplicateHandleWithReducedRights(
+ sys0, h0, MOJO_HANDLE_RIGHT_DUPLICATE, &handle_denied));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, handle_denied);
+ handle_denied = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ MojoSystemImplDuplicateHandle(sys0, h1, &handle_denied));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, handle_denied);
+
// Move the other end of the pipe to a different SystemImpl.
EXPECT_EQ(MOJO_RESULT_OK, MojoSystemImplTransferHandle(sys0, h1, sys1, &h1));
EXPECT_NE(h1, MOJO_HANDLE_INVALID);
@@ -182,6 +194,18 @@
EXPECT_EQ(MOJO_RESULT_OK, MojoSystemImplGetRights(sys0, hc, &rights));
EXPECT_EQ(kDefaultDataPipeConsumerHandleRights, rights);
+ // Shouldn't be able to duplicate either handle (just test "with reduced
+ // rights" on one, and without on the other).
+ MojoHandle handle_denied = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ MojoSystemImplDuplicateHandleWithReducedRights(
+ sys0, hp, MOJO_HANDLE_RIGHT_DUPLICATE, &handle_denied));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, handle_denied);
+ handle_denied = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ MojoSystemImplDuplicateHandle(sys0, hc, &handle_denied));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, handle_denied);
+
// Move the other end of the pipe to a different SystemImpl.
EXPECT_EQ(MOJO_RESULT_OK, MojoSystemImplTransferHandle(sys0, hc, sys1, &hc));
EXPECT_NE(hc, MOJO_HANDLE_INVALID);
@@ -599,11 +623,8 @@
MojoSystemImpl sys1 = MojoSystemImplCreateImpl();
EXPECT_NE(sys0, sys1);
- MojoHandle h0, h1;
- void* pointer;
-
// Create a shared buffer (|h0|).
- h0 = MOJO_HANDLE_INVALID;
+ MojoHandle h0 = MOJO_HANDLE_INVALID;
EXPECT_EQ(MOJO_RESULT_OK,
MojoSystemImplCreateSharedBuffer(sys0, nullptr, kSize, &h0));
EXPECT_NE(h0, MOJO_HANDLE_INVALID);
@@ -624,7 +645,7 @@
}
// Map everything.
- pointer = nullptr;
+ void* pointer = nullptr;
EXPECT_EQ(MOJO_RESULT_OK,
MojoSystemImplMapBuffer(sys0, h0, 0u, kSize, &pointer,
MOJO_MAP_BUFFER_FLAG_NONE));
@@ -632,10 +653,10 @@
static_cast<char*>(pointer)[kSize / 2] = 'x';
// Duplicate |h0| to |h1|.
- h1 = MOJO_HANDLE_INVALID;
- EXPECT_EQ(MOJO_RESULT_OK,
- MojoSystemImplDuplicateBufferHandle(sys0, h0, nullptr, &h1));
+ MojoHandle h1 = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_OK, MojoSystemImplDuplicateHandle(sys0, h0, &h1));
EXPECT_NE(h1, MOJO_HANDLE_INVALID);
+ EXPECT_NE(h1, h0);
// The new handle should have the correct rights.
rights = MOJO_HANDLE_RIGHT_NONE;
@@ -679,7 +700,25 @@
// Unmap it.
EXPECT_EQ(MOJO_RESULT_OK, MojoSystemImplUnmapBuffer(sys1, pointer));
+ // Test duplication with reduced rights.
+ MojoHandle h2 = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_OK, MojoSystemImplDuplicateHandleWithReducedRights(
+ sys1, h1, MOJO_HANDLE_RIGHT_DUPLICATE, &h2));
+ EXPECT_NE(h2, MOJO_HANDLE_INVALID);
+ EXPECT_NE(h2, h1);
+ // |h2| should have the correct rights.
+ rights = MOJO_HANDLE_RIGHT_NONE;
+ EXPECT_EQ(MOJO_RESULT_OK, MojoSystemImplGetRights(sys1, h2, &rights));
+ EXPECT_EQ(kDefaultSharedBufferHandleRights & ~MOJO_HANDLE_RIGHT_DUPLICATE,
+ rights);
+ // Trying to duplicate |h2| should fail.
+ MojoHandle h3 = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ MojoSystemImplDuplicateHandle(sys1, h2, &h3));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, h3);
+
EXPECT_EQ(MOJO_RESULT_OK, MojoSystemImplClose(sys1, h1));
+ EXPECT_EQ(MOJO_RESULT_OK, MojoSystemImplClose(sys1, h2));
// 2 SystemImpls are leaked...
}
diff --git a/mojo/public/platform/native/system_thunks.c b/mojo/public/platform/native/system_thunks.c
index 9ed890f..6cff1cb 100644
--- a/mojo/public/platform/native/system_thunks.c
+++ b/mojo/public/platform/native/system_thunks.c
@@ -25,6 +25,20 @@
return g_thunks.GetRights(handle, rights);
}
+MojoResult MojoDuplicateHandleWithReducedRights(
+ MojoHandle handle,
+ MojoHandleRights rights_to_remove,
+ MojoHandle* new_handle) {
+ assert(g_thunks.DuplicateHandleWithReducedRights);
+ return g_thunks.DuplicateHandleWithReducedRights(handle, rights_to_remove,
+ new_handle);
+}
+
+MojoResult MojoDuplicateHandle(MojoHandle handle, MojoHandle* new_handle) {
+ assert(g_thunks.DuplicateHandle);
+ return g_thunks.DuplicateHandle(handle, new_handle);
+}
+
MojoResult MojoWait(MojoHandle handle,
MojoHandleSignals signals,
MojoDeadline deadline,
diff --git a/mojo/public/platform/native/system_thunks.h b/mojo/public/platform/native/system_thunks.h
index 23f7d69..3650d1f 100644
--- a/mojo/public/platform/native/system_thunks.h
+++ b/mojo/public/platform/native/system_thunks.h
@@ -127,6 +127,11 @@
struct MojoDataPipeProducerOptions* options,
uint32_t options_num_bytes);
MojoResult (*GetRights)(MojoHandle handle, MojoHandleRights* rights);
+ MojoResult (*DuplicateHandleWithReducedRights)(
+ MojoHandle handle,
+ MojoHandleRights rights_to_remove,
+ MojoHandle* new_handle);
+ MojoResult (*DuplicateHandle)(MojoHandle handle, MojoHandle* new_handle);
};
#pragma pack(pop)
@@ -161,6 +166,8 @@
MojoSetDataPipeProducerOptions,
MojoGetDataPipeProducerOptions,
MojoGetRights,
+ MojoDuplicateHandleWithReducedRights,
+ MojoDuplicateHandle,
};
return system_thunks;
}