示例#1
0
void uv_inject(page_desc_t      *pd,
		page_desc_t      *pdbegin,
		page_desc_t      *pdend,
		unsigned long    pages,
		unsigned long    addr,
		unsigned long    addrend,
		unsigned int     pagesize,
		unsigned long    mattr,
		unsigned long    nodeid,
		unsigned long    paddr,
		char             *pte_str,
		unsigned long    nodeid_start,
		unsigned long    mattr_start,
		unsigned long    addr_start,
		int              mce_opt)
{
        int count = 0;
	eid.cpu = sched_getcpu();

        for (pd=pdbegin, pdend=pd+pages; pd<pdend && addr < addrend; pd++, addr += pagesize) {
		if (pd->flags & PD_HOLE) {
			pagesize = pd->pte;
			mattr = 0;
			nodeid = -1;
		} else {
			nodeid = get_pnodeid(*pd);
			paddr = get_paddr(*pd);
			if (nodeid == INVALID_NODE)
				nodeid = 0;

			mattr = get_memory_attr(*pd);
			pagesize = get_pagesize(*pd);
			if (mattr && paddr) {
				if ((pd_total / 2) == count){
				sprintf(pte_str, "  0x%016lx  ", pd->pte);
				printf("\t[%012lx] -> 0x%012lx on %s %3s  %s%s\n",
						addr, paddr, idstr(), nodestr(nodeid),
						pte_str, get_memory_attr_str(nodeid, mattr));
				/* Setting value at memory location  for recovery
 				 * before injecting.
 				 */
        			memset((void *)addr, 'A', pagesize);
				injecteddata = (char *)addr;
				printf("Data:%x\n",*injecteddata);
				eid.addr = paddr;
				eid.cpu = nodeid;
				break;//only allow once for now
				}
			}
		}
		count++;
	} 
	if (delay){
		printf("Enter char to inject..");
		getchar();
	}	
	if(!manual){
		inject_uc(eid.addr, 0 /*int notrigger*/);
	}
}
示例#2
0
void* rwxalloc(size_t bytes){
	if (!bytes) return 0;
	static const size_t pagesize = get_pagesize();
	size_t numpages = (bytes+pagesize-1)/pagesize;

	void* block = VirtualAlloc(NULL, numpages*pagesize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	return block;
}
示例#3
0
/* Params are passed directly, offset is in pages */
int
sys_mmap_pgoff(struct tcb *tcp)
{
	/* Try test/mmap_offset_decode.c */
	unsigned long long offset;
	offset = (unsigned long) tcp->u_arg[5];
	offset *= get_pagesize();
	return print_mmap(tcp, tcp->u_arg, offset);
}
示例#4
0
int
cm_get_proc_stat (T_CM_PROC_STAT * stat, int pid)
{
  long vmem_pages;
  long rmem_pages;
  char fname[PATH_MAX];
  FILE *cpufp, *memfp;

  if (stat == NULL || pid == 0)
    {
      return 0;
    }

  stat->pid = pid;

  snprintf (fname, PATH_MAX - 1, "/proc/%d/stat", (int) pid);
  cpufp = fopen (fname, "r");
  if (!cpufp)
    {
      return 0;
    }

  snprintf (fname, PATH_MAX - 1, "/proc/%d/statm", (int) pid);
  memfp = fopen (fname, "r");
  if (memfp == NULL)
    {
      fclose (cpufp);
      return 0;
    }

  fscanf (cpufp, "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%llu%llu",
	  &stat->cpu_user, &stat->cpu_kernel);
  fscanf (memfp, "%lu%lu", &vmem_pages, &rmem_pages);	/* 'size' and 'resident' in stat file */
  stat->mem_virtual = vmem_pages * get_pagesize ();
  stat->mem_physical = rmem_pages * get_pagesize ();

  fclose (cpufp);
  fclose (memfp);

  return 1;
}
示例#5
0
/* Params are pointed to by u_arg[0], offset is in pages */
int
sys_old_mmap_pgoff(struct tcb *tcp)
{
	long u_arg[5];
	int i;
	unsigned narrow_arg[6];
	unsigned long long offset;
	if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), (char *) narrow_arg) == -1)
		return 0;
	for (i = 0; i < 5; i++)
		u_arg[i] = (unsigned long) narrow_arg[i];
	offset = narrow_arg[5];
	offset *= get_pagesize();
	return print_mmap(tcp, u_arg, offset);
}
示例#6
0
int main(int argc, char **argv)
{
	vps_param *param, *gparam;
	struct stat st;
	char *infile = NULL;
	int opt, recover = 0, ask = 0;
	int ret = 1;
	int vswap = -1;

	init_log(NULL, 0, 1, 0, 0, progname);

	while ((opt = getopt(argc, argv, "rihv:")) > 0) {
		switch(opt) {
		case 'r'	:
			recover = 1;
			break;
		case 'i'	:
			ask = 1;
			break;
		case 'h'	:
			usage(0);
		case 'v':
			switch (yesno2id(optarg)) {
				case YES:
					vswap = 1;
					break;
				case NO:
					vswap = 0;
					break;
				default:
					logger(-1, 0, "Invalid argument "
							"for -v: %s", optarg);
					usage(1);
			}
			break;
		default	:
			usage(1);
		}
	}
	if (optind >= argc)
		usage(1);

	if ((page_size = get_pagesize()) < 0)
		return 1;

	/* Read global config */
	gparam = init_vps_param();
	if (vps_parse_config(0, GLOBAL_CFG, gparam, NULL)) {
		logger(-1, 0, "WARNING: Global configuration file %s "
			"not found", GLOBAL_CFG);
	}

	/* Read container config */
	infile = strdup(argv[optind]);
	if (!infile) {
		logger(-1, 0, "No free memory");
		goto err;
	}
	if (stat(infile, &st)) {
		logger(-1, 0, "Container configuration file %s not found",
			infile);
		goto err;
	}
	param = init_vps_param();
	if (vps_parse_config(0, infile, param, NULL))
		goto err;

	/* Merge configs (needed for DISK_QUOTA value, maybe others) */
	merge_vps_param(gparam, param);

	if (vswap == -1)
		vswap = is_vswap_config(&param->res.ub);

	if (!(ret = validate(&param->res, recover, ask, vswap))) {
		if (recover || ask)
			if (vps_save_config(0, infile, param, NULL, NULL))
				goto err;
		logger(-1, 0, "Validation completed: success");
		ret = 0;
	}
	else
		ret = 2;

err:
	free(infile);
	exit(ret);
}
示例#7
0
文件: vzcalc.c 项目: open-sw/vzctl
int calculate(int veid, ub_param *ub, int verbose)
{
	ub_param ub_cur;
	char tmp[STR_SIZE];
	int ret = 0;
	double kmem_net_cur, lm_cur, tr_cur, ms_cur, al_cur, np_cur;
	double kmem_net_max, lm_max, lm_prm, ms_prm, al_prm, al_max, np_max;
	double cur, prm, max;
	unsigned long long lowmem;
	unsigned long long ram, swap = 1;
	int run, thrmax;
	int page;

	if (check_param(ub))
		return 1;
	if (get_mem(&ram))
		return 1;
	if (get_thrmax(&thrmax))
		return 1;
	get_swap(&swap);
	if (get_lowmem(&lowmem))
		return 1;
	page = get_pagesize();
	lm_cur = tr_cur = ms_cur = al_cur = np_cur = 0;
	lowmem *= 0.4;
	memset(&ub_cur, 0, sizeof(ub_cur));
	if (!(run = vps_read_ubc(veid, &ub_cur))) {
		if (check_param(&ub_cur))
			return 1;
		kmem_net_cur = (double)ub_cur.kmemsize[0] +
			(double)ub_cur.tcprcvbuf[0] +
			(double)ub_cur.tcpsndbuf[0] +
			(double)ub_cur.dgramrcvbuf[0] +
			(double)ub_cur.othersockbuf[0];
		/*	Low memory	*/
		lm_cur = kmem_net_cur / lowmem;
		/*	Total RAM	*/
		tr_cur = ((double)ub_cur.physpages[0] * page + kmem_net_cur)
					/ ram;
		/*	Mem + Swap	*/
		ms_cur = ((double)ub_cur.oomguarpages[0] * page +
				kmem_net_cur) /	(ram + swap);
		/*	Allocated	*/
		al_cur = ((double)ub_cur.privvmpages[0] * page +
				kmem_net_cur) / (ram + swap);
		/*	Numproc		*/
		np_cur = (double)ub_cur.numproc[0] / thrmax;
	}
	kmem_net_max = (double)ub->kmemsize[1] +
		(double)ub->tcprcvbuf[1] +
		(double)ub->tcpsndbuf[1] +
		(double)ub->dgramrcvbuf[1] +
		(double)ub->othersockbuf[1];

	/*	Low memory	*/
	lm_max = kmem_net_max / lowmem;
	lm_prm = lm_max;
	/*	Mem + Swap	*/
	ms_prm = ((double)ub->oomguarpages[0] * page + kmem_net_max) /
			(ram + swap);
	/*	Allocated	*/
	al_prm = ((double)ub->vmguarpages[0] * page + kmem_net_max) /
			(ram + swap);
	al_max = ((double)ub->privvmpages[1] * page + kmem_net_max) /
			(ram + swap);
	/*	Numproc		*/
	np_max = (double)ub->numproc[0] / thrmax;

	/* Calculate maximum for current */
	cur = lm_cur;
	if (tr_cur > cur)
		cur = tr_cur;
	if (ms_cur > cur)
		cur = ms_cur;
	if (al_cur > cur)
		cur = al_cur;
	if (np_cur > cur)
		cur = np_cur;
	/* Calculate maximum for promised */
	prm = lm_prm;
	if (ms_prm > prm)
		prm = ms_prm;
	if (al_prm > prm)
		prm = al_prm;
	/* Calculate maximum for Max */
	max = lm_max;
	if (al_max > max)
		max = al_max;
	if (np_max > max)
		max = np_max;
	sprintf(tmp, "n/a");
	printf("Resource     Current(%%)  Promised(%%)  Max(%%)\n");
	if (verbose) {
		if (!run)
			sprintf(tmp, "%10.2f", lm_cur * 100);
		printf("Low Mem    %10s %10.2f %10.2f\n",
				tmp, lm_prm * 100, lm_max * 100);
		if (!run)
			sprintf(tmp, "%10.2f", tr_cur * 100);
		printf("Total RAM  %10s        n/a        n/a \n", tmp);
		if (!run)
			sprintf(tmp, "%10.2f", ms_cur * 100);
		printf("Mem + Swap %10s %10.2f        n/a\n",
				tmp, ms_prm * 100);
		if (!run)
			sprintf(tmp, "%10.2f", al_cur * 100);
		printf("Alloc. Mem %10s %10.2f %10.2f\n",
				tmp , al_prm * 100, al_max * 100);
		if (!run)
			sprintf(tmp, "%10.2f", np_cur * 100);
		printf("Num. Proc  %10s        n/a %10.2f\n",
				tmp, np_max * 100);
		printf("--------------------------------------------\n");
	}
	if (!run)
		sprintf(tmp, "%10.2f", cur * 100);
	printf("Memory     %10s %10.2f %10.2f\n", tmp, prm * 100, max * 100);
	free_ub_param(&ub_cur);
	return ret;
}
示例#8
0
static ssize_t
vm_read_mem(const pid_t pid, void *const laddr,
	    const kernel_ulong_t raddr, const size_t len)
{
	const unsigned long truncated_raddr = raddr;

#if SIZEOF_LONG < SIZEOF_KERNEL_LONG_T
	if (raddr != (kernel_ulong_t) truncated_raddr) {
		errno = EIO;
		return -1;
	}
#endif

	const struct iovec local = {
		.iov_base = laddr,
		.iov_len = len
	};
	const struct iovec remote = {
		.iov_base = (void *) truncated_raddr,
		.iov_len = len
	};

	const ssize_t rc = process_vm_readv(pid, &local, 1, &remote, 1, 0);
	if (rc < 0 && errno == ENOSYS)
		process_vm_readv_not_supported = true;

	return rc;
}

