示例#1
0
文件: zmq_syscalls.c 项目: camuel/zvm
/* ###
 * get the fully qualified ip address from swift daemon
 * populate given NaClAppThread object with channel info
 * return 0 when success, otherwise - nacl error code
 */
int32_t ZMQSysOpen(struct NaClAppThread *natp, char *name, int flags, int mode)
{
	int32_t retval = 0;
	struct NaClHostDesc *hd;

	NaClLog(3, "Entered ZMQSysOpen(natp, %s, %X, %X)\n", name, flags, mode);

	/* ### dummy
	 * just open the local file w/o "http://" prefix to test this function
	 * example of file name: "http://dummy_zmq.dat" (will open "dummy_zmq.dat")
	 */
	hd = malloc(sizeof *hd);
	if (NULL == hd)
	{
		return -NACL_ABI_ENOMEM;
	}

	/* add extra info to hd */
//	strcpy(hd->channel, name); // ###
	NaClLog(1, "NaClHostDescOpen(0x%08"NACL_PRIxPTR", %s, 0%o, 0%o) returned %d\n",
			(uintptr_t) hd, name + URL_MARK_SIZE - 1, flags, mode, retval);

	/* add a new record to the file descriptors table */
	if (0 == retval)
	{
		retval = NaClSetAvail(natp->nap, ((struct NaClDesc *) NaClDescIoDescMake(hd)));
		NaClLog(1, "Entered url into open file table at %d\n", retval);
	}

	/* ### log to remove. i only use it to debug this class */
//	NaClLog(1, "int32_t ZMQSysOpen(struct NaClAppThread  *natp, char "
//			"*pathname, int flags, int mode): channel == %s, desc == %d\n", hd->channel, hd->d);
	return retval;
}
/*
 * Look up by string name, resulting in a handle (if name is in the
 * preimage), a object proxy handle, and an error code.
 */
