Add rights for mapping buffer. Update (shared) buffer APIs.

R=azani@chromium.org

Review URL: https://codereview.chromium.org/1964953002 .
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
index a8c2007..65eb073 100644
--- a/mojo/edk/system/core.cc
+++ b/mojo/edk/system/core.cc
@@ -638,7 +638,7 @@
                                       uint32_t info_num_bytes) {
   RefPtr<Dispatcher> dispatcher;
   MojoResult result =
-      GetDispatcherAndCheckRights(buffer_handle, MOJO_HANDLE_RIGHT_READ,
+      GetDispatcherAndCheckRights(buffer_handle, MOJO_HANDLE_RIGHT_GET_OPTIONS,
                                   EntrypointClass::BUFFER, &dispatcher);
   if (result != MOJO_RESULT_OK)
     return result;
@@ -652,11 +652,13 @@
                            UserPointer<void*> buffer,
                            MojoMapBufferFlags flags) {
   RefPtr<Dispatcher> dispatcher;
-  // TODO(vtl): Is this right? Or should there be a "map" right? Probably I need
-  // to rethink rights for buffers.
-  MojoResult result =
-      GetDispatcherAndCheckRights(buffer_handle, MOJO_HANDLE_RIGHT_WRITE,
-                                  EntrypointClass::BUFFER, &dispatcher);
+  // TODO(vtl): Currently we can only map read/write. So both
+  // |MOJO_HANDLE_RIGHT_MAP_READABLE| and |MOJO_HANDLE_RIGHT_MAP_WRITABLE| are
+  // required.
+  MojoResult result = GetDispatcherAndCheckRights(
+      buffer_handle,
+      MOJO_HANDLE_RIGHT_MAP_READABLE | MOJO_HANDLE_RIGHT_MAP_WRITABLE,
+      EntrypointClass::BUFFER, &dispatcher);
   if (result != MOJO_RESULT_OK)
     return result;
 
diff --git a/mojo/edk/system/core_test_base.cc b/mojo/edk/system/core_test_base.cc
index ed98702..1f982ec 100644
--- a/mojo/edk/system/core_test_base.cc
+++ b/mojo/edk/system/core_test_base.cc
@@ -230,7 +230,9 @@
       std::move(dispatcher),
       MOJO_HANDLE_RIGHT_DUPLICATE | MOJO_HANDLE_RIGHT_TRANSFER |
           MOJO_HANDLE_RIGHT_READ | MOJO_HANDLE_RIGHT_WRITE |
-          MOJO_HANDLE_RIGHT_GET_OPTIONS | MOJO_HANDLE_RIGHT_SET_OPTIONS));
+          MOJO_HANDLE_RIGHT_GET_OPTIONS | MOJO_HANDLE_RIGHT_SET_OPTIONS |
+          MOJO_HANDLE_RIGHT_MAP_READABLE | MOJO_HANDLE_RIGHT_MAP_WRITABLE |
+          MOJO_HANDLE_RIGHT_MAP_EXECUTABLE));
   CHECK_NE(rv, MOJO_HANDLE_INVALID);
   return rv;
 }
diff --git a/mojo/edk/system/handle_unittest.cc b/mojo/edk/system/handle_unittest.cc
index 8c630ed..5dc27cd 100644
--- a/mojo/edk/system/handle_unittest.cc
+++ b/mojo/edk/system/handle_unittest.cc
@@ -125,6 +125,9 @@
     EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_WRITE));
     EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_GET_OPTIONS));
     EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_SET_OPTIONS));
+    EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_MAP_READABLE));
+    EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_MAP_WRITABLE));
+    EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_MAP_EXECUTABLE));
   }
 
   {
@@ -138,6 +141,9 @@
     EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_WRITE));
     EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_GET_OPTIONS));
     EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_SET_OPTIONS));
+    EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_MAP_READABLE));
+    EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_MAP_WRITABLE));
+    EXPECT_FALSE(h.has_all_rights(MOJO_HANDLE_RIGHT_MAP_EXECUTABLE));
 
     EXPECT_TRUE(
         h.has_all_rights(MOJO_HANDLE_RIGHT_DUPLICATE | MOJO_HANDLE_RIGHT_READ));
diff --git a/mojo/edk/system/shared_buffer_dispatcher.h b/mojo/edk/system/shared_buffer_dispatcher.h
index 70e2158..68c3209 100644
--- a/mojo/edk/system/shared_buffer_dispatcher.h
+++ b/mojo/edk/system/shared_buffer_dispatcher.h
@@ -36,7 +36,9 @@
   // duplicable by default.
   static constexpr MojoHandleRights kDefaultHandleRights =
       MOJO_HANDLE_RIGHT_DUPLICATE | MOJO_HANDLE_RIGHT_TRANSFER |
