Ejemplo n.º 1
0
/*
 * See discussion at NaClDescXferableDataDescSendMsg for details.  An
 * imc_recvmsg race is not substantively different from an imc_sendmsg
 * race.
 */
static ssize_t NaClDescXferableDataDescRecvMsg(struct NaClDesc          *vself,
                                               struct NaClMessageHeader *dgram,
                                               int                      flags) {
  struct NaClDescXferableDataDesc *self = ((struct NaClDescXferableDataDesc *)
                                           vself);
  int                             result;

  NaClLog(4, "Entered NaClDescXferableDataDescRecvMsg, h = %d\n", self->base.h);
  if (0 != dgram->handle_count) {
    /*
     * A transferable descriptor is data-only, and it is an error to
     * try to receive any I/O descriptors with it.
     */
    NaClLog(2,
            "NaClDescXferableDataDescRecvMsg:"
            " tranferable and non-zero handle_count\n");
    return -NACL_ABI_EINVAL;
  }

  result = NaClReceiveDatagram(self->base.h, dgram, flags);

  if (-1 == result) {
    return -errno;
  }
  return result;
}
/*
 * See discussion at NaClDescXferableDataDescLowLevelSendMsg for details.  An
 * imc_recvmsg race is not substantively different from an imc_sendmsg
 * race.
 */
static ssize_t NaClDescXferableDataDescLowLevelRecvMsg(
    struct NaClDesc          *vself,
    struct NaClMessageHeader *dgram,
    int                      flags) {
  struct NaClDescXferableDataDesc *self = ((struct NaClDescXferableDataDesc *)
                                           vself);
  int                             result;

  NaClLog(4, "Entered NaClDescXferableDataDescLowLevelRecvMsg, h = %d\n",
          self->base.h);
  if (0 != dgram->handle_count) {
    /*
     * A transferable descriptor is data-only, and it is an error to
     * try to receive any I/O descriptors with it.
     */
    NaClLog(2,
            "NaClDescXferableDataDescLowLevelRecvMsg:"
            " tranferable and non-zero handle_count\n");
    return -NACL_ABI_EINVAL;
  }

  result = NaClReceiveDatagram(self->base.h, dgram, flags);

  if (-1 == result) {
#if NACL_WINDOWS
    return -NaClXlateSystemError(GetLastError());
#elif NACL_LINUX || NACL_OSX
    return -errno;
#else
# error "Unknown target platform: cannot translate error code(s) from RecvMsg"
#endif
  }
  return result;
}
Ejemplo n.º 3
0
int main(int argc, char* argv[]) {
  int result;
  NaClHandle pair[2];
  NaClMessageHeader header;
  NaClIOVec vec;
  char buffer[] = "Hello!";

  g_front = NaClBoundSocket(&test_address);
  if (g_front == NACL_INVALID_HANDLE) {
    PrintError("BoundSocket");
    exit(EXIT_FAILURE);
  }
  atexit(CleanUp);

  if (NaClSocketPair(pair) != 0) {
    PrintError("SocketPair");
    exit(EXIT_FAILURE);
  }

  vec.base = buffer;
  vec.length = sizeof buffer;

  /* Test SendDatagram */
  header.iov = &vec;
  header.iov_length = 1;
  header.handles = NULL;
  header.handle_count = 0;
  result = NaClSendDatagram(pair[0], &header, 0);
  assert(result == sizeof buffer);

  /* Test ReceiveDatagram */
  memset(buffer, 0, sizeof buffer);
  header.iov = &vec;
  header.iov_length = 1;
  header.handles = NULL;
  header.handle_count = 0;
  result = NaClReceiveDatagram(pair[1], &header, 0);
  assert(result == sizeof buffer);

  assert(strcmp(buffer, "Hello!") == 0);
  printf("%s\n", buffer);

  (void) NaClClose(pair[0]);
  (void) NaClClose(pair[1]);

  return 0;
}
Ejemplo n.º 4
0
/*
 * See discussion at NaClDescImcDescSendMsg for details.  An
 * imc_recvmsg race is not substantively different from an imc_sendmsg
 * race.
 */
static ssize_t NaClDescImcDescRecvMsg(struct NaClDesc          *vself,
                                      struct NaClMessageHeader *dgram,
                                      int                      flags) {
  struct NaClDescImcDesc *self = ((struct NaClDescImcDesc *)
                                  vself);
  int result;

  NaClLog(4, "Entered NaClDescImcDescRecvMsg, h=%d\n", self->base.h);
  NaClXMutexLock(&self->recvmsg_mu);
  result = NaClReceiveDatagram(self->base.h, dgram, flags);
  NaClXMutexUnlock(&self->recvmsg_mu);

  if (-1 == result) {
    return -errno;
  }
  return result;
}
/*
 * See discussion at NaClDescImcDescLowLevelSendMsg for details.  An
 * imc_recvmsg race is not substantively different from an imc_sendmsg
 * race.
 */