static bool
tracee_addr_is_invalid(kernel_ulong_t addr)
{
	return
#if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
		current_wordsize < sizeof(addr) && addr & ~(kernel_ulong_t) -1U;
#else
		false;
#endif
}

/* legacy method of copying from tracee */
static int
umoven_peekdata(const int pid, kernel_ulong_t addr, unsigned int len,
		void *laddr)
{
	unsigned int nread = 0;
	unsigned int residue = addr & (sizeof(long) - 1);

	while (len) {
		addr &= -sizeof(long);		/* aligned address */

		errno = 0;
		union {
			long val;
			char x[sizeof(long)];
		} u = { .val = ptrace(PTRACE_PEEKDATA, pid, addr, 0) };

		switch (errno) {
			case 0:
				break;
			case ESRCH: case EINVAL:
				/* these could be seen if the process is gone */
				return -1;
			case EFAULT: case EIO: case EPERM:
				/* address space is inaccessible */
				if (nread) {
					perror_msg("umoven: short read (%u < %u) @0x%" PRI_klx,
						   nread, nread + len, addr - nread);
				}
				return -1;
			default:
				/* all the rest is strange and should be reported */
				perror_msg("umoven: PTRACE_PEEKDATA pid:%d @0x%" PRI_klx,
					    pid, addr);
				return -1;
		}

		unsigned int m = MIN(sizeof(long) - residue, len);
		memcpy(laddr, &u.x[residue], m);
		residue = 0;
		addr += sizeof(long);
		laddr += m;
		nread += m;
		len -= m;
	}

	return 0;
}

/*
 * Copy `len' bytes of data from process `pid'
 * at address `addr' to our space at `our_addr'.
 */
int
umoven(struct tcb *const tcp, kernel_ulong_t addr, unsigned int len,
       void *const our_addr)
{
	if (tracee_addr_is_invalid(addr))
		return -1;

	const int pid = tcp->pid;

	if (process_vm_readv_not_supported)
		return umoven_peekdata(pid, addr, len, our_addr);

	int r = vm_read_mem(pid, our_addr, addr, len);
	if ((unsigned int) r == len)
		return 0;
	if (r >= 0) {
		error_msg("umoven: short read (%u < %u) @0x%" PRI_klx,
			  (unsigned int) r, len, addr);
		return -1;
	}
	switch (errno) {
		case ENOSYS:
		case EPERM:
			/* try PTRACE_PEEKDATA */
			return umoven_peekdata(pid, addr, len, our_addr);
		case ESRCH:
			/* the process is gone */
			return -1;
		case EFAULT: case EIO:
			/* address space is inaccessible */
			return -1;
		default:
			/* all the rest is strange and should be reported */
			perror_msg("process_vm_readv: pid:%d @0x%" PRI_klx,
				    pid, addr);
			return -1;
	}
}

/*
 * Like umoven_peekdata but make the additional effort of looking
 * for a terminating zero byte.
 */
static int
umovestr_peekdata(const int pid, kernel_ulong_t addr, unsigned int len,
		  void *laddr)
{
	unsigned int nread = 0;
	unsigned int residue = addr & (sizeof(long) - 1);
	void *const orig_addr = laddr;

	while (len) {
		addr &= -sizeof(long);		/* aligned address */

		errno = 0;
		union {
			unsigned long val;
			char x[sizeof(long)];
		} u = { .val = ptrace(PTRACE_PEEKDATA, pid, addr, 0) };

		switch (errno) {
			case 0:
				break;
			case ESRCH: case EINVAL:
				/* these could be seen if the process is gone */
				return -1;
			case EFAULT: case EIO: case EPERM:
				/* address space is inaccessible */
				if (nread) {
					perror_msg("umovestr: short read (%d < %d) @0x%" PRI_klx,
						   nread, nread + len, addr - nread);
				}
				return -1;
			default:
				/* all the rest is strange and should be reported */
				perror_msg("umovestr: PTRACE_PEEKDATA pid:%d @0x%" PRI_klx,
					   pid, addr);
				return -1;
		}

		unsigned int m = MIN(sizeof(long) - residue, len);
		memcpy(laddr, &u.x[residue], m);
		while (residue < sizeof(long))
			if (u.x[residue++] == '\0')
				return (laddr - orig_addr) + residue;
		residue = 0;
		addr += sizeof(long);
		laddr += m;
		nread += m;
		len -= m;
	}

	return 0;
}

/*
 * Like `umove' but make the additional effort of looking
 * for a terminating zero byte.
 *
 * Returns < 0 on error, strlen + 1  if NUL was seen,
 * else 0 if len bytes were read but no NUL byte seen.
 *
 * Note: there is no guarantee we won't overwrite some bytes
 * in laddr[] _after_ terminating NUL (but, of course,
 * we never write past laddr[len-1]).
 */
int
umovestr(struct tcb *const tcp, kernel_ulong_t addr, unsigned int len,
	 char *laddr)
{
	if (tracee_addr_is_invalid(addr))
		return -1;

	const int pid = tcp->pid;

	if (process_vm_readv_not_supported)
		return umovestr_peekdata(pid, addr, len, laddr);

	const size_t page_size = get_pagesize();
	const size_t page_mask = page_size - 1;
	unsigned int nread = 0;

	while (len) {
		/*
		 * Don't cross pages, otherwise we can get EFAULT
		 * and fail to notice that terminating NUL lies
		 * in the existing (first) page.
		 */
		unsigned int chunk_len = len > page_size ? page_size : len;
		unsigned int end_in_page = (addr + chunk_len) & page_mask;
		if (chunk_len > end_in_page) /* crosses to the next page */
			chunk_len -= end_in_page;

		int r = vm_read_mem(pid, laddr, addr, chunk_len);
		if (r > 0) {
			char *nul_addr = memchr(laddr, '\0', r);

			if (nul_addr)
				return (nul_addr - laddr) + 1;
			addr += r;
			laddr += r;
			nread += r;
			len -= r;
			continue;
		}
		switch (errno) {
			case ENOSYS:
			case EPERM:
				/* try PTRACE_PEEKDATA */
				if (!nread)
					return umovestr_peekdata(pid, addr,
								 len, laddr);
				ATTRIBUTE_FALLTHROUGH;
			case EFAULT: case EIO:
				/* address space is inaccessible */
				if (nread)
					perror_msg("umovestr: short read (%d < %d) @0x%" PRI_klx,
						   nread, nread + len, addr - nread);
				return -1;
			case ESRCH:
				/* the process is gone */
				return -1;
			default:
				/* all the rest is strange and should be reported */
				perror_msg("process_vm_readv: pid:%d @0x%" PRI_klx,
					    pid, addr);
				return -1;
		}
	}

	return 0;
}