Пример #1
0
static boolean
check_register_usage(
   struct sanity_check_ctx *ctx,
   uint file,
   int index,
   const char *name,
   boolean indirect_access )
{
   if (!check_file_name( ctx, file ))
      return FALSE;

   if (indirect_access) {
      /* Note that 'index' is an offset relative to the value of the
       * address register.  No range checking done here.
       */
      if (!is_any_register_declared( ctx, file ))
         report_error( ctx, "%s: Undeclared %s register", file_names[file], name );
      ctx->regs_ind_used[file] = TRUE;
   }
   else {
      if (index < 0 || index >= MAX_REGISTERS) {
         report_error( ctx, "%s[%d]: Invalid %s index", file_names[file], index, name );
         return FALSE;
      }

      if (!is_register_declared( ctx, file, index ))
         report_error( ctx, "%s[%d]: Undeclared %s register", file_names[file], index, name );
      ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG));
   }
   return TRUE;
}
Пример #2
0
static boolean
iter_declaration(
   struct tgsi_iterate_context *iter,
   struct tgsi_full_declaration *decl )
{
   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
   uint file;
   uint i;

   /* No declarations allowed after the first instruction.
    */
   if (ctx->num_instructions > 0)
      report_error( ctx, "Instruction expected but declaration found" );

   /* Check registers' validity.
    * Mark the registers as declared.
    */
   file = decl->Declaration.File;
   if (!check_file_name( ctx, file ))
      return TRUE;
   for (i = decl->DeclarationRange.First; i <= decl->DeclarationRange.Last; i++) {
      if (is_register_declared( ctx, file, i ))
         report_error( ctx, "%s[%u]: The same register declared more than once", file_names[file], i );
      ctx->regs_decl[file][i / BITS_IN_REG_FLAG] |= (1 << (i % BITS_IN_REG_FLAG));
   }

   return TRUE;
}
Пример #3
0
static boolean
iter_declaration(
   struct tgsi_iterate_context *iter,
   struct tgsi_full_declaration *decl )
{
   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
   uint file;
   uint i;

   /* No declarations allowed after the first instruction.
    */
   if (ctx->num_instructions > 0)
      report_error( ctx, "Instruction expected but declaration found" );

   /* Check registers' validity.
    * Mark the registers as declared.
    */
   file = decl->Declaration.File;
   if (!check_file_name( ctx, file ))
      return TRUE;
   for (i = decl->Range.First; i <= decl->Range.Last; i++) {
      /* declared TGSI_FILE_INPUT's for geometry and tessellation
       * have an implied second dimension */
      uint processor = ctx->iter.processor.Processor;
      uint patch = decl->Semantic.Name == TGSI_SEMANTIC_PATCH ||
         decl->Semantic.Name == TGSI_SEMANTIC_TESSOUTER ||
         decl->Semantic.Name == TGSI_SEMANTIC_TESSINNER;
      if (file == TGSI_FILE_INPUT && !patch && (
                processor == TGSI_PROCESSOR_GEOMETRY ||
                processor == TGSI_PROCESSOR_TESS_CTRL ||
                processor == TGSI_PROCESSOR_TESS_EVAL)) {
         uint vert;
         for (vert = 0; vert < ctx->implied_array_size; ++vert) {
            scan_register *reg = MALLOC(sizeof(scan_register));
            fill_scan_register2d(reg, file, i, vert);
            check_and_declare(ctx, reg);
         }
      } else if (file == TGSI_FILE_OUTPUT && !patch &&
                 processor == TGSI_PROCESSOR_TESS_CTRL) {
         uint vert;
         for (vert = 0; vert < ctx->implied_out_array_size; ++vert) {
            scan_register *reg = MALLOC(sizeof(scan_register));
            fill_scan_register2d(reg, file, i, vert);
            check_and_declare(ctx, reg);
         }
      } else {
         scan_register *reg = MALLOC(sizeof(scan_register));
         if (decl->Declaration.Dimension) {
            fill_scan_register2d(reg, file, i, decl->Dim.Index2D);
         } else {
            fill_scan_register1d(reg, file, i);
         }
         check_and_declare(ctx, reg);
      }
   }