static ssize_t NaClDescImcDescLowLevelRecvMsg(struct NaClDesc          *vself,
                                              struct NaClMessageHeader *dgram,
                                              int                      flags) {
  struct NaClDescImcDesc *self = ((struct NaClDescImcDesc *)
                                  vself);
  int result;

  NaClLog(4, "Entered NaClDescImcDescLowLevelRecvMsg, h=%d\n", self->base.h);
  NaClXMutexLock(&self->recvmsg_mu);
  result = NaClReceiveDatagram(self->base.h, dgram, flags);
  NaClXMutexUnlock(&self->recvmsg_mu);

  if (-1 == result) {
#if NACL_WINDOWS
    return -NaClXlateSystemError(GetLastError());
#elif NACL_LINUX || NACL_OSX
    return -errno;
#else
# error "Unknown target platform: cannot translate error code(s) from RecvMsg"
#endif
  }
  return result;
}
static int NaClDescImcBoundDescAcceptConn(struct NaClDesc *vself,
                                          struct NaClDesc **result) {
  /*
   * See NaClDescConnCapConnectAddr code in nacl_desc_conn_cap.c
   */
  struct NaClDescImcBoundDesc *self;
  int                         retval;
  NaClHandle                  nh;
  int                         nbytes;
  struct NaClMessageHeader    conn_msg;
  struct NaClDescImcDesc      *peer;

  self = (struct NaClDescImcBoundDesc *) vself;

  if (NULL == (peer = malloc(sizeof *peer))) {
    return -NACL_ABI_ENOMEM;
  }

  conn_msg.iov = 0;
  conn_msg.iov_length = 0;
  conn_msg.handle_count = 1;
  conn_msg.handles = &nh;
  conn_msg.flags = 0;
  nh = NACL_INVALID_HANDLE;

  NaClLog(3,
          ("NaClDescImcBoundDescAcceptConn(0x%08"NACL_PRIxPTR"):"
           " h = %d\n"),
          (uintptr_t) vself,
          self->h);

  if (-1 == (nbytes = NaClReceiveDatagram(self->h, &conn_msg, 0))) {
    NaClLog(LOG_ERROR,
            ("NaClDescImcBoundDescAcceptConn:"
             " could not receive connection message, errno %d\n"),
            errno);
    retval = -NACL_ABI_EMFILE;
    goto cleanup;
  }
  if (0 != nbytes) {
    NaClLog(LOG_ERROR, ("NaClDescImcBoundDescAcceptConn:"
                        " connection message contains data?!?\n"));
    retval = -NACL_ABI_EMFILE;  /* TODO(bsy): better errno? */
    goto cleanup;
  }
  if (1 != conn_msg.handle_count) {
    NaClLog(LOG_ERROR, ("NaClDescImcBoundDescAcceptConn: connection"
                        " message contains %"NACL_PRIdS" descriptors?!?\n"),
            conn_msg.handle_count);
    retval = -NACL_ABI_EMFILE;  /* TODO(bsy): better errno? */
    goto cleanup;
  }
  if (!NaClDescImcDescCtor(peer, nh)) {
    retval = -NACL_ABI_EMFILE;
    goto cleanup;
  }
  nh = NACL_INVALID_HANDLE;

  *result = (struct NaClDesc *) peer;
  retval = 0;

cleanup:
  if (retval < 0) {
    if (NACL_INVALID_HANDLE != nh) {
      (void) NaClClose(nh);
      nh = NACL_INVALID_HANDLE;
    }
    free(peer);
  }
  return retval;
}
Ejemplo n.º 7
0
int main(int argc, char **argv) {
  
  struct NaClApp app;
  struct NaClDesc *nd;
  NaClHandle handle_pair[2];
  char *parse_args[] = {"prog", "parse"};
  int return_code;
  char buffer[100];
  NaClMessageHeader header;
  NaClIOVec vec;

  struct ncwebserver_t server;
  struct ncwebserver_conf_t conf;

  if (argc < 2){
    usage(ncwebserver_usage_string);
  }

  NaClAllModulesInit();
  NaClFileNameForValgrind(argv[1]);
  nd = (struct NaClDesc *) NaClDescIoDescOpen(argv[1], NACL_ABI_O_RDONLY, 0);
  CHECK(NULL != nd);
  CHECK(NaClAppCtor(&app));
  /* Use a smaller guest address space size, because 32-bit Windows
     does not let us allocate 2GB of address space.  We don't do this
     for x86-64 because there is an assertion in NaClAllocateSpace()
     that requires 4GB. */
#if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
  app.addr_bits = 29; /* 512MB per process */
#endif
  /*
   * On x86-32, we cannot enable ASLR even when the address space is
   * 512MB.  In particular, when on Windows where the available
   * contiguous address space is tight, if the random choice for the
   * base of the first 512MB address space puts that address space
   * in the middle of the available address space region, the
   * address space allocation code might not be able to (randomly)
   * find another contiguous 512MB region for the second NaCl
   * module.
   */
  CHECK(NaClAppLoadFileAslr(nd, &app,
                            NACL_DISABLE_ASLR) == LOAD_OK);
  NaClAppInitialDescriptorHookup(&app);
  CHECK(NaClAppPrepareToLaunch(&app) == LOAD_OK);
  /* Set up an IMC connection between the host and guest. */
  CHECK(NaClSocketPair(handle_pair) == 0);
  NaClAddImcHandle(&app, handle_pair[0], SEND_DESC);
  CHECK(NaClCreateMainThread(&app, 2, parse_args, NULL));
  return_code = NaClWaitForMainThreadToExit(&app);
  CHECK(return_code == 101);

  // receive message sent from HTML parser
  vec.base = buffer;
  vec.length = sizeof buffer;
  memset(buffer, 0, sizeof buffer);
  header.iov = &vec;
  header.iov_length = 1;
  header.handles = NULL;
  header.handle_count = 0;
  return_code = NaClReceiveDatagram(handle_pair[1], &header, 0);
  assert(return_code == sizeof buffer);
  printf("Server received \"%s\" (with size = %d)\n", buffer+16, return_code);

  // run web server
  memset(&conf, 0, sizeof(conf));
  parse_argv(argc, argv, &conf);
  ncwebserver_init(&server, &conf);
  ncwebserver_start(&server);

  /*
   * Avoid calling exit() because it runs process-global destructors
   * which might break code that is running in our unjoined threads.
   */
  NaClExit(0);
}