-      MOJO_HANDLE_RIGHT_READ | MOJO_HANDLE_RIGHT_WRITE;
+      MOJO_HANDLE_RIGHT_GET_OPTIONS | MOJO_HANDLE_RIGHT_SET_OPTIONS |
+      MOJO_HANDLE_RIGHT_MAP_READABLE | MOJO_HANDLE_RIGHT_MAP_WRITABLE |
+      MOJO_HANDLE_RIGHT_MAP_EXECUTABLE;
 
   // The default options to use for |MojoCreateSharedBuffer()|. (Real uses
   // should obtain this via |ValidateCreateOptions()| with a null |in_options|;
diff --git a/mojo/public/c/system/buffer.h b/mojo/public/c/system/buffer.h
index 0c253c0..2dd7477 100644
--- a/mojo/public/c/system/buffer.h
+++ b/mojo/public/c/system/buffer.h
@@ -102,7 +102,11 @@
 // |options| may be set to null for a shared buffer with the default options.
 //
 // On success, |*shared_buffer_handle| will be set to the handle for the shared
-// buffer. (On failure, it is not modified.)
+// buffer. (On failure, it is not modified.) The handle has (at least) the
+// following rights: |MOJO_HANDLE_RIGHT_DUPLICATE|,
+// |MOJO_HANDLE_RIGHT_TRANSFER|, |MOJO_HANDLE_RIGHT_GET_OPTIONS|,
+// |MOJO_HANDLE_RIGHT_SET_OPTIONS|, |MOJO_HANDLE_RIGHT_MAP_READABLE|,
+// |MOJO_HANDLE_RIGHT_MAP_WRITABLE|, and |MOJO_HANDLE_RIGHT_MAP_EXECUTABLE|.
 //
 // Note: While more than |num_bytes| bytes may apparently be
 // available/visible/readable/writable, trying to use those extra bytes is
@@ -122,11 +126,11 @@
     uint64_t num_bytes,                               // In.
     MojoHandle* MOJO_RESTRICT shared_buffer_handle);  // Out.
 
-// |MojoDuplicateBufferHandle()|: Duplicates the handle |buffer_handle| to a
-// buffer. This creates another handle (returned in |*new_buffer_handle| on
-// success), which can then be sent to another application over a message pipe,
-// while retaining access to the |buffer_handle| (and any mappings that it may
-// have).
+// |MojoDuplicateBufferHandle()|: Duplicates the handle |buffer_handle| (which
+// must have the |MOJO_HANDLE_RIGHT_DUPLICATE| right) to a buffer. This creates
+// another handle (returned in |*new_buffer_handle| on success), which can then
+// be sent to another application over a message pipe, while retaining access to
+// the |buffer_handle| (and any mappings that it may have).
 //
 // |options| may be set to null to duplicate the buffer handle with the default
 // options.
@@ -138,6 +142,8 @@
 //   |MOJO_RESULT_OK| on success.
 //   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid (e.g.,
 //       |buffer_handle| is not a valid buffer handle or |*options| is invalid).
+//   |MOJO_RESULT_PERMISSION_DENIED| if |buffer_handle| does not have the
+//       |MOJO_HANDLE_RIGHT_DUPLICATE| right.
 //   |MOJO_RESULT_UNIMPLEMENTED| if an unsupported flag was set in |*options|.
 //   |MOJO_RESULT_BUSY| if |buffer_handle| is currently in use in some
 //       transaction (that, e.g., may result in it being invalidated, such as
@@ -149,9 +155,10 @@
     MojoHandle* MOJO_RESTRICT new_buffer_handle);  // Out.
 
 // |MojoGetBufferInformation()|: Gets information about the buffer with handle
-// |buffer_handle|. |info| should be non-null and point to a buffer of size
-// |info_num_bytes|; |info_num_bytes| should be at least 16 (the size of the
-// first, and currently only, version of |struct MojoBufferInformation|).
+// |buffer_handle| (which must have the |MOJO_HANDLE_RIGHT_GET_OPTIONS| right).
+// |info| should be non-null and point to a buffer of size |info_num_bytes|;
+// |info_num_bytes| should be at least 16 (the size of the first, and currently
+// only, version of |struct MojoBufferInformation|).
 //
 // On success, |*info| will be filled with information about the given buffer.
 // Note that if additional (larger) versions of |struct MojoBufferInformation|
@@ -164,6 +171,8 @@
 //   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid (e.g.,
 //       |buffer_handle| is not a valid buffer handle, |*info| is null, or
 //       |info_num_bytes| is too small).
