Exemple #1
0
/*
 * mount given channel (must be constructed) with a given mode/attributes
 * return 0 - when everything is ok, otherwise - negative error
 */
int MountChannel(struct NaClApp *nap, enum ChannelType ch)
{
  struct PreOpenedFileDesc *channel = &nap->manifest->user_setup->channels[ch];
  if(channel)
  {
    switch(channel->mounted)
    {
      int code;
      case MAPPED:
        code = PremapChannel(nap, channel);
        COND_ABORT(code, "cannot premap channel\n");
        break;
      case LOADED:
        code = PreloadChannel(nap, channel);
        COND_ABORT(code, "cannot preload channel\n");
        break;
      case NETWORK:
        code = PrefetchChannel(nap, channel);
        COND_ABORT(code, "cannot allocate network channel\n");
        break;
      default:
        COND_ABORT(1, "mounting method not supported\n");
        break;
    }
  }
  return 0;
}
Exemple #2
0
/*
 * construct SetupList (policy) part of manifest structure (w/o channels)
 * note: malloc(). must be called only once
 */
void SetupUserPolicy(struct NaClApp *nap)
{
  /* allocate space for policy */
  struct SetupList *policy = malloc(sizeof(*policy));
  COND_ABORT(!policy, "cannot allocate memory for user policy\n");
  policy->self_size = sizeof(*policy); /* set self size */

  /* setup limits */
  TRANSET(policy->max_cpu, "CPUMax");
  TRANSET(policy->max_mem, "MemMax");
  TRANSET(policy->max_setup_calls, "SetupCallsMax");
  TRANSET(policy->max_syscalls, "SyscallsMax");

  /* setup counters */
  policy->cnt_cpu = 0;
  policy->cnt_cpu_last = 0;
  policy->cnt_mem = 0;
  policy->cnt_setup_calls = 0;
  policy->cnt_syscalls = 0;
  policy->heap_ptr = 0; /* set user heap to NULL until it allocated */

  /* clear syscallback */
  policy->syscallback = 0;

  /* setup custom attributes */
#define STRNCPY_NULL(a, b, n) if ((a) && (b)) strncpy(a, b, n);
  STRNCPY_NULL(policy->content_type, get_value_by_key(nap, "ContentType"), CONTENT_TYPE_LEN);
  STRNCPY_NULL(policy->timestamp, get_value_by_key(nap, "TimeStamp"), TIMESTAMP_LEN);
  STRNCPY_NULL(policy->x_object_meta_tag, get_value_by_key(nap, "XObjectMetaTag"), X_OBJECT_META_TAG_LEN);
  STRNCPY_NULL(policy->user_etag, get_value_by_key(nap, "UserETag"), USER_TAG_LEN);
#undef STRNCPY_NULL
  nap->manifest->user_setup = policy;
}
Exemple #3
0
/*
 * preallocate channel. for output files only. since we cannot say how much user
 * program will use we only can allocate max size provided for current channel
 * note: must be called from PremapChannel() after file opened and measured
 * note: user_log file will be trimmed to asciiz string size it contain
 */
static void PreallocateChannel(struct PreOpenedFileDesc* channel)
{
  if(channel->fsize != channel->max_size &&
      (channel->type == OutputChannel || channel->type == LogChannel))
  {
    int ret_code = ftruncate(channel->handle, channel->max_size);
    COND_ABORT(ret_code < 0, "cannot set the channel size\n");
    channel->fsize = channel->max_size;
  }
}
Exemple #4
0
/*
 * preload given file (channel). return 0 if success, otherwise negative errcode
 */
int PreloadChannel(struct NaClApp *nap, struct PreOpenedFileDesc* channel)
{
  /* debug checks */
  if(!channel->name) return -1; /* channel is not constructed. skip it */
  COND_ABORT(channel->mounted != LOADED, "channel is not supposed to be loaded\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");

  /* mounting finalization */
  channel->bsize = -1; /* will be provided by user */
  return 0;
}
Exemple #5
0
/*
 * construct SystemList (zerovm settings) part of manifest structure
 * note: malloc(). must be called only once
 */
void SetupSystemPolicy(struct NaClApp *nap)
{
  /* allocate space for policy */
  struct SystemList *policy = malloc(sizeof(*policy));
  COND_ABORT(!policy, "cannot allocate memory for system policy\n");

  /* get zerovm settings */
  policy->version = get_value_by_key(nap, "Version");
  policy->zerovm = get_value_by_key(nap, "ZeroVM");
  policy->log = get_value_by_key(nap, "Log");
  policy->report = get_value_by_key(nap, "Report");
  COND_ABORT(policy->nexe, "nexe file name is already specified in the command line\n");
  policy->nexe = get_value_by_key(nap, "Nexe");
  policy->blob = get_value_by_key(nap, "Blob");
  policy->nexe_etag = get_value_by_key(nap, "NexeEtag");

  TRANSET(policy->nexe_max, "NexeMax");
  TRANSET(policy->timeout, "Timeout");
  TRANSET(policy->kill_timeout, "KillTimeout");

  nap->manifest->system_setup = policy;
}
Exemple #6
0
/*
 * construct Report (zerovm report to proxy) part of manifest structure
 * note: malloc(). must be called only once
 */