static void NaClReverseServiceManifestLookupRpc(
    struct NaClSrpcRpc      *rpc,
    struct NaClSrpcArg      **in_args,
    struct NaClSrpcArg      **out_args,
    struct NaClSrpcClosure  *done_cls) {
  struct NaClReverseService *nrsp =
    (struct NaClReverseService *) rpc->channel->server_instance_data;
  char                      *url_key = in_args[0]->arrays.str;
  int                       flags = in_args[0]->u.ival;
  struct NaClFileInfo       info;
  struct NaClHostDesc       *host_desc;
  struct NaClDescIoDesc     *io_desc = NULL;
  struct NaClDesc           *nacl_desc = NULL;

  memset(&info, 0, sizeof(info));

  NaClLog(4, "Entered ManifestLookupRpc: 0x%08"NACL_PRIxPTR", %s, %d\n",
          (uintptr_t) nrsp, url_key, flags);

  NaClLog(4, "ManifestLookupRpc: invoking OpenManifestEntry\n");
  if (!(*NACL_VTBL(NaClReverseInterface, nrsp->iface)->
        OpenManifestEntry)(nrsp->iface, url_key, &info)
      || -1 == info.desc) {
    NaClLog(1, "ManifestLookupRpc: OpenManifestEntry failed.\n");
    out_args[0]->u.ival = NACL_ABI_ENOENT; /* failed */
    out_args[1]->u.hval = (struct NaClDesc *) NaClDescInvalidMake();
    out_args[2]->u.lval = 0;
    out_args[3]->u.lval = 0;
    out_args[4]->u.count = 0;
    goto done;
  }
  NaClLog(4, "ManifestLookupRpc: OpenManifestEntry returned desc %d.\n",
          info.desc);
  host_desc = (struct NaClHostDesc *) malloc(sizeof *host_desc);
  CHECK(host_desc != NULL);
  CHECK(NaClHostDescPosixTake(host_desc, info.desc, NACL_ABI_O_RDONLY) == 0);
  io_desc = NaClDescIoDescMake(host_desc);
  CHECK(io_desc != NULL);
  nacl_desc = (struct NaClDesc *) io_desc;

  out_args[0]->u.ival = 0;  /* OK */
  out_args[1]->u.hval = nacl_desc;
  out_args[2]->u.lval = (int64_t) info.file_token.lo;
  out_args[3]->u.lval = (int64_t) info.file_token.hi;
  out_args[4]->u.count = 10;
  strncpy(out_args[4]->arrays.carr, "123456789", 10);
  /*
   * TODO(phosek): the array should be an object reference (issue 3035).
   */

 done:
  rpc->result = NACL_SRPC_RESULT_OK;
  (*done_cls->Run)(done_cls);
  NaClDescSafeUnref((struct NaClDesc *) io_desc);
}
示例#3
0
struct NaClDescIoDesc *NaClDescIoDescOpen(char  *path,
                                          int   mode,
                                          int   perms) {
  struct NaClHostDesc *nhdp;

  nhdp = malloc(sizeof *nhdp);
  if (NULL == nhdp) {
    NaClLog(LOG_FATAL, "NaClDescIoDescOpen: no memory for %s\n", path);
  }
  if (0 != NaClHostDescOpen(nhdp, path, mode, perms)) {
    NaClLog(LOG_FATAL, "NaClDescIoDescOpen: NaClHostDescOpen failed for %s\n",
            path);
  }
  return NaClDescIoDescMake(nhdp);
}
示例#4
0
struct NaClDesc *NaClDescIoDescFromDescAllocCtor(int desc,
                                                 int flags) {
  struct NaClHostDesc *nhdp;

  nhdp = NaClHostDescPosixMake(desc, flags);
  if (NULL == nhdp) {
    /*
     * BUG: In Windows, we leak posix_d representation in the POSIX
     * layer, since caller will continue to own |handle| on a failure
     * return, but we cannot close |posix_d| without implicitly
     * invoking CloseHandle on |handle|.
     */
    return NULL;
  }
  return (struct NaClDesc *) NaClDescIoDescMake(nhdp);
}
示例#5
0
struct NaClDesc *NaClDescIoDescMakeFromHandle(NaClHandle handle) {
  int posix_d;
  struct NaClHostDesc *nhdp;
  struct NaClDescIoDesc *desc;

#if NACL_WINDOWS
  posix_d = _open_osfhandle((intptr_t) handle, _O_RDWR | _O_BINARY);
  if (-1 == posix_d)
    return NULL;
#else
  posix_d = handle;
#endif
  nhdp = NaClHostDescPosixMake(posix_d, NACL_ABI_O_RDWR);
  if (NULL == nhdp)
    return NULL;
  desc = NaClDescIoDescMake(nhdp);
  return &desc->base;
}
示例#6
0
文件: premap.c 项目: bortoq/zerovm
/*
 * premap given file (channel). return 0 if success, otherwise negative errcode
 * note: malloc()
 */