+//   |MOJO_RESULT_PERMISSION_DENIED| if |buffer_handle| does not have the
+//       |MOJO_HANDLE_RIGHT_GET_OPTIONS| right.
 //   |MOJO_RESULT_BUSY| if |buffer_handle| is currently in use in some
 //       transaction (that, e.g., may result in it being invalidated, such as
 //       being sent in a message).
@@ -172,10 +181,12 @@
                                     uint32_t info_num_bytes);            // In.
 
 // |MojoMapBuffer()|: Maps the part (at offset |offset| of length |num_bytes|)
-// of the buffer given by |buffer_handle| into memory, with options specified by
-// |flags|. |offset + num_bytes| must be less than or equal to the size of the
-// buffer. On success, |*buffer| points to memory with the requested part of the
-// buffer. (On failure, it is not modified.)
+// of the buffer given by |buffer_handle| (which must have both the
+// |MOJO_HANDLE_RIGHT_MAP_READABLE| and |MOJO_HANDLE_RIGHT_MAP_WRITABLE| rights)
+// into memory, with options specified by |flags|. |offset + num_bytes| must be
+// less than or equal to the size of the buffer. On success, |*buffer| points to
+// memory with the requested part of the buffer. (On failure, it is not
+// modified.)
 //
 // A single buffer handle may have multiple active mappings (possibly depending
 // on the buffer type). The permissions (e.g., writable or executable) of the
@@ -191,6 +202,9 @@
 //   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid (e.g.,
 //       |buffer_handle| is not a valid buffer handle or the range specified by
 //       |offset| and |num_bytes| is not valid).
+//   |MOJO_RESULT_PERMISSION_DENIED| if |buffer_handle| does not have both the
+//       |MOJO_HANDLE_RIGHT_MAP_READABLE| and |MOJO_HANDLE_RIGHT_MAP_WRITABLE|
+//       rights.
 //   |MOJO_RESULT_RESOURCE_EXHAUSTED| if the mapping operation itself failed
 //       (e.g., due to not having appropriate address space available).
 //   |MOJO_RESULT_BUSY| if |buffer_handle| is currently in use in some
diff --git a/mojo/public/c/system/handle.h b/mojo/public/c/system/handle.h
index 096a248..445558c 100644
--- a/mojo/public/c/system/handle.h
+++ b/mojo/public/c/system/handle.h
@@ -35,6 +35,12 @@
 //       message).
 //   |MOJO_HANDLE_RIGHT_GET_OPTIONS| - Right to get a handle's options.
 //   |MOJO_HANDLE_RIGHT_SET_OPTIONS| - Right to set a handle's options.
+//   |MOJO_HANDLE_RIGHT_MAP_READABLE| - Right to "map" a (e.g., buffer) handle
+//       as readable memory.
+//   |MOJO_HANDLE_RIGHT_MAP_WRITABLE| - Right to "map" a (e.g., buffer) handle
+//       as writable memory.
+//   |MOJO_HANDLE_RIGHT_MAP_EXECUTABLE| - Right to "map" a (e.g., buffer) handle
+//       as executable memory.
 //
 // TODO(vtl): Add rights support/checking to existing handle types.
 
@@ -47,6 +53,9 @@
 #define MOJO_HANDLE_RIGHT_WRITE ((MojoHandleRights)1 << 3)
 #define MOJO_HANDLE_RIGHT_GET_OPTIONS ((MojoHandleRights)1 << 4)
 #define MOJO_HANDLE_RIGHT_SET_OPTIONS ((MojoHandleRights)1 << 5)
+#define MOJO_HANDLE_RIGHT_MAP_READABLE ((MojoHandleRights)1 << 6)
+#define MOJO_HANDLE_RIGHT_MAP_WRITABLE ((MojoHandleRights)1 << 7)
+#define MOJO_HANDLE_RIGHT_MAP_EXECUTABLE ((MojoHandleRights)1 << 8)
 
 // |MojoHandleSignals|: Used to specify signals that can be waited on for a
 // handle (and which can be triggered), e.g., the ability to read or write to
@@ -79,6 +88,7 @@
 //         determine which, if any, of the signals can still be satisfied.
 // Note: This struct is not extensible (and only has 32-bit quantities), so it's
 // 32-bit-aligned.
+
 MOJO_STATIC_ASSERT(MOJO_ALIGNOF(uint32_t) == 4, "uint32_t has weird alignment");
 struct MOJO_ALIGNAS(4) MojoHandleSignalsState {
   MojoHandleSignals satisfied_signals;