void SetupReportSettings(struct NaClApp *nap)
{
  /* allocate space for report */
  struct Report *report = malloc(sizeof(*report)); // ### memory must be allocated before nexe start
  COND_ABORT(!report, "cannot allocate memory for report\n");

  /* set results */
  report->etag = MakeEtag(nap);
  report->content_type = "application/octet-stream"; // where to get it?
  report->x_object_meta_tag = "Format:Pickle"; // where to get it?

  /* ### ret codes must be set from main() */
  nap->manifest->report = report;
}
Exemple #7
0
/*
 * construct Report (zerovm report to proxy) part of manifest structure
 * note: malloc(). must be called only once
 */
void SetupReportSettings(struct NaClApp *nap)
{
  /*
   * allocate space for report
   * todo: memory must be allocated before nexe start
   */
  struct Report *report = malloc(sizeof(*report));
  COND_ABORT(!report, "cannot allocate memory for report\n");

  /* set results. note: etag is temporary disabled  */
  report->etag = MakeEtag(nap);

  /* get custom attributes from the manifest */
  report->content_type = get_value_by_key(nap, "ContentType");
  report->x_object_meta_tag = get_value_by_key(nap, "XObjectMetaTag");

  nap->manifest->report = report;
}
Exemple #8
0
/*
 * preallocate memory area of given size. abort if fail
 */
void PreallocateUserMemory(struct NaClApp *nap)
{
  struct SetupList *policy = nap->manifest->user_setup;
  uintptr_t i = nap->data_end;
  uint32_t stump = nap->manifest->user_setup->max_mem - nap->stack_size - nap->data_end;
  uint32_t dead_space;
  struct NaClVmmapEntry *user_space;

  /* check if max_mem is specified in manifest and proceed if so */
  if(!policy->max_mem) return;

  /* user memory chunk must be allocated next to the data end */
  i = (i + NACL_MAP_PAGESIZE - 1) & ~(NACL_MAP_PAGESIZE - 1);

  policy->heap_ptr = NaClCommonSysMmapIntern(nap, (void*)i, stump, 3, 0x22, -1, 0);
  assert(policy->heap_ptr == i);

  /*
   * free "whole chunk" block without real memory deallocation
   * the map entry we need is the last in raw
   */
  user_space = nap->mem_map.vmentry[nap->mem_map.nvalid - 1];
  assert(policy->heap_ptr / NACL_PAGESIZE == user_space->page_num);
  assert(nap->mem_map.is_sorted != 1);

  /* protect dead space */
  dead_space = NaClVmmapFindMaxFreeSpace(&nap->mem_map, 1) * NACL_PAGESIZE;
  i = (user_space->page_num + user_space->npages) * NACL_PAGESIZE;
  dead_space = NaClCommonSysMmapIntern(nap, (void*)i, dead_space, 0, 0x22, -1, 0);
  assert(dead_space == i);

  /* sort and remove deleted blocks */
  user_space->removed = 1;
  nap->mem_map.is_sorted = 0; /* force sort because we need to get rid of removed blocks */
  NaClVmmapMakeSorted(&nap->mem_map);

  /* why 0xfffff000? 1. 0x1000 reserved for error codes 2. it is still larger then 4gb - stack */
  COND_ABORT(policy->heap_ptr > 0xfffff000, "cannot preallocate memory for user\n");
}
Exemple #9
0
/*
 * construct SystemList (zerovm settings) part of manifest structure
 * note: malloc(). must be called only once
 */
void SetupSystemPolicy(struct NaClApp *nap)
{
  /* allocate space for policy */
  struct SystemList *policy = malloc(sizeof(*policy));
  COND_ABORT(!policy, "cannot allocate memory for system policy\n");

  /* get zerovm settings */
  policy->version = GetValueByKey(nap, "Version");
  policy->zerovm = GetValueByKey(nap, "ZeroVM");
  policy->log = GetValueByKey(nap, "Log");
  policy->report = GetValueByKey(nap, "Report");
  policy->nexe = GetValueByKey(nap, "Nexe");
  policy->cmd_line = GetValueByKey(nap, "CommandLine");
  policy->blob = GetValueByKey(nap, "Blob");
  policy->nexe_etag = GetValueByKey(nap, "NexeEtag");

  TRANSET(policy->nexe_max, "NexeMax");
  TRANSET(policy->timeout, "Timeout");
  TRANSET(policy->kill_timeout, "KillTimeout");

  nap->manifest->system_setup = policy;
}
Exemple #10
0
/*
 * 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;
}
Exemple #11
0
/*
 * infere file open flags by channel prefix
 */
static int GetChannelOpenFlags(struct PreOpenedFileDesc* channel)
{
  int flags[] = CHANNEL_OPEN_FLAGS;
  COND_ABORT(channel->type >= sizeof(flags)/sizeof(*flags), "unknown channel type\n");
  return flags[channel->type];
}
Exemple #12
0
/*
 * set "prefix" (channel name) by "ch" (channel id)
 * note: prefix must have enough space to hold it
 */
static void GetChannelPrefixById(enum ChannelType ch, char *prefix)
{
  char *prefixes[] = CHANNEL_PREFIXES;
  COND_ABORT(ch >= sizeof(prefixes)/sizeof(*prefixes), "unknown channel id\n");
  strcpy(prefix, prefixes[ch]);
}