int PremapChannel(struct NaClApp *nap, struct PreOpenedFileDesc* channel)
{
  int desc;
  struct NaClHostDesc *hd = malloc(sizeof(*hd));

  /* debug checks */
  COND_ABORT(!hd, "cannot allocate memory to hold channel descriptor\n");
  COND_ABORT(!channel, "channel is not constructed\n");
  COND_ABORT(channel->mounted != MAPPED, "channel is not supposed to be mapped\n");
  COND_ABORT(!channel->name, "cannot resolve channel name\n");

  /* open file */
  channel->handle = open((char*)channel->name, GetChannelOpenFlags(channel), S_IRWXU);
  COND_ABORT(channel->handle < 0, "channel open error\n");

  /* check if given file in bounds of manifest limits */
  channel->fsize = GetFileSize((char*)channel->name);
  PreallocateChannel(channel);
  COND_ABORT(channel->max_size < channel->fsize, "channel legnth exceeded policy limit\n");

  /* construct nacl descriptor */
  hd->d = channel->handle;
  desc = NaClSetAvail(nap, ((struct NaClDesc *) NaClDescIoDescMake(hd)));

  /* map whole file into the memory. address cannot be higher than stack */
  channel->buffer = NaClCommonSysMmapIntern(nap, NULL, channel->fsize,
      GetChannelMapProt(channel), GetChannelMapFlags(channel), desc, 0);
  COND_ABORT((uint32_t)channel->buffer > 0xFF000000, "channel map error\n");


  /* mounting finalization */
  close(channel->handle);
  channel->bsize = channel->fsize; /* yes. mapped file always put to memory whole */
  channel->handle = -1; /* there is no opened file for mapped channel */

  return 0;
}
示例#7
0
int32_t NaClSysOpen(struct NaClAppThread  *natp,
                    uint32_t              pathname,
                    int                   flags,
                    int                   mode) {
  struct NaClApp       *nap = natp->nap;
  uint32_t             retval = -NACL_ABI_EINVAL;
  char                 path[NACL_CONFIG_PATH_MAX];
  nacl_host_stat_t     stbuf;
  int                  allowed_flags;

  NaClLog(3, "NaClSysOpen(0x%08"NACL_PRIxPTR", "
          "0x%08"NACL_PRIx32", 0x%x, 0x%x)\n",
          (uintptr_t) natp, pathname, flags, mode);

  if (!NaClAclBypassChecks) {
    return -NACL_ABI_EACCES;
  }

  retval = CopyPathFromUser(nap, path, sizeof path, (uintptr_t) pathname);
  if (0 != retval)
    goto cleanup;

  allowed_flags = (NACL_ABI_O_ACCMODE | NACL_ABI_O_CREAT | NACL_ABI_O_EXCL
                   | NACL_ABI_O_TRUNC | NACL_ABI_O_APPEND
                   | NACL_ABI_O_DIRECTORY);
  if (0 != (flags & ~allowed_flags)) {
    NaClLog(LOG_WARNING, "Invalid open flags 0%o, ignoring extraneous bits\n",
            flags);
    flags &= allowed_flags;
  }
  if (0 != (mode & ~0600)) {
    NaClLog(1, "IGNORING Invalid access mode bits 0%o\n", mode);
    mode &= 0600;
  }

  /*
   * Perform a stat to determine whether the file is a directory.
   *
   * NB: it is okay for the stat to fail, since the request may be to
   * create a new file.
   *
   * There is a race conditions here: between the stat and the
   * open-as-a-file and open-as-a-dir, the type of the object that the
   * path refers to can change.
   */
  retval = NaClHostDescStat(path, &stbuf);

  /* Windows does not have S_ISDIR(m) macro */
  if (0 == retval && S_IFDIR == (S_IFDIR & stbuf.st_mode)) {
    struct NaClHostDir  *hd;
    /*
     * Directories cannot be opened with O_EXCL. Technically, due to the above
     * race condition we might no longer be dealing with a directory, but
     * until the race is fixed this is best we can do.
     */
    if (flags & NACL_ABI_O_EXCL) {
      retval = -NACL_ABI_EEXIST;
      goto cleanup;
    }

    hd = malloc(sizeof *hd);
    if (NULL == hd) {
      retval = -NACL_ABI_ENOMEM;
      goto cleanup;
    }
    retval = NaClHostDirOpen(hd, path);
    NaClLog(1, "NaClHostDirOpen(0x%08"NACL_PRIxPTR", %s) returned %d\n",
            (uintptr_t) hd, path, retval);
    if (0 == retval) {
      retval = NaClAppSetDescAvail(
          nap, (struct NaClDesc *) NaClDescDirDescMake(hd));
      NaClLog(1, "Entered directory into open file table at %d\n",
              retval);
    }
  } else {
    struct NaClHostDesc  *hd;

    if (flags & NACL_ABI_O_DIRECTORY) {
      retval = -NACL_ABI_ENOTDIR;
      goto cleanup;
    }

    hd = malloc(sizeof *hd);
    if (NULL == hd) {
      retval = -NACL_ABI_ENOMEM;
      goto cleanup;
    }
    retval = NaClHostDescOpen(hd, path, flags, mode);
    NaClLog(1,
            "NaClHostDescOpen(0x%08"NACL_PRIxPTR", %s, 0%o, 0%o) returned %d\n",
            (uintptr_t) hd, path, flags, mode, retval);
    if (0 == retval) {
      struct NaClDesc *desc = (struct NaClDesc *) NaClDescIoDescMake(hd);
      if ((flags & NACL_ABI_O_ACCMODE) == NACL_ABI_O_RDONLY) {
        /*
         * Let any read-only open be used for PROT_EXEC mmap
         * calls.  Under -a, the user informally warrants that
         * files' code segments won't be changed after open.
         */
        NaClDescSetFlags(desc,
                         NaClDescGetFlags(desc) | NACL_DESC_FLAGS_MMAP_EXEC_OK);
      }
      retval = NaClAppSetDescAvail(nap, desc);
      NaClLog(1, "Entered into open file table at %d\n", retval);
    }
  }
cleanup:
  return retval;
}
示例#8
0
int main(int ac, char **av) {
  int                         opt;
  char const                  *message = NULL;
  char                        *conn_addr = NULL;
  ssize_t                     rv;
  struct NaClDesc             *channel;
  struct NaClNrdXferEffector  eff;
  struct NaClDescEffector     *effp;
  struct NaClDesc             *pair[2];
  struct NaClSocketAddress    nsa;
  struct NaClDescConnCap      ndcc;
  struct NaClImcTypedMsgHdr   msg_hdr;
  struct NaClImcMsgIoVec      iov[1];
  struct NaClDesc             *desc_buffer[NACL_ABI_IMC_USER_DESC_MAX];
  char                        data_buffer[4096];
  size_t                      i;
  char                        *transfer_file = NULL;

  printf("Hello world\n");

  NaClNrdAllModulesInit();

  printf("Learning to walk... (parsing command line)\n");

  while (EOF != (opt = getopt(ac, av, "c:m:st:v"))) {
    switch (opt) {
      case 'c':
        conn_addr = optarg;
        break;
      case 'm':
        message = optarg;
        break;
      case 's':
        server = 1;
        break;
      case 't':
        transfer_file = optarg;
        break;
      case 'v':
        NaClLogIncrVerbosity();
        break;
      default:
        fprintf(stderr,
                "Usage: nrd_xfer_test [-sv] [-c connect-addr] [-m message]\n"
                "         [-t transfer_file_name]\n"
                "\n");
        fprintf(stderr,
                 "    -s run in server mode (prints NaCl sock addr)\n"
                 "    -v increases verbosity in the NRD xfer library\n"
                 "    -c run in client mode, with server NaCl sock addr as\n"
                 "       parameter\n"
                 "    -m message to be sent to peer (client sends message\n"
                 "       as payload data in IMC datagram; and if -t was\n"
                 "       specifed in the client to transfer a file\n"
                 "       descriptor to the server, the server will write its\n"
                 "       message into the file via the transferred\n"
                 "       descriptor\n");
        return 1;
    }
  }

  printf("Learning to talk... (setting up channels)\n");

  if (NULL == message) {
    if (server) {
      message = "\"Hello world!\", from server\n";
    } else {
      message = "\"Goodbye cruel world!\", from client\n";
    }
  }

  if (0 != (rv = NaClCommonDescMakeBoundSock(pair))) {
    fprintf(stderr, "make bound sock returned %"NACL_PRIdS"\n", rv);
    return 2;
  }

  if (!NaClNrdXferEffectorCtor(&eff, pair[0])) {
    fprintf(stderr, "EffectorCtor failed\n");
    return 3;
  }
  effp = (struct NaClDescEffector *) &eff;
  memset(desc_buffer, 0, sizeof desc_buffer);
  memset(data_buffer, 0, sizeof data_buffer);

  if (server) {
    /*
     * print out our sockaddr, accept a connection, then receive a message,
     * and print it out
     */

    /* not opaque type */
    printf("Server socket address:\n%.*s\n",
           NACL_PATH_MAX,
           ((struct NaClDescConnCap *) pair[1])->cap.path);
    fflush(stdout);

    if (0 != (rv = (*pair[0]->vtbl->AcceptConn)(pair[0], effp))) {
      fprintf(stderr, "AcceptConn returned %"NACL_PRIdS"\n", rv);
      return 4;
    }

    channel = NaClNrdXferEffectorTakeDesc(&eff);
    if (NULL == channel) {
      fprintf(stderr, "Could not take descriptor from accept\n");
      return 5;
    }

    iov[0].base = data_buffer;
    iov[0].length = sizeof data_buffer;

    msg_hdr.iov = iov;
    msg_hdr.iov_length = NACL_ARRAY_SIZE(iov);
    msg_hdr.ndescv = desc_buffer;
    msg_hdr.ndesc_length = NACL_ARRAY_SIZE(desc_buffer);

    rv = NaClImcRecvTypedMessage(channel, effp, &msg_hdr, 0);

    printf("Receive returned %"NACL_PRIdS"\n", rv);

    if (!NaClIsNegErrno(rv)) {
      /* Sanity check: make sure the return value is within range.
       * This is a panic check because NaClImcRecvTypedMessage should
       * never return more than the amount of data we asked for, and
       * that should never be more than INT_MAX.
       */
      if(((size_t)rv > sizeof data_buffer) || (rv > INT_MAX)) {
        NaClLog(LOG_FATAL, "Buffer overflow in NaClImcRecvTypedMessage. "
                "Requested %"NACL_PRIdS" bytes, received %"NACL_PRIdS".",
                sizeof data_buffer, rv);
      }
      /* Casting rv to int here because otherwise the pedantic Mac compiler
       * will complain. Cast is safe due to the range check above.
       */
      printf("Data bytes: %.*s\n", (int)rv, data_buffer);
      printf("Got %"NACL_PRIdNACL_SIZE" NaCl descriptors\n",
             msg_hdr.ndesc_length);

      for (i = 0; i < msg_hdr.ndesc_length; ++i) {
        struct NaClDesc *ndp;
        size_t msglen = strlen(message);
        ssize_t write_result;
        /*
         * TODO(bsy): a bit gross; we should expose type tags and RTTI
         * in a better way, e.g, downcast functions.  (Though exposing
         * type tags allows users to use a switch statement on the
         * type tag, rather than linearly trying to downcast to all
         * subclasses.)
         */
        ndp = msg_hdr.ndescv[i];
        printf(" type %d\n", ndp->vtbl->typeTag);

        write_result = (*ndp->vtbl->Write)(ndp,
                                           effp,
                                           (void *) message,
                                           msglen);
        if (-1 == write_result || msglen != (size_t) write_result) {
          printf("Write failed: got %"NACL_PRIdS", expected %"NACL_PRIuS"\n",
                 write_result, msglen);
        }

        NaClDescUnref(ndp);
      }
    }

    NaClDescUnref(channel);
    NaClDescUnref(pair[0]);
    NaClDescUnref(pair[1]);

  } else {
    if (NULL == conn_addr) {
      fprintf(stderr,
              "Client needs server socket address to which to connect\n");
      return 100;
    }

    memset(&nsa, 0, sizeof nsa);
    strncpy(nsa.path, conn_addr, sizeof nsa.path);  /* not nec'y NUL term'd */

    if (!NaClDescConnCapCtor(&ndcc, &nsa)) {
      fprintf(stderr,
              "Client conn cap initialization failed\n");
      return 101;
    }

    rv = (*ndcc.base.vtbl->ConnectAddr)((struct NaClDesc *) &ndcc, effp);

    printf("Connect returned %"NACL_PRIdS"\n", rv);

    if (0 != rv) {
      fprintf(stderr, "Client could not connect\n");
      return 102;
    }

    channel = NaClNrdXferEffectorTakeDesc(&eff);
    if (NULL == channel) {
      fprintf(stderr, "Could not take descriptor from connect\n");
      return 103;
    }

    strncpy(data_buffer, message, sizeof data_buffer);
    iov[0].base = data_buffer;
    iov[0].length = strlen(data_buffer);

    msg_hdr.iov = iov;
    msg_hdr.iov_length = NACL_ARRAY_SIZE(iov);
    msg_hdr.ndesc_length = 0;
    msg_hdr.ndescv = desc_buffer;

    if (NULL != transfer_file) {
      int                 xfer_fd;
      struct NaClHostDesc *nhdp = malloc(sizeof *nhdp);

      xfer_fd = OPEN(transfer_file, O_CREAT| O_WRONLY | O_TRUNC, 0777);
      if (-1 == xfer_fd) {
        fprintf(stderr, "Could not open file \"%s\" to transfer descriptor.\n",
                transfer_file);
        return 104;
      }
      NaClHostDescPosixTake(nhdp, xfer_fd, O_RDWR);
      desc_buffer[0] = (struct NaClDesc *) NaClDescIoDescMake(nhdp);
      msg_hdr.ndesc_length = 1;
    }

    rv = NaClImcSendTypedMessage(channel, effp, &msg_hdr, 0);

    if (NULL != desc_buffer[0]) {
      NaClDescUnref(desc_buffer[0]);
      desc_buffer[0] = NULL;
    }

    printf("Send returned %"NACL_PRIdS"\n", rv);
  }

  (*effp->vtbl->Dtor)(effp);

  NaClNrdAllModulesFini();
  return 0;
}