Esempio n. 1
0
static ssize_t ExampleDescRecvMsg(void *handle,
                                  struct NaClImcTypedMsgHdr *msg,
                                  int flags) {
  ssize_t result = 0;
  uint32_t index;

  CHECK(handle == g_handle);
  CHECK(msg->flags == 0);
  CHECK(flags == 0);

  /*
   * ndesc_length tells us how large the buffer is.  *Currently*, the
   * syscall allocates the same size buffer regardless of the buffer
   * size that untrusted code provided.  Furthermore, the buffer is
   * filled with NULLs to guard against RecvMsg() forgetting to set
   * ndesc_length.  However, a RecvMsg() implementation should not
   * rely on either of these things.
   */
  CHECK(msg->ndesc_length == NACL_ABI_IMC_DESC_MAX);
  for (index = 0; index < msg->ndesc_length; index++) {
    CHECK(msg->ndescv[index] == NULL);
  }

  if (g_desc_state == REPLY_WITH_DATA_ONLY) {
    result = WriteReplyData(msg, "test_receiving_data_only");
    /*
     * TODO(mseaborn): RecvMsg() currently has to set ndesc_length to
     * indicate how many descriptors are in the message.  Since
     * ndesc_length is used as an input and output parameter, there is
     * no way for a caller of RecvMsg() to have an assertion to check
     * whether RecvMsg() has forgotten to set ndesc_length.  We might
     * want to change this so that there are separate input and output
     * parameters.
     */
    msg->ndesc_length = 0;
    /*
     * TODO(mseaborn): RecvMsg() currently receives a pointer into
     * untrusted address space.  We might want to change things so
     * that RecvMsg() does not write directly into untrusted address
     * space.
     */
    CHECK(msg->iov_length == 1);
    CHECK(NaClIsUserAddr(g_nap, (uintptr_t) msg->iov[0].base));
  } else if (g_desc_state == REPLY_WITH_DESCS) {
    result = WriteReplyData(msg, "test_receiving_descs");
    /*
     * A non-test implementation would truncate the descriptor array
     * if the buffer were too small, rather than producing a fatal
     * error.
     */
    CHECK(msg->ndesc_length >= 2);
    msg->ndescv[0] = MakeExampleDesc();
    msg->ndescv[1] = MakeExampleDesc();
    msg->ndesc_length = 2;
  } else {
    NaClLog(LOG_FATAL, "RecvMsg called while in an expected state\n");
  }
  g_desc_state = REPLY_UNEXPECTED;
  return result;
}
Esempio n. 2
0
int NaClMachThreadStateIsInUntrusted(x86_thread_state_t *state,
                                     size_t nacl_thread_index) {
#if NACL_BUILD_SUBARCH == 32

  uint16_t global_cs;

  UNREFERENCED_PARAMETER(nacl_thread_index);

  CHECK(state->tsh.flavor == x86_THREAD_STATE32);

  global_cs = NaClGetGlobalCs();

  /*
   * If global_cs is 0 (which is not a usable segment selector), the
   * sandbox has not been initialised yet, so there can be no untrusted
   * code running.
   */
  if (global_cs == 0) {
    return 0;
  }

  return state->uts.ts32.__cs != global_cs;

#elif NACL_BUILD_SUBARCH == 64

  struct NaClAppThread *natp;

  CHECK(state->tsh.flavor == x86_THREAD_STATE64);

  natp = NaClAppThreadGetFromIndex(nacl_thread_index);
  return NaClIsUserAddr(natp->nap, state->uts.ts64.__rip);

#endif  /* NACL_BUILD_SUBARCH */
}
Esempio n. 3
0
static ssize_t ExampleDescSendMsg(void *handle,
                                  const struct NaClImcTypedMsgHdr *msg,
                                  int flags) {
  int result_code = 100;
  CHECK(handle == g_handle);
  CHECK(msg->flags == 0);
  CHECK(flags == 0);

  if (MessageDataMatches(msg, "test_sending_data_only")) {
    CHECK(msg->ndesc_length == 0);
    /*
     * TODO(mseaborn): SendMsg() currently receives a pointer into
     * untrusted address space.  We might want to change things so
     * that SendMsg() receives a copy of the message data.
     */
    CHECK(msg->iov_length == 1);
    CHECK(NaClIsUserAddr(g_nap, (uintptr_t) msg->iov[0].base));
    result_code = 101;
  } else if (MessageDataMatches(msg, "test_sending_descs")) {
    uint32_t index;
    for (index = 0; index < msg->ndesc_length; index++) {
      CHECK(msg->ndescv[index] == g_expected_desc);
    }
    CHECK(msg->ndesc_length == 2);
    result_code = 102;
  } else if (MessageDataMatches(msg, "request_receiving_data_only")) {
    CHECK(msg->ndesc_length == 0);
    g_desc_state = REPLY_WITH_DATA_ONLY;
    result_code = 200;
  } else if (MessageDataMatches(msg, "request_receiving_descs")) {
    CHECK(msg->ndesc_length == 0);
    g_desc_state = REPLY_WITH_DESCS;
    result_code = 200;
  } else {
    NaClLog(LOG_FATAL, "Unexpected message\n");
  }
  /*
   * imc_sendmsg() is normally expected to return the number of bytes
   * that were sent, but the custom descriptor can assign whatever
   * meaning it wants to the return value.  Here, for testing, we use
   * the return value to indicate which message was matched.
   */
  return result_code;
}