/* * 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, GetValueByKey(nap, "ContentType"), CONTENT_TYPE_LEN); STRNCPY_NULL(policy->timestamp, GetValueByKey(nap, "TimeStamp"), TIMESTAMP_LEN); STRNCPY_NULL(policy->x_object_meta_tag, GetValueByKey(nap, "XObjectMetaTag"), X_OBJECT_META_TAG_LEN); STRNCPY_NULL(policy->user_etag, GetValueByKey(nap, "UserETag"), USER_TAG_LEN); #undef STRNCPY_NULL nap->manifest->user_setup = policy; }
/* construct system_manifest object and initialize it from manifest */ void SystemManifestCtor(struct NaClApp *nap) { struct SystemManifest *policy; /* check for design errors */ assert(nap != NULL); assert(nap->system_manifest != NULL); policy = nap->system_manifest; policy->syscallback = 0; /* get zerovm settings from manifest */ policy->version = GetValueByKey("Version"); policy->nexe_etag = GetValueByKey("NexeEtag"); /* check mandatory manifest keys */ ZLOGFAIL(nap->system_manifest->version == NULL, EFAULT, "the manifest version is not provided"); ZLOGFAIL(STRCMP(nap->system_manifest->version, MANIFEST_VERSION), EFAULT, "manifest version not supported"); SetTimeout(policy); /* user data (environment, command line) */ policy->envp = NULL; SetCustomAttributes(policy); /* prepare command line arguments for nexe */ policy->cmd_line = NULL; policy->cmd_line_size = 0; SetCommandLine(policy); /* get node name and id */ SetNodeName(nap); /* construct and initialize all channels */ ChannelsCtor(nap); /* * allocate "whole memory chunk" if specified. should be the last allocation * in raw because after chunk allocated there will be no free user memory * note: will set "heap_ptr" */ GET_INT_BY_KEY(nap->heap_end, "MemMax"); PreallocateUserMemory(nap); /* zerovm return code */ nap->system_manifest->ret_code = OK_CODE; }
/* helper. sets command line parameters for the user */ static void SetCommandLine(struct SystemManifest *policy) { int i; char *parameters; char *buf[BIG_ENOUGH_SPACE], **tokens = buf; assert(policy != NULL); assert(policy->cmd_line == NULL); assert(policy->cmd_line_size == 0); /* get parameters */ parameters = GetValueByKey(MFT_COMMANDLINE); /* if there is command line parse and check count of parameters */ if(parameters != NULL) { policy->cmd_line_size = ParseValue(parameters, " \t", tokens, BIG_ENOUGH_SPACE); ZLOGFAIL(policy->cmd_line_size == 0, EFAULT, "invalid user parameters"); ZLOGFAIL(policy->cmd_line_size == BIG_ENOUGH_SPACE, EFAULT, "too long user command line"); } /* * allocate space to hold string pointers. 0st element reserved for argv[0]. * also, the last element should be NULL so 1 extra element must be reserved */ ++policy->cmd_line_size; policy->cmd_line = g_malloc0((policy->cmd_line_size + 1) * sizeof *policy->cmd_line); /* populate command line arguments array with pointers */ for(i = 0; i < policy->cmd_line_size - 1; ++i) policy->cmd_line[i + 1] = tokens[i]; }
/* sets node_id in nap object and user argv[0] */ static void SetNodeName(struct NaClApp *nap) { int i; char *buf[BIG_ENOUGH_SPACE], **tokens = buf; char *pgm_name = GetValueByKey(MFT_NODE); assert(nap != NULL); assert(nap->system_manifest != NULL); assert(nap->system_manifest->cmd_line != NULL); assert(nap->system_manifest->cmd_line_size > 0); /* set the node name (0st parameter) and node id (n/a for the user) */ if(pgm_name == NULL) { nap->system_manifest->cmd_line[0] = NEXE_PGM_NAME; nap->system_manifest->node_id = 0; } else { i = ParseValue(pgm_name, ",", tokens, BIG_ENOUGH_SPACE); ZLOGFAIL(i != 2, EFAULT, "invalid NodeName specified"); ZLOGFAIL(tokens[0] == NULL, EFAULT, "invalid node name"); ZLOGFAIL(tokens[1] == NULL, EFAULT, "invalid node id"); nap->system_manifest->cmd_line[0] = tokens[0]; nap->system_manifest->node_id = ATOI(tokens[1]); ZLOGFAIL(nap->system_manifest->node_id == 0, EFAULT, "node id must be > 0"); } /* put node name and id to the log */ ZLOGS(LOG_DEBUG, "node name = %s, node id = %d", nap->system_manifest->cmd_line[0], nap->system_manifest->node_id); }
/* helper. sets custom user attributes for user */ static void SetCustomAttributes(struct SystemManifest *policy) { int i; int count; char *environment; char *buf[BIG_ENOUGH_SPACE], **tokens = buf; assert(policy != NULL); assert(policy->envp == NULL); /* get environment */ environment = GetValueByKey(MFT_ENVIRONMENT); if(environment == NULL) return; /* parse and check count of attributes */ count = ParseValue(environment, ", \t", tokens, BIG_ENOUGH_SPACE); ZLOGFAIL(count % 2 != 0, EFAULT, "odd number of user environment variables"); ZLOGFAIL(count == 0, EFAULT, "invalid user environment"); ZLOGFAIL(count == BIG_ENOUGH_SPACE, EFAULT, "user environment exceeded the limit"); /* allocate space to hold string pointers */ count >>= 1; policy->envp = g_malloc0((count + 1) * sizeof(*policy->envp)); /* construct array of environment variables */ for(i = 0; i < count; ++i) { char *key = *tokens++; char *value = *tokens++; int length = strlen(key) + strlen(value) + 1 + 1; /* + '=' + '\0' */ policy->envp[i] = g_malloc0((length + 1) * sizeof(*policy->envp[0])); sprintf(policy->envp[i], "%s=%s", key, value); } }
void Config::SetKeyValue( string setion, string key, string value ) { int index_begin = 0; int index_end = 0; if( 0 >= GetSetion( setion, index_begin, index_end ))//没找到setion,新增setion { m_content.insert( index_end, LINE_END ); int index_enter = m_content.find_last_not_of( LINE_END, index_end ); string append_string = LINE_END+R_SECTION+setion+L_SECTION + LINE_END + key + KEY_VALUE_GAP; m_content.insert( index_enter, append_string ); index_begin = index_end = index_begin + append_string.length(); } else if( 0 == GetValueByKey( key, index_begin, index_end ) )//没找到键值对,新增键值 { m_content.insert( index_end, key+KEY_VALUE_GAP ); index_begin = index_end = index_end+key.length()+KEY_VALUE_GAP.length(); } else { m_content.erase( index_begin, index_end-index_begin+1 );//包含第一个字符和最后一个字符,所以要加上1 } //修改值 m_content.insert( index_begin, value ); //保存配置 FileIO(m_file_name).SaveContent( m_content ); }
void Config::GetKeyValue( string setion, string key, string &value, string defaultValue ) { int index_begin = 0; int index_end = 0; if( GetSetion( setion, index_begin, index_end ) > 0 ) { if( GetValueByKey( key, index_begin, index_end ) > 0 ) { value = m_content.substr( index_begin, index_end - index_begin + 1 ); return ; } } value = defaultValue; }
/* * 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; }
/* * construct i/o channel and update SetupList with not mounted channel * if successful return 0, otherwise - 1 * note: SetupList object must be allocated */ int32_t ConstructChannel(struct NaClApp *nap, enum ChannelType ch) { /* allocate channel */ char prefix[1024]; struct PreOpenedFileDesc *channel = &nap->manifest->user_setup->channels[ch]; channel->self_size = sizeof(*channel); /* set self size */ GetChannelPrefixById(ch, prefix); // ### rewrite it! we must detect not set keywords and make default action (or set default value) #define SET_LIMIT(a, limit)\ do {\ char str[1024];\ char *p;\ if(!limit) break;\ sprintf(str, "%s%s", prefix, limit);\ p = GetValueByKey(nap, str);\ a = p ? atoll(p) : 0;\ } while (0); /* check if channel is set in manifest and set main attributes */ channel->name = (uint64_t)GetValueByKey(nap, prefix); if(!channel->name) return 1; SET_LIMIT(channel->mounted, "Mode"); channel->type = ch; /* set limits */ SET_LIMIT(channel->max_size, "Max"); SET_LIMIT(channel->max_get_size, "MaxGet"); SET_LIMIT(channel->max_gets, "MaxGetCnt"); SET_LIMIT(channel->max_put_size, "MaxPut"); SET_LIMIT(channel->max_puts, "MaxPutCnt"); /* set counters */ channel->cnt_get_size = 0; channel->cnt_gets = 0; channel->cnt_put_size = 0; channel->cnt_puts = 0; #undef SET_LIMIT return 0; }
/* parse given command line and initialize NaClApp object */ static void ParseCommandLine(struct NaClApp *nap, int argc, char **argv) { int opt; char *manifest_name = NULL; /* set defaults */ nap->skip_qualification = 0; nap->quit_after_load = 0; nap->handle_signals = 1; nap->storage_limit = ZEROVM_IO_LIMIT; /* construct zlog with default verbosity */ ZLogCtor(LOG_ERROR); /* todo(d'b): revise switches and rename them */ while((opt = getopt(argc, argv, "+FeQsSv:M:l:")) != -1) { switch(opt) { case 'M': manifest_name = optarg; break; case 's': nap->skip_validator = 1; ZLOG(LOG_ERROR, "validation disabled by -s"); break; case 'F': nap->quit_after_load = 1; break; case 'e': TagEngineCtor(); nap->user_tag = TagCtor(); break; case 'S': /* d'b: disable signals handling */ nap->handle_signals = 0; break; case 'l': /* calculate hard limit in Gb and don't allow it less then "big enough" */ nap->storage_limit = ATOI(optarg) * ZEROVM_IO_LIMIT_UNIT; ZLOGFAIL(nap->storage_limit < ZEROVM_IO_LIMIT_UNIT, EFAULT, "invalid storage limit: %d", nap->storage_limit); break; case 'v': ZLogDtor(); ZLogCtor(ATOI(optarg)); break; case 'Q': nap->skip_qualification = 1; ZLOGS(LOG_ERROR, "PLATFORM QUALIFICATION DISABLED BY -Q - " "Native Client's sandbox will be unreliable!"); break; default: ZLOGS(LOG_ERROR, "ERROR: unknown option: [%c]", opt); puts(HELP_SCREEN); exit(EINVAL); break; } } /* show zerovm command line */ ZVMCommandLine(argc, argv); /* parse manifest file specified in cmdline */ if(manifest_name == NULL) { puts(HELP_SCREEN); exit(EINVAL); } ZLOGFAIL(ManifestCtor(manifest_name), EFAULT, "Invalid manifest '%s'", manifest_name); /* set available nap and manifest fields */ assert(nap->system_manifest != NULL); nap->system_manifest->nexe = GetValueByKey("Nexe"); ZLOGFAIL(GetFileSize(nap->system_manifest->nexe) < 0, ENOENT, "nexe open error"); syscallback = 0; }