   return TRUE;
}
Пример #4
0
static boolean
check_register_usage(
   struct sanity_check_ctx *ctx,
   scan_register *reg,
   const char *name,
   boolean indirect_access )
{
   if (!check_file_name( ctx, reg->file )) {
      FREE(reg);
      return FALSE;
   }

   if (indirect_access) {
      /* Note that 'index' is an offset relative to the value of the
       * address register.  No range checking done here.*/
      reg->indices[0] = 0;
      reg->indices[1] = 0;
      if (!is_any_register_declared( ctx, reg->file ))
         report_error( ctx, "%s: Undeclared %s register", file_names[reg->file], name );
      if (!is_ind_register_used(ctx, reg))
         cso_hash_insert(ctx->regs_ind_used, reg->file, reg);
      else
         FREE(reg);
   }
   else {
      if (!is_register_declared( ctx, reg )) {
         if (reg->dimensions == 2) {
            report_error( ctx, "%s[%d][%d]: Undeclared %s register", file_names[reg->file],
                          reg->indices[0], reg->indices[1], name );
         }
         else {
            report_error( ctx, "%s[%d]: Undeclared %s register", file_names[reg->file],
                          reg->indices[0], name );
         }
      }
      if (!is_register_used( ctx, reg ))
         cso_hash_insert(ctx->regs_used, scan_register_key(reg), reg);
      else
         FREE(reg);
   }
   return TRUE;
}
int report_data(void)
{
	char filename[91];
	FILE *fid;

	printf("Enter the file name for reporting statistics: ");
	gets(filename);
	printf("\n");

	int error = check_file_name(filename);
	if (!error)
	{
		fid = fopen(filename, "r");
		if (!fid)
		{
			// error in opening file
			printf(
					"Error in opening file %s: Check to make sure filename is correct and file exists.\n",
					filename);
			return FILE_ERROR; // a return here means we don't need an else clause
		}

		// Getting the data from the file.
		FileHeaderPtr fh_p = (FileHeaderPtr) malloc(sizeof(FileHeader));
		get_file_header(fh_p, fid);

		char buffer[256];
		printf("%s", to_string_file_header(fh_p, buffer));

		fclose(fid);

		printf("\nReporting Statistics for %s", filename);
		printf("\nThe mean is: %f", fh_p->mean);
		printf("\nThe median is: %f", fh_p->median);
		printf("\nThe variance is: %f", fh_p->variance);
		printf("\nThe standard deviation is: %f\n", fh_p->std_dev);
		printf("Reporting Statistics complete. Closing %s\n", filename);
		free(fh_p);
	}

	return error;
}
Пример #6
0
list<stack_line_info> get_stack_list(size_t maxDepth, size_t offset, bool module, bool symbolName)
{
	assert(maxDepth <= 32);

	QWORD trace[33];
	CONTEXT context;

	::ZeroMemory(&context, sizeof(context));
	context.ContextFlags = CONTEXT_FULL;
#ifdef _WIN64
	get_bp_sp_ip((void**)&context.Rbp, (void**)&context.Rsp, (void**)&context.Rip);
#else
	get_bp_sp_ip((void**)&context.Ebp, (void**)&context.Esp, (void**)&context.Eip);
#endif
	size_t depths = _stackwalk(trace, maxDepth+1, &context);

	list<stack_line_info> imageList;
	HANDLE hProcess = ::GetCurrentProcess();
	for (size_t i = 1 + offset; i < depths; i++)
	{
		stack_line_info stackResult;

		{
			DWORD symbolDisplacement = 0;
			IMAGEHLP_LINE64 imageHelpLine;
			imageHelpLine.SizeOfStruct = sizeof(imageHelpLine);

			if (::SymGetLineFromAddr64(hProcess, trace[i], &symbolDisplacement, &imageHelpLine))
			{
				stackResult.file = string(imageHelpLine.FileName, check_file_name(imageHelpLine.FileName));
				memset(imageHelpLine.FileName, 0, stackResult.file.size() + 1);
				stackResult.line = (int)imageHelpLine.LineNumber;
			}
			else
			{
				stackResult.line = -1;
			}
		}
		if (symbolName)
		{
			static const int maxNameLength = 1024;
			char symbolBf[sizeof(IMAGEHLP_SYMBOL64)+maxNameLength] = { 0 };
			PIMAGEHLP_SYMBOL64 symbol;
			DWORD64 symbolDisplacement64 = 0;

			symbol = (PIMAGEHLP_SYMBOL64)symbolBf;
			symbol->SizeOfStruct = sizeof(symbolBf);
			symbol->MaxNameLength = maxNameLength;

			if (::SymGetSymFromAddr64(
				hProcess,
				trace[i],
				&symbolDisplacement64,
				symbol)
				)
			{
				stackResult.symbolName = symbol->Name;
			}
			else
			{
				stackResult.symbolName = "unknow...";
			}
		}
		if (module)
		{
			IMAGEHLP_MODULE64 imageHelpModule;
			imageHelpModule.SizeOfStruct = sizeof(imageHelpModule);

			if (::SymGetModuleInfo64(hProcess, trace[i], &imageHelpModule))
			{
				stackResult.module = string(imageHelpModule.ImageName, check_file_name(imageHelpModule.ImageName));
				memset(imageHelpModule.ImageName, 0, stackResult.module.size() + 1);
			}
		}
		imageList.push_back(std::move(stackResult));
	}
	return std::move(imageList);
}
Пример #7
0
static std::list<stack_info> get_stack_list(
  void* bp, void* sp, void* ip,
  size_t max_depth, size_t offset, bool module, bool symbol, bool brief
)
{
  QWORD trace[33];
  CONTEXT context;

  ZeroMemory(&context, sizeof(context));
  context.ContextFlags = CONTEXT_FULL;
#ifdef _WIN64
  context.Rbp = (DWORD64)bp;
  context.Rsp = (DWORD64)sp;
  context.Rip = (DWORD64)ip;
#else
  context.Ebp = (DWORD)bp;
  context.Esp = (DWORD)sp;
  context.Eip = (DWORD)ip;
#endif
  size_t depths = stack_walk(trace, max_depth, &context);

  std::list<stack_info> image_list;
  HANDLE hProcess = GetCurrentProcess();
  for (size_t i = offset; i < depths; i++)
  {
    stack_info stack_result(brief);

    {
      DWORD symbolDisplacement = 0;
      IMAGEHLP_LINE64 imageHelpLine;
      imageHelpLine.SizeOfStruct = sizeof(imageHelpLine);

      if (SymGetLineFromAddr64(hProcess, trace[i], &symbolDisplacement, &imageHelpLine))
      {
        stack_result.file_ = std::string(imageHelpLine.FileName, check_file_name(imageHelpLine.FileName));
        std::memset(imageHelpLine.FileName, 0, stack_result.file_.size() + 1);
        stack_result.line_ = (int)imageHelpLine.LineNumber;
      }
      else
      {
        stack_result.line_ = -1;
      }
    }
    if (symbol)
    {
      static const int max_name_length = 1024;
      char symbolBf[sizeof(IMAGEHLP_SYMBOL64) + max_name_length] = { 0 };
      PIMAGEHLP_SYMBOL64 symbol;
      DWORD64 symbolDisplacement64 = 0;

      symbol = (PIMAGEHLP_SYMBOL64)symbolBf;
      symbol->SizeOfStruct = sizeof(symbolBf);
      symbol->MaxNameLength = max_name_length;

      if (SymGetSymFromAddr64(
        hProcess,
        trace[i],
        &symbolDisplacement64,
        symbol)
        )
      {
        stack_result.symbol_ = symbol->Name;
      }
      else
      {
        stack_result.symbol_ = "unknow...";
      }
    }
    if (module)
    {
      IMAGEHLP_MODULE64 imageHelpModule;
      imageHelpModule.SizeOfStruct = sizeof(imageHelpModule);

      if (SymGetModuleInfo64(hProcess, trace[i], &imageHelpModule))
      {
        stack_result.module_ = std::string(imageHelpModule.ImageName, check_file_name(imageHelpModule.ImageName));
        std::memset(imageHelpModule.ImageName, 0, stack_result.module_.size() + 1);
      }
    }
    image_list.push_back(std::move(stack_result));
  }
  return image_list;
}
Пример #8
0
static PLI_INT32 sys_readmem_calltf(PLI_BYTE8*name)
{
    int code;
    int wwid;
    char*path;
    char*mem_name;
    FILE*file;
    unsigned addr;
    s_vpi_value value;
    vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
    vpiHandle argv = vpi_iterate(vpiArgument, sys);
    vpiHandle item = vpi_scan(argv);
    vpiHandle mitem;
    vpiHandle start_item;
    vpiHandle stop_item;
    vpiHandle left_range;
    vpiHandle right_range;
    vpiHandle word_index;

    /* These are left and right hand side parameters in the
    declaration of the memory. */
    int left_addr, right_addr;

    /* start_addr and stop_addr are the parameters given to $readmem in the
    Verilog code. When not specified, start_addr is equal to the lower of
     the [left,right]_addr and stop_addr is equal to the higher of the
     [left,right]_addr. */
    int start_addr, stop_addr, addr_incr;

    /* min_addr and max_addr are equal to start_addr and stop_addr if
    start_addr<stop_addr or vice versa if not... */
    unsigned min_addr, max_addr;

    /* This is the number of words that we need from the memory. */
    unsigned word_count;


    /*======================================== Get parameters */

    if (item == 0) {
        vpi_printf("%s: file name parameter missing.\n", name);
        return 0;
    }

    /* Check then get the first argument, the file name. It is
       possible that Verilog would right-justify a name to fit a
       reg value to fit the reg width, so chop off leading white
       space in the process. */
    if (check_file_name(name, item) == 0) {
        vpi_free_object(argv);
        return 0;
    }

    value.format = vpiStringVal;
    vpi_get_value(item, &value);
    path = strdup(value.value.str + strspn(value.value.str, " "));

    /* Get and check the second parameter. It must be a memory. */
    mitem = vpi_scan(argv);
    if (mitem == 0) {
        vpi_printf("%s: Missing memory parameter\n", name);
        free(path);
        return 0;
    }

    if (vpi_get(vpiType, mitem) != vpiMemory) {
        vpi_printf("%s: Second parameter must be a memory.\n", name);
        free(path);
        vpi_free_object(argv);
        return 0;
    }

    mem_name = vpi_get_str(vpiFullName, mitem);

    /* Get optional third parameter. It must be a constant. */
    start_item = vpi_scan(argv);
    if (start_item!=0) {
        if (check_integer_constant(name, start_item) == 0) {
            vpi_free_object(argv);
            return 0;
        }

        /* Get optional forth parameter. It must be a constant. */
        stop_item = vpi_scan(argv);
        if (stop_item!=0) {
            if (check_integer_constant(name, stop_item) == 0) {
                vpi_free_object(argv);
                return 0;
            }

            /* Check that there is no 5th parameter */
            if (vpi_scan(argv) != 0) {
                vpi_printf("ERROR: %s accepts maximum 4 parameters!\n", name );
                vpi_free_object(argv);
                return 0;
            }

        }
    }
    else {
        stop_item = 0;
    }

    /*======================================== Process parameters */

    /* Open the data file. */
    file = fopen(path, "r");
    if (file == 0) {
        vpi_printf("%s: Unable to open %s for reading.\n", name, path);
        free(path);
        return 0;
    }

    /* Get left addr of memory */
    left_range = vpi_handle(vpiLeftRange, mitem);
    value.format = vpiIntVal;
    vpi_get_value(left_range, &value);
    left_addr = value.value.integer;

    /* Get right addr of memory */
    right_range = vpi_handle(vpiRightRange, mitem);
    value.format = vpiIntVal;
    vpi_get_value(right_range, &value);
    right_addr = value.value.integer;

    /* Get start_addr, stop_addr and addr_incr */
    if (start_item==0) {
        start_addr = left_addr<right_addr ? left_addr  : right_addr;
        stop_addr  = left_addr<right_addr ? right_addr : left_addr;
        addr_incr = 1;
    }
    else {
        s_vpi_value value2;
        value2.format = vpiIntVal;
        vpi_get_value(start_item, &value2);
        start_addr = value2.value.integer;

        if (stop_item==0) {
            stop_addr = left_addr<right_addr ? right_addr : left_addr;
            addr_incr = 1;
        }
        else {
            s_vpi_value value3;
            value3.format = vpiIntVal;
            vpi_get_value(stop_item, &value3);
            stop_addr = value3.value.integer;

            addr_incr = start_addr<stop_addr ? 1 : -1;
        }
    }

    min_addr = start_addr<stop_addr ? start_addr : stop_addr ;
    max_addr = start_addr<stop_addr ? stop_addr  : start_addr;

    /* We need this many words from the file. */
    word_count = max_addr-min_addr+1;

    /* Check that start_addr and stop_addr are within the memory
    range */
    if (left_addr<right_addr) {
        if (start_addr<left_addr || start_addr > right_addr) {
            vpi_printf("%s: Start address is out of bounds for memory \'%s\'!\n", name, mem_name);
            return 0;
        }

        if (stop_addr<left_addr || stop_addr > right_addr) {
            vpi_printf("%s: Stop address is out of bounds for memory \'%s\'!\n", name, mem_name);
            return 0;
        }
    }
    else {
        if (start_addr<right_addr || start_addr > left_addr) {
            vpi_printf("%s: Start address is out of bounds for memory \'%s\'!\n", name, mem_name);
            return 0;
        }

        if (stop_addr<right_addr || stop_addr > left_addr) {
            vpi_printf("%s: Stop address is out of bounds for memory \'%s\'!\n", name, mem_name);
            return 0;
        }
    }

    item = vpi_handle_by_index(mitem,min_addr);
    wwid = vpi_get(vpiSize, item);

    /* variable that will be uses by the lexer to pass values
    back to this code */
    value.format = vpiVectorVal;
    value.value.vector = calloc((wwid+31)/32, sizeof(s_vpi_vecval));

    /* Configure the readmem lexer */
    if (strcmp(name,"$readmemb") == 0)
        sys_readmem_start_file(file, 1, wwid, value.value.vector);
    else
        sys_readmem_start_file(file, 0, wwid, value.value.vector);


    /*======================================== Read memory file */

    /* Run through the input file and store the new contents in the memory */
    addr = start_addr;
    while ((code = readmemlex()) != 0) {
        switch (code) {
        case MEM_ADDRESS:
            addr = value.value.vector->aval;
            /* if there is an address in the memory file, then
               turn off any possible warnings about not having
               enough words to load the memory. This is standard
               behavior. */
            word_count = 0;
            break;

        case MEM_WORD:
            if (addr >= min_addr && addr <= max_addr) {
                word_index = vpi_handle_by_index(mitem, addr);
                assert(word_index);
                vpi_put_value(word_index, &value, 0, vpiNoDelay);

                if (word_count > 0)
                    word_count -= 1;
            }
            else {
                vpi_printf("%s(%s): address (0x%x) out of range (0x%x:0x%x)\n",
                           name, path, addr, start_addr, stop_addr);
                goto bailout;
            }

            addr += addr_incr;
            break;

        default:
            vpi_printf("Huh?! (%d)\n", code);
            break;
        }
    }

    if (word_count > 0)
        vpi_printf("%s(%s): Not enough words in the read file "
                   "for requested range.\n", name, path);

bailout:
    free(value.value.vector);
    free(path);
    fclose(file);
    return 0;
}
Пример #9
0
// check profile line; if line == 0, this was generated from a command line option
// return 1 if the command is to be added to the linked list of profile commands
// return 0 if the command was already executed inside the function
int profile_check_line(char *ptr, int lineno) {
	// seccomp, caps, private, user namespace
	if (strcmp(ptr, "noroot") == 0) {
		check_user_namespace();
		return 0;
	}
	else if (strcmp(ptr, "seccomp") == 0) {
		arg_seccomp = 1;
		return 0;
	}
	else if (strcmp(ptr, "caps") == 0) {
		arg_caps_default_filter = 1;
		return 0;
	}
	else if (strcmp(ptr, "caps.drop all") == 0) {
		arg_caps_drop_all = 1;
		return 0;
	}
	else if (strcmp(ptr, "shell none") == 0) {
		arg_shell_none = 1;
		return 0;
	}	
	else if (strcmp(ptr, "private") == 0) {
		arg_private = 1;
		return 0;
	}
	else if (strcmp(ptr, "private-dev") == 0) {
		arg_private_dev = 1;
		return 0;
	}
	else if (strcmp(ptr, "nogroups") == 0) {
		arg_nogroups = 1;
		return 0;
	}
	else if (strcmp(ptr, "netfilter") == 0) {
		arg_netfilter = 1;
		return 0;
	}
	else if (strncmp(ptr, "netfilter ", 10) == 0) {
		arg_netfilter = 1;
		arg_netfilter_file = strdup(ptr + 10);
		if (!arg_netfilter_file)
			errExit("strdup");
		check_netfilter_file(arg_netfilter_file);
		return 0;
	}
	
	// seccomp drop list on top of default list
	if (strncmp(ptr, "seccomp ", 8) == 0) {
		arg_seccomp = 1;
#ifdef HAVE_SECCOMP
		arg_seccomp_list = strdup(ptr + 8);
		if (!arg_seccomp_list)
			errExit("strdup");
#endif
		return 0;
	}
	
	// seccomp drop list without default list
	if (strncmp(ptr, "seccomp.drop ", 13) == 0) {
		arg_seccomp = 1;
#ifdef HAVE_SECCOMP
		arg_seccomp_list_drop = strdup(ptr + 13);
		if (!arg_seccomp_list_drop)
			errExit("strdup");
#endif
		return 0;
	}

	// seccomp keep list
	if (strncmp(ptr, "seccomp.keep ", 13) == 0) {
		arg_seccomp = 1;
#ifdef HAVE_SECCOMP
		arg_seccomp_list_keep= strdup(ptr + 13);
		if (!arg_seccomp_list_keep)
			errExit("strdup");
#endif
		return 0;
	}
	
	// caps drop list
	if (strncmp(ptr, "caps.drop ", 10) == 0) {
		arg_caps_drop = 1;
		arg_caps_list = strdup(ptr + 10);
		if (!arg_caps_list)
			errExit("strdup");
		// verify seccomp list and exit if problems
		if (caps_check_list(arg_caps_list, NULL))
			exit(1);
		return 0;
	}
	
	// caps keep list
	if (strncmp(ptr, "caps.keep ", 10) == 0) {
		arg_caps_keep = 1;
		arg_caps_list = strdup(ptr + 10);
		if (!arg_caps_list)
			errExit("strdup");
		// verify seccomp list and exit if problems
		if (caps_check_list(arg_caps_list, NULL))
			exit(1);
		return 0;
	}
	
	// dns
	if (strncmp(ptr, "dns ", 4) == 0) {
		uint32_t dns;
		if (atoip(ptr + 4, &dns)) {
			fprintf(stderr, "Error: invalid DNS server IP address\n");
			return 1;
		}
		
		if (cfg.dns1 == 0)
			cfg.dns1 = dns;
		else if (cfg.dns2 == 0)
			cfg.dns2 = dns;
		else if (cfg.dns3 == 0)
			cfg.dns3 = dns;
		else {
			fprintf(stderr, "Error: up to 3 DNS servers can be specified\n");
			return 1;
		}
		return 0;
	}
	
	// cpu affinity
	if (strncmp(ptr, "cpu ", 4) == 0) {
		read_cpu_list(ptr + 4);
		return 0;
	}
	
	// cgroup
	if (strncmp(ptr, "cgroup ", 7) == 0) {
		set_cgroup(ptr + 7);
		return 0;
	}
	
	// private directory
	if (strncmp(ptr, "private ", 8) == 0) {
		cfg.home_private = ptr + 8;
		fs_check_private_dir();
		arg_private = 1;
		return 0;
	}

	// private list of files and directories
	if (strncmp(ptr, "private.keep ", 13) == 0) {
		cfg.home_private_keep = ptr + 13;
		fs_check_home_list();
		arg_private = 1;
		return 0;
	}

	// filesystem bind
	if (strncmp(ptr, "bind ", 5) == 0) {
		if (getuid() != 0) {
			fprintf(stderr, "Error: --bind option is available only if running as root\n");
			exit(1);
		}

		// extract two directories
		char *dname1 = ptr + 5;
		char *dname2 = split_comma(dname1); // this inserts a '0 to separate the two dierctories
		if (dname2 == NULL) {
			fprintf(stderr, "Error: mising second directory for bind\n");
			exit(1);
		}
		
		// check directories
		check_file_name(dname1, lineno);
		check_file_name(dname2, lineno);
		if (strstr(dname1, "..") || strstr(dname2, "..")) {
			fprintf(stderr, "Error: invalid file name.\n");
			exit(1);
		}
		
		// insert comma back
		*(dname2 - 1) = ',';
		return 1;
	}

	// rlimit
	if (strncmp(ptr, "rlimit", 6) == 0) {
		if (strncmp(ptr, "rlimit-nofile ", 14) == 0) {
			ptr += 14;
			if (not_unsigned(ptr)) {
				fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
				exit(1);
			}
			sscanf(ptr, "%u", &cfg.rlimit_nofile);
			arg_rlimit_nofile = 1;
		}
		else if (strncmp(ptr, "rlimit-nproc ", 13) == 0) {
			ptr += 13;
			if (not_unsigned(ptr)) {
				fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
				exit(1);
			}
			sscanf(ptr, "%u", &cfg.rlimit_nproc);
			arg_rlimit_nproc = 1;
		}
		else if (strncmp(ptr, "rlimit-fsize ", 13) == 0) {
			ptr += 13;
			if (not_unsigned(ptr)) {
				fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
				exit(1);
			}
			sscanf(ptr, "%u", &cfg.rlimit_fsize);
			arg_rlimit_fsize = 1;
		}
		else if (strncmp(ptr, "rlimit-sigpending ", 18) == 0) {
			ptr += 18;
			if (not_unsigned(ptr)) {
				fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
				exit(1);
			}
			sscanf(ptr, "%u", &cfg.rlimit_sigpending);
			arg_rlimit_sigpending = 1;
		}
		else {
			fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
			exit(1);
		}
		
		return 0;		
	}

	// rest of filesystem
	if (strncmp(ptr, "blacklist ", 10) == 0)
		ptr += 10;
	else if (strncmp(ptr, "read-only ", 10) == 0)
		ptr += 10;
	else if (strncmp(ptr, "tmpfs ", 6) == 0)
		ptr += 6;
	else {
		if (lineno == 0)
			fprintf(stderr, "Error: \"%s\" as a command line option is invalid\n", ptr);
		else
			fprintf(stderr, "Error: line %d in the custom profile is invalid\n", lineno);
		exit(1);
	}

	// some characters just don't belong in filenames
	check_file_name(ptr, lineno);
	if (strstr(ptr, "..")) {
		if (lineno == 0)
			fprintf(stderr, "Error: \"%s\" is an invalid filename\n", ptr);
		else
			fprintf(stderr, "Error: line %d in the custom profile is invalid\n", lineno);
		exit(1);
	}
	return 1;
}
Пример #10
0
// check profile line; if line == 0, this was generated from a command line option
// return 1 if the command is to be added to the linked list of profile commands
// return 0 if the command was already executed inside the function
int profile_check_line(char *ptr, int lineno) {
	// seccomp, caps, private
	if (strcmp(ptr, "seccomp") == 0) {
		arg_seccomp = 1;
		return 0;
	}
	else if (strcmp(ptr, "caps") == 0) {
		arg_caps = 1;
		return 0;
	}
	else if (strcmp(ptr, "private") == 0) {
		arg_private = 1;
		return 0;
	}
	
	// seccomp list
	if (strncmp(ptr, "seccomp ", 8) == 0) {
		arg_seccomp = 1;
#ifdef HAVE_SECCOMP
		arg_seccomp_list = strdup(ptr + 8);
		if (!arg_seccomp_list)
			errExit("strdup");
		// verify seccomp list and exit if problems
		if (syscall_check_list(arg_seccomp_list, NULL))
			exit(1);
#endif
		return 0;
	}
	
	// private directory
	if (strncmp(ptr, "private ", 8) == 0) {
		cfg.home_private = ptr + 8;
		check_private_dir();
		arg_private = 1;
		return 0;
	}

	// filesystem bind
	if (strncmp(ptr, "bind ", 5) == 0) {
		if (getuid() != 0) {
			fprintf(stderr, "Error: --bind option is available only if running as root\n");
			exit(1);
		}

		// extract two directories
		char *dname1 = ptr + 5;
		char *dname2 = split_comma(dname1); // this inserts a '0 to separate the two dierctories
		if (dname2 == NULL) {
			fprintf(stderr, "Error: mising second directory for bind\n");
			exit(1);
		}
		
		// check directories
		check_file_name(dname1, lineno);
		check_file_name(dname2, lineno);
		
		// insert comma back
		*(dname2 - 1) = ',';
		return 1;
	}

	// rlimit
	if (strncmp(ptr, "rlimit", 6) == 0) {
		if (strncmp(ptr, "rlimit-nofile ", 14) == 0) {
			ptr += 14;
			if (not_unsigned(ptr)) {
				fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
				exit(1);
			}
			sscanf(ptr, "%u", &cfg.rlimit_nofile);
			arg_rlimit_nofile = 1;
		}
		else if (strncmp(ptr, "rlimit-nproc ", 13) == 0) {
			ptr += 13;
			if (not_unsigned(ptr)) {
				fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
				exit(1);
			}
			sscanf(ptr, "%u", &cfg.rlimit_nproc);
			arg_rlimit_nproc = 1;
		}
		else if (strncmp(ptr, "rlimit-fsize ", 13) == 0) {
			ptr += 13;
			if (not_unsigned(ptr)) {
				fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
				exit(1);
			}
			sscanf(ptr, "%u", &cfg.rlimit_fsize);
			arg_rlimit_fsize = 1;
		}
		else if (strncmp(ptr, "rlimit-sigpending ", 18) == 0) {
			ptr += 18;
			if (not_unsigned(ptr)) {
				fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
				exit(1);
			}
			sscanf(ptr, "%u", &cfg.rlimit_sigpending);
			arg_rlimit_sigpending = 1;
		}
		else {
			fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
			exit(1);
		}
		
		return 0;		
	}

	// rest of filesystem
	if (strncmp(ptr, "blacklist ", 10) == 0)
		ptr += 10;
	else if (strncmp(ptr, "read-only ", 10) == 0)
		ptr += 10;
	else if (strncmp(ptr, "tmpfs ", 6) == 0)
		ptr += 6;
	else {
		if (lineno == 0)
			fprintf(stderr, "Error: \"%s\" as a command line option is invalid\n", ptr);
		else
			fprintf(stderr, "Error: line %d in the custom profile is invalid\n", lineno);
		exit(1);
	}

	// some characters just don't belong in filenames
	check_file_name(ptr, lineno);
	return 1;
}