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; }