/* called to setup bootcharting */
int   bootchart_init( void )
{
    int  ret;
    char buff[4];
    int  timeout = 0, count = 0;

    buff[0] = 0;
    proc_read( LOG_STARTFILE, buff, sizeof(buff) );
    if (buff[0] != 0) {
        timeout = atoi(buff);
    }
    else {
        /* when running with emulator, androidboot.bootchart=<timeout>
         * might be passed by as kernel parameters to specify the bootchart
         * timeout. this is useful when using -wipe-data since the /data
         * partition is fresh
         */
        char  cmdline[1024];
        char* s;
#define  KERNEL_OPTION  "androidboot.bootchart="
        proc_read( "/proc/cmdline", cmdline, sizeof(cmdline) );
        s = strstr(cmdline, KERNEL_OPTION);
        if (s) {
            s      += sizeof(KERNEL_OPTION)-1;
            timeout = atoi(s);
        }
    }
    if (timeout == 0)
        return 0;

    if (timeout > BOOTCHART_MAX_TIME_SEC)
        timeout = BOOTCHART_MAX_TIME_SEC;

    count = (timeout*1000 + BOOTCHART_POLLING_MS-1)/BOOTCHART_POLLING_MS;

    do {ret=mkdir(LOG_ROOT,0755);}while (ret < 0 && errno == EINTR);
    selinux_android_restorecon(LOG_ROOT, 0);

    file_buff_open(log_stat,  LOG_STAT);
    file_buff_open(log_procs, LOG_PROCS);
    file_buff_open(log_disks, LOG_DISK);

    /* create kernel process accounting file */
    {
        int  fd = open( LOG_ACCT, O_WRONLY|O_CREAT|O_TRUNC,0644);
        if (fd >= 0) {
            close(fd);
            acct( LOG_ACCT );
        }
    }

    log_header();
    return count;
}
示例#2
0
int sys_read(unsigned int fd,char * buf,int count)
{
	struct file * file;
	struct m_inode * inode;

	if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd]))
		return -EINVAL;
	if (!count)
		return 0;
	verify_area(buf,count);
	inode = file->f_inode;
	if (inode->i_pipe)
		return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO;
	if (S_ISCHR(inode->i_mode))
		return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos);
	if (S_ISBLK(inode->i_mode))
		return block_read(inode->i_zone[0],&file->f_pos,buf,count);
	if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) {
		if (count+file->f_pos > inode->i_size)
			count = inode->i_size - file->f_pos;
		if (count<=0)
			return 0;
		return file_read(inode,file,buf,count);
	}
	if(S_ISPROC(inode->i_mode))
		return proc_read(inode, buf, count, &file->f_pos);

	printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode);
	return -EINVAL;
}
int	proc_seek_args(proc_obj_t* obj, args_t* args)
{
  regs_t*	regs = NULL;
  list_t*	list = NULL;
  arg_t*	arg = NULL;
  int		i;
  addr_t	cur_addr = 0;

  if (!args)
    return (-1);

  regs = proc_get_registers(obj);
  if (regs == NULL)
    return (-1);

  /*
  ** Browse the stack to find args.
  */
  for (list = args->prev, i = 0; list; list = list->prev, i++)
    {
      arg = (arg_t*) list->value;
      /*
      ** TODO struct ...
      */
      if (arg->size > sizeof(long double))
	{
	  if (regs)
	    free(regs);
	  return (-1);
	}
      if (arg->size < sizeof(int))
	arg->size = sizeof(int);

      /*
      ** 7 first arguments are in register R_O0 to R_06
      ** nexts are on the stack.
      */
      arg->value[0] = 0;
      if (last_call_reg && i < 6)
	long_to_strval(last_call_reg->greg[R_O0 + i], arg);
      else
	{
	  long	ulr;

	  if (cur_addr == 0)
	    cur_addr = regs->greg[R_FP] + 92;
	  if (proc_read(obj, cur_addr, sizeof(long), (char*) &ulr) != sizeof(long))
	    return (-1);
	  long_to_strval(ulr, arg);
	  cur_addr += arg->size;
	}

      if (list == args)
	break;
    }
  free(regs);
  return (0);
}
示例#4
0
static long long
get_uptime_jiffies()
{
    char       buff[64];
    long long  jiffies = 0;

    if (proc_read("/proc/uptime", buff, sizeof(buff)) > 0)
        jiffies = 100LL*strtod(buff,NULL);

    return jiffies;
}
示例#5
0
void setup_history()
{
	/*
	 * The /proc file size will vary during intervals, use double of current
	 * size to have enough buffer for growing values.
	 */
	meminfo_size = proc_read_size("/proc/meminfo") * 2;
	vmstat_size = proc_read_size("/proc/vmstat") * 2;
	cpustat_size = CPUSTAT_SIZE;

	meminfo = malloc(meminfo_size * (history_max + 1));
	if (!meminfo)
		cpuplugd_exit("Out of memory: meminfo\n");
	vmstat = malloc(vmstat_size * (history_max + 1));
	if (!vmstat)
		cpuplugd_exit("Out of memory: vmstat\n");
	cpustat = malloc(cpustat_size * (history_max + 1));
	if (!cpustat)
		cpuplugd_exit("Out of memory: cpustat\n");
	timestamps = malloc(sizeof(double) * (history_max + 1));
	if (!timestamps)
		cpuplugd_exit("Out of memory: timestamps\n");

	/*
	 * Read history data, at least 1 interval for swaprate, apcr, idle, etc.
	 */
	history_current = 0;
	cpuplugd_info("Waiting %i intervals to accumulate history.\n",
		      history_max);
	do {
		time_read(&timestamps[history_current]);
		proc_read(meminfo + history_current * meminfo_size,
			  "/proc/meminfo", meminfo_size);
		proc_read(vmstat + history_current * vmstat_size,
			  "/proc/vmstat", vmstat_size);
		proc_cpu_read(cpustat + history_current * cpustat_size);
		sleep(cfg.update);
		history_current++;
	} while (history_current < history_max);
	history_current--;
}
示例#6
0
static void
do_log_procs(FileBuff  log)
{
    DIR*  dir = opendir("/proc");
    struct dirent*  entry;

    do_log_uptime(log);

    while ((entry = readdir(dir)) != NULL) {
        /* only match numeric values */
        char*  end;
        int    pid = strtol( entry->d_name, &end, 10);
        if (end != NULL && end > entry->d_name && *end == 0) {
            char  filename[32];
            char  buff[1024];
            char  cmdline[1024];
            int   len;
            int   fd;

            /* read command line and extract program name */
            snprintf(filename,sizeof(filename),"/proc/%d/cmdline",pid);
            proc_read(filename, cmdline, sizeof(cmdline));

            /* read process stat line */
            snprintf(filename,sizeof(filename),"/proc/%d/stat",pid);
            fd = open(filename,O_RDONLY);
            if (fd >= 0) {
               len = unix_read(fd, buff, sizeof(buff)-1);
               close(fd);
               if (len > 0) {
                    int  len2 = strlen(cmdline);
                    if (len2 > 0) {
                        /* we want to substitute the process name with its real name */
                        const char*  p1;
                        const char*  p2;
                        buff[len] = 0;
                        p1 = strchr(buff, '(');
                        p2 = strchr(p1, ')');
                        file_buff_write(log, buff, p1+1-buff);
                        file_buff_write(log, cmdline, strlen(cmdline));
                        file_buff_write(log, p2, strlen(p2));
                    } else {
                        /* no substitution */
                        file_buff_write(log,buff,len);
                    }
               }
            }
        }
    }
    closedir(dir);
    do_log_ln(log);
}
示例#7
0
static void
log_header(void)
{
    FILE*      out;
    char       cmdline[1024];
    char       uname[128];
    char       cpuinfo[128];
    char*      cpu;
    char       date[32];
    time_t     now_t = time(NULL);
    struct tm  now = *localtime(&now_t);
    strftime(date, sizeof(date), "%x %X", &now);

    out = fopen( LOG_HEADER, "w" );
    if (out == NULL)
        return;

    proc_read("/proc/cmdline", cmdline, sizeof(cmdline));
    proc_read("/proc/version", uname, sizeof(uname));
    proc_read("/proc/cpuinfo", cpuinfo, sizeof(cpuinfo));

    cpu = strchr( cpuinfo, ':' );
    if (cpu) {
        char*  p = strchr(cpu, '\n');
        cpu += 2;
        if (p)
            *p = 0;
    }

    fprintf(out, "version = %s\n", VERSION);
    fprintf(out, "title = Boot chart for Linux ( %s )\n", date);
    fprintf(out, "system.uname = %s\n", uname);
    fprintf(out, "system.release = 0.0\n");
    fprintf(out, "system.cpu = %s\n", cpu);
    fprintf(out, "system.kernel.options = %s\n", cmdline);
    fclose(out);
}
示例#8
0
文件: lock64.c 项目: cz0u/studynotes
void *proc_mmap(struct proc *p, int prot, int flags) {
	void *addr = NULL;
	char *code = "\xcd\x80\x00\x00\x00\x00\x00\x00";
	proc_save(p);
	p->regs = p->oregs;
	p->regs.rax = SYS_mmap; 
	p->regs.rdi = 0;
	p->regs.rsi = 4;
	p->regs.rdx = prot;
	p->regs.r10 = flags;
	p->regs.r8 = -1;
	p->regs.r9 = 0;
	p->regs.rip = EBASE;
	char savebuf[8] = {0};
	int n = proc_read(p, (void*)EBASE, savebuf, 8);
	if (n != 8) {
		perror("read");
		exit(1);
	}
	n = proc_write(p, (void*)EBASE, code, 8);
	if (n != 8) {
		perror("write");
		exit(1);
	}
	proc_regs(p, 1);
	printf("syscall mmap begin...\n");
	ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL);
	while (1) {
		proc_wait(p);
		if (p->stat != SYSCALL_STOP) {
			goto cont;
		}
		proc_regs(p, 0);
		if (p->regs.orig_rax == SYS_mmap) {
			if (p->insys == 0) {
				p->insys = 1;
			} else if (p->insys == 1) {
				addr = (void *)p->regs.rax;
				p->insys = 0;
				break;
			}
		}
cont:
		ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL);
	}
	proc_write(p, (void *)EBASE, savebuf, 4);
	proc_restore(p);
	return addr;
}
static void	detect_call_and_save_args(proc_obj_t* obj, regs_t* regs)
{
  addr_t	r;

  if (proc_read(obj, regs->greg[R_PC], sizeof(int), (char*) &r) != -1)
    {
      if ((0xFF000000 & r) == 0x7f000000 ||
	  (0xFF000000 & r) == 0x40000000)
	{
	  if (last_call_reg)
	    free(last_call_reg);
	  last_call_reg = proc_get_registers(obj);
	}
    }
}
示例#10
0
文件: lock64.c 项目: cz0u/studynotes
int proc_mprotect(struct proc *p, void *addr, int prot) {
	int ret = 0;
	unsigned long err = 0;
	char *code = "\x0f\x05\x00\x00\x00\x00\x00\x00";
	proc_save(p);
	p->regs = p->oregs;
	p->regs.rax = SYS_mprotect; 
	p->regs.rdi = (unsigned long)addr;
	p->regs.rsi = 0x1000;
	p->regs.rdx = prot;
	p->regs.rip = EBASE;
	char savebuf[8] = {0};
	int n = proc_read(p, (void*)EBASE, savebuf, 8);
	if (n != 8) {
		perror("read");
		exit(1);
	}
	n = proc_write(p, (void*)EBASE, code, 8);
	if (n != 8) {
		perror("write");
		exit(1);
	}
	proc_regs(p, 1);
	ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL);
	while (1) {
		proc_wait(p);
		if (p->stat != SYSCALL_STOP) {
			printf("not syscall\n");
			goto cont;
		}
		proc_regs(p, 0);
		if (p->regs.orig_rax == SYS_mprotect) {
			if (p->insys == 0) {
				p->insys = 1;
			} else if (p->insys == 1) {
				err = p->regs.rax;
				p->insys = 0;
				break;
			}
		}
cont:
		ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL);
	}
	proc_write(p, (void *)EBASE, savebuf, 8);
	proc_restore(p);
	printf("%d, %s\n", err, strerror(-err));
	return ret;
}
示例#11
0
/* called each time you want to perform a bootchart sampling op */
int  bootchart_step( void )
{
    do_log_file(log_stat,   "/proc/stat");
    do_log_file(log_disks,  "/proc/diskstats");
    do_log_procs(log_procs);

    /* we stop when /data/bootchart-stop contains 1 */
    {
        char  buff[2];
        if (proc_read(LOG_STOPFILE,buff,sizeof(buff)) > 0 && buff[0] == '1') {
            return -1;
        }
    }

    return 0;
}
示例#12
0
文件: lxcfs.c 项目: Blub/lxcfs
static int do_proc_read(const char *path, char *buf, size_t size, off_t offset,
		struct fuse_file_info *fi)
{
	int (*proc_read)(const char *path, char *buf, size_t size, off_t offset,
		struct fuse_file_info *fi);
	char *error;

	dlerror();    /* Clear any existing error */
	proc_read = (int (*)(const char *, char *, size_t, off_t, struct fuse_file_info *)) dlsym(dlopen_handle, "proc_read");
	error = dlerror();
	if (error != NULL) {
		fprintf(stderr, "proc_read: %s\n", error);
		return -1;
	}

	return proc_read(path, buf, size, offset, fi);
}
示例#13
0
文件: lock64.c 项目: cz0u/studynotes
void proc_exit(struct proc *p, int no) {
	char *code = "\xcd\x80\x00\x00\x00\x00\x00\x00";
	proc_save(p);
	p->regs = p->oregs;
	p->regs.rax = SYS_exit;
	p->regs.rdi = no;
	p->regs.rip = EBASE;
	char savebuf[8] = {0};
	int n = proc_read(p, (void*)EBASE, savebuf, 8);
	if (n != 8) {
		perror("read");
		exit(1);
	}
	proc_write(p, (void*)EBASE, code, 8);
	proc_regs(p, 1);
	printf("syscall exit begin...\n");
	ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL);
	while (1) {
		proc_wait(p);
		if (p->stat == DEAD) {
			printf("%p: ", p->status);
			if (WIFEXITED(p->status)) {
				printf("exit code %d\n", WEXITSTATUS(p->status));
			} else if (WIFSIGNALED(p->status)) {
				printf("signal %d\n", WTERMSIG(p->status));
			}
			break;
		}
		if (p->stat != SYSCALL_STOP) {
			goto cont;
		}
		proc_regs(p, 0);
		if (p->regs.orig_rax == SYS_exit) {
			if (p->insys == 0) {
				p->insys = 1;
			} else if (p->insys == 1) {
				p->insys = 0;
				break;
			}
		}
cont:
		ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL);
	}
}
示例#14
0
文件: proc.c 项目: tolimit/nmon
		void proc_mem (struct mem_brk * mem_brk)
		{
			if (mem_brk == NULL)
				return;

			struct proc_file * proc = mem_brk->ext->proc;
			struct data * p = mem_brk->ext->p;
			if(proc[P_MEMINFO].read_this_interval == 0)
				proc_read(proc, P_MEMINFO);

			p->mem.memtotal   = proc_mem_search(proc, "MemTotal");
			p->mem.memfree    = proc_mem_search(proc, "MemFree");
			p->mem.memshared  = proc_mem_search(proc, "MemShared");
			p->mem.buffers    = proc_mem_search(proc, "Buffers");
			p->mem.cached     = proc_mem_search(proc, "Cached");
			p->mem.swapcached = proc_mem_search(proc, "SwapCached");
			p->mem.active     = proc_mem_search(proc, "Active");
			p->mem.inactive   = proc_mem_search(proc, "Inactive");
			p->mem.hightotal  = proc_mem_search(proc, "HighTotal");
			p->mem.highfree   = proc_mem_search(proc, "HighFree");
			p->mem.lowtotal   = proc_mem_search(proc, "LowTotal");
			p->mem.lowfree    = proc_mem_search(proc, "LowFree");
			p->mem.swaptotal  = proc_mem_search(proc, "SwapTotal");
			p->mem.swapfree   = proc_mem_search(proc, "SwapFree");
#ifdef LARGEMEM
			p->mem.dirty         = proc_mem_search(proc, "Dirty");
			p->mem.writeback     = proc_mem_search(proc, "Writeback");
			p->mem.mapped        = proc_mem_search(proc, "Mapped");
			p->mem.slab          = proc_mem_search(proc, "Slab");
			p->mem.committed_as  = proc_mem_search(proc, "Committed_AS");
			p->mem.pagetables    = proc_mem_search(proc, "PageTables");
			p->mem.hugetotal     = proc_mem_search(proc, "HugePages_Total");
			p->mem.hugefree      = proc_mem_search(proc, "HugePages_Free");
			p->mem.hugesize      = proc_mem_search(proc, "Hugepagesize");
#else
			p->mem.bigfree       = proc_mem_search(proc, "BigFree");
#endif /*LARGEMEM*/
		}
示例#15
0
/** void loop_all_pids(char *ps, pid_t max_pid, int *_errors, int *_total)
 * Check all the available PIDs for hidden stuff.
 */
void loop_all_pids(char *ps, pid_t max_pid, int *_errors, int *_total)
{
    int _kill0 = 0;
    int _kill1 = 0;
    int _gsid0 = 0;
    int _gsid1 = 0;
    int _gpid0 = 0;
    int _gpid1 = 0;
    int _ps0 = -1;
    int _proc_stat  = 0;
    int _proc_read  = 0;
    int _proc_chdir = 0;

    pid_t i = 1;
    pid_t my_pid;

    char command[OS_SIZE_1024 +1];

    my_pid = getpid();

    for(;;i++)
    {
        if((i <= 0)||(i > max_pid))
            break;

        (*_total)++;

        _kill0 = 0;
        _kill1 = 0;
        _gsid0 = 0;
        _gsid1 = 0;
        _gpid0 = 0;
        _gpid1 = 0;
        _ps0 = -1;
        _proc_stat  = 0;
        _proc_read  = 0;
        _proc_chdir = 0;


        /* kill test */
        if(!((kill(i, 0) == -1)&&(errno == ESRCH)))
        {
            _kill0 = 1;
        }

        /* getsid to test */
        if(!((getsid(i) == -1)&&(errno == ESRCH)))
        {
            _gsid0 = 1;
        }

        /* getpgid test */
        if(!((getpgid(i) == -1)&&(errno == ESRCH)))
        {
            _gpid0 = 1;
        }


        /* proc stat */
        _proc_stat = proc_stat(i);

        /* proc readdir */
        _proc_read = proc_read(i);

        /* proc chdir */
        _proc_chdir = proc_chdir(i);


        /* IF PID does not exist, keep going */
        if(!_kill0 && !_gsid0 && !_gpid0 &&
           !_proc_stat && !_proc_read && !_proc_chdir)
        {
            continue;
        }

        /* We do not need to look at our own pid */
        else if(i == my_pid)
        {
            continue;
        }

        /* Checking the number of errors */
        if((*_errors) > 15)
        {
            char op_msg[OS_SIZE_1024 +1];
            snprintf(op_msg,OS_SIZE_1024,"Excessive number of hidden processes"
                    ". It maybe a false-positive or "
                    "something really bad is going on.");
            notify_rk(ALERT_SYSTEM_CRIT, op_msg);
            return;
        }


        /* checking if process appears on ps */
        if(*ps)
        {
            snprintf(command, OS_SIZE_1024, "%s -p %d > /dev/null 2>&1",
                                                        ps,
                                                        (int)i);

            /* Found PID on ps */
            _ps0 = 0;
            if(system(command) == 0)
                _ps0 = 1;
        }

        /* If we are being run by the ossec hids, sleep here (no rush) */
        #ifdef OSSECHIDS
        sleep(2);
        #endif

        /* Everyone returned ok */
        if(_ps0 && _kill0 && _gsid0 && _gpid0 && _proc_stat && _proc_read)
        {
            continue;
        }



        /* If our kill or getsid system call, got the
         * PID , but ps didn't, we need to find if it was a problem
         * with a PID being deleted (not used anymore)
         */
        {
            if(!((getsid(i) == -1)&&(errno == ESRCH)))
            {
                _gsid1 = 1;
            }

            if(!((kill(i, 0) == -1)&&(errno == ESRCH)))
            {
                _kill1 = 1;
            }

            if(!((getpgid(i) == -1)&&(errno == ESRCH)))
            {
                _gpid1 = 1;
            }


            _proc_stat = proc_stat(i);

            _proc_read = proc_read(i);

            _proc_chdir = proc_chdir(i);

            /* If it matches, process was terminated */
            if(!_gsid1 &&!_kill1 &&!_gpid1 &&!_proc_stat &&
               !_proc_read &&!_proc_chdir)
            {
                continue;
            }
        }

        #ifdef AIX
        /* Ignoring AIX wait and sched programs. */
        if((_gsid0 == _gsid1) &&
           (_kill0 == _kill1) &&
           (_gpid0 == _gpid1) &&
           (_ps0 == 1) &&
           (_gsid0 == 1) &&
           (_kill0 == 0))
        {
            /* The wait and sched programs do not respond to kill 0.
             * So, if everything else finds it, including ps, getpid, getsid,
             * but not
             * kill, we can safely ignore on AIX.
             * A malicious program would specially try to hide from ps..
             */
            continue;
        }
        #endif


        if((_gsid0 == _gsid1)&&
           (_kill0 == _kill1)&&
           (_gsid0 != _kill0))
        {
            /* If kill found, but getsid and getpgid didnt', it may
             * be a defunct process -- ignore.
             */
            if(!((_kill0 == 1)&&(_gsid0 == 0)&&(_gpid0 == 0)&&(_gsid1 == 0)))
            {
                char op_msg[OS_SIZE_1024 +1];

                snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from "
                        "kill (%d) or getsid (%d). Possible kernel-level"
                        " rootkit.", (int)i, _kill0, _gsid0);

                notify_rk(ALERT_ROOTKIT_FOUND, op_msg);
                (*_errors)++;
            }
        }
        else if((_kill1 != _gsid1)||
                (_gpid1 != _kill1)||
                (_gpid1 != _gsid1))
        {
            /* See defunct process comment above. */
            if(!((_kill1 == 1)&&(_gsid1 == 0)&&(_gpid0 == 0)&&(_gsid1 == 0)))
            {
                char op_msg[OS_SIZE_1024 +1];
                snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from "
                        "kill (%d), getsid (%d) or getpgid. Possible "
                        "kernel-level rootkit.", (int)i, _kill1, _gsid1);

                notify_rk(ALERT_ROOTKIT_FOUND, op_msg);
                (*_errors)++;
            }
        }
        else if((_proc_read != _proc_stat)||
                (_proc_read != _proc_chdir)||
                (_proc_stat != _kill1))
        {
            /* checking if the pid is a thread (not showing on proc */
            if(!noproc && !check_rc_readproc((int)i))
            {
                char op_msg[OS_SIZE_1024 +1];
                snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from "
                        "/proc. Possible kernel level rootkit.", (int)i);
                notify_rk(ALERT_ROOTKIT_FOUND, op_msg);
                (*_errors)++;
            }
        }
        else if(_gsid1 && _kill1 && !_ps0)
        {
            /* checking if the pid is a thread (not showing on ps */
            if(!check_rc_readproc((int)i))
            {
                char op_msg[OS_SIZE_1024 +1];
                snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from "
                             "ps. Possible trojaned version installed.",
                             (int)i);

                notify_rk(ALERT_ROOTKIT_FOUND, op_msg);
                (*_errors)++;
            }
        }
    }
}
示例#16
0
文件: lock64.c 项目: cz0u/studynotes
void ProcWriteInt(struct proc *p, void *addr, int n) {
	char buf[8] = {0};
	proc_read(p, addr, buf, 8);
	memmove(buf, &n, 4);
	proc_write(p, addr, buf, 8);
}
list_t*	proc_get_depends_list(proc_obj_t* obj)
{
  Elf_Ehdr		ehdr;
  Elf_Phdr		phdr;
  Elf_Dyn		dyn;
  struct link_map	lmap;
  unsigned long		phdr_addr, dyn_addr, addr;
  struct r_debug	rdebug;
  char			buf[PATH_MAX + 1];
  list_t*		ret = NULL;
  depend_t*		cur = NULL;

  /*
  ** Get elf header.
  */
  if (proc_read(obj, 0x10000, sizeof(Elf32_Ehdr), (char*) &ehdr) == -1)
    return (NULL);
  if (!IS_ELF(ehdr))
    {
      errno = EFTRACE;
      ftrace_errstr = "Not Elf ?!";
      exit(1);
      return (NULL);
    }
  /*
  ** Get program Headers and find the Dynamic program header..
  */
  phdr_addr = 0x10000 + ehdr.e_phoff;
  if (proc_read(obj, phdr_addr, sizeof(Elf32_Phdr), (char*) &phdr) == -1)
    return (NULL);
  while (phdr.p_type != PT_DYNAMIC)
    {
      if (proc_read(obj, phdr_addr += sizeof(Elf32_Phdr),
		    sizeof(Elf32_Phdr), (char*) &phdr) == -1)
	return (NULL);
    }
  if  (phdr.p_type != PT_DYNAMIC)
    return (NULL);
  /*
  ** Browse evrey dyn and find {DT_PLTGOT|DT_DEBUG}
  */
  if (proc_read(obj, phdr.p_vaddr, sizeof(Elf32_Dyn), (char*) &dyn) == -1)
    return (NULL);
  dyn_addr = phdr.p_vaddr;
  /*
  ** ---------------------------
  ** Retrieve with the DT_DEBUG
  */
  while (dyn.d_tag != DT_DEBUG)
    {
      if (proc_read(obj, dyn_addr += sizeof(Elf32_Dyn), sizeof(Elf32_Dyn), (char*) &dyn) == -1)
	return (NULL);
    }
  if (dyn.d_tag != DT_DEBUG)
    return (NULL);
  /* printf("struct rdebug found @ 0x%x\n", dyn.d_un.d_ptr); */
  /*
  ** Get addresse's struct rdebug
  */
  if (proc_read(obj, dyn.d_un.d_ptr, sizeof(struct r_debug), (char*) &rdebug) == -1)
    return (NULL);
  /*
  ** Here we have the link_map addr.
  ** Create the depend list...
  */
  for (addr = (unsigned long) rdebug.r_map; addr; addr = (unsigned long) lmap.l_next)
    {
      if (proc_read(obj, addr, sizeof(struct link_map), (char*) &lmap) == -1)
	goto proc_get_depends_list_failed;
      if (lmap.l_name == 0)
	continue;
      if (proc_read(obj, (long) lmap.l_name, PATH_MAX, (char*) buf) == -1)
	goto proc_get_depends_list_failed;
      cur = malloc(sizeof(depend_t));
      if (cur == NULL)
	goto proc_get_depends_list_failed;
      cur->path = strdup(buf);
      cur->base_addr = (addr_t) lmap.l_addr;
      ret = list_add(ret, cur);
      if (ret == NULL)
	goto proc_get_depends_list_failed;
    }
  return (ret);
  /*
  ** If failed, free list And return NULL.
  */
 proc_get_depends_list_failed:
  for (; ret; )
    {
      cur = (depend_t*) ret->value;
      ret = list_del(ret, cur);
      if (cur && cur->path)
	free(cur->path);
      free(cur);
    }
  return (NULL);
}
示例#18
0
int main(int argc, char *argv[])
{
	double interval;
	int fd, rc;

	reload_pending = 0;
	sym_names_count = sizeof(sym_names) / sizeof(struct symbol_names);
	varinfo_size = VARINFO_SIZE;
	varinfo = calloc(varinfo_size, 1);
	if (!varinfo) {
		cpuplugd_error("Out of memory: varinfo\n");
		exit(1);
	}
	/*
	 * varinfo must start with '\n' for correct string matching
	 * in get_var_rvalue().
	 */
	varinfo[0] = '\n';

	/* Parse the command line options */
	parse_options(argc, argv);

	/* flock() lock file to prevent multiple instances of cpuplugd */
	fd = open(LOCKFILE, O_CREAT | O_RDONLY, S_IRUSR);
	if (fd == -1) {
		cpuplugd_error("Cannot open lock file %s: %s\n", LOCKFILE,
			       strerror(errno));
		exit(1);
	}
	rc = flock(fd, LOCK_EX | LOCK_NB);
	if (rc) {
		cpuplugd_error("flock() failed on lock file %s: %s\nThis might "
			       "indicate that an instance of this daemon is "
			       "already running.\n", LOCKFILE, strerror(errno));
		exit(1);
	}

	/* Make sure that the daemon is not started multiple times */
	check_if_started_twice();
	/* Store daemon pid also in foreground mode */
	handle_signals();
	handle_sighup();

	/* Need 1 history level minimum for internal symbols */
	history_max = 1;
	/*
	 * Parse arguments from the configuration file, also calculate
	 * history_max
	 */
	parse_configfile(configfile);
	if (history_max > MAX_HISTORY)
		cpuplugd_exit("History depth %i exceeded maximum (%i)\n",
			      history_max, MAX_HISTORY);
	/* Check the settings in the configuration file */
	check_config();

	if (!foreground) {
		rc = daemon(1, 0);
		if (rc < 0)
			cpuplugd_exit("Detach from terminal failed: %s\n",
				      strerror(errno));
	}
	/* Store daemon pid */
	store_pid();
	/* Unlock lock file */
	flock(fd, LOCK_UN);
	close(fd);

	/* Install signal handler for floating point exceptions */
	rc = feenableexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW |
			    FE_INVALID);
	act.sa_flags = SA_NODEFER;
	sigemptyset(&act.sa_mask);
	act.sa_handler = sigfpe_handler;
	if (sigaction(SIGFPE, &act, NULL) < 0)
		cpuplugd_exit("sigaction( SIGFPE, ... ) failed - reason %s\n",
			      strerror(errno));

	setup_history();

	/* Main loop */
	while (1) {
		if (reload_pending) {		// check for daemon reload
			reload_daemon();
			reload_pending = 0;
		}

		history_prev = history_current;
		history_current = (history_current + 1) % (history_max + 1);
		time_read(&timestamps[history_current]);
		proc_read(meminfo + history_current * meminfo_size,
			  "/proc/meminfo", meminfo_size);
		proc_read(vmstat + history_current * vmstat_size,
			  "/proc/vmstat", vmstat_size);
		proc_cpu_read(cpustat + history_current * cpustat_size);
		interval = timestamps[history_current] -
			   timestamps[history_prev];
		cpuplugd_debug("config update interval: %ld seconds\n",
			       cfg.update);
		cpuplugd_debug("real update interval: %f seconds\n", interval);

		/* Run code that may signal failure via longjmp. */
		if (cpu == 1) {
			if (setjmp(jmpenv) == 0)
				eval_cpu_rules();
			else
				cpuplugd_error("Floating point exception, "
					       "skipping cpu rule "
					       "evaluation.\n");
		}
		if (memory == 1) {
			if (setjmp(jmpenv) == 0)
				eval_mem_rules(interval);
			else
				cpuplugd_error("Floating point exception, "
					       "skipping memory rule "
					       "evaluation.\n");
		}
		sleep(cfg.update);
	}
	return 0;
}
示例#19
0
TCN_IMPLEMENT_CALL(jint, OS, info)(TCN_STDARGS,
                                   jlongArray inf)
{
    jint rv;
    int  i;
    jsize ilen = (*e)->GetArrayLength(e, inf);
    jlong *pvals = (*e)->GetLongArrayElements(e, inf, NULL);

    UNREFERENCED(o);
    if (ilen < 16) {
        return APR_EINVAL;
    }
    for (i = 0; i < 16; i++)
        pvals[i] = 0;
#if defined(__linux__)
    {
        struct sysinfo info;
        if (sysinfo(&info))
            rv = apr_get_os_error();
        else {
            pvals[0] = (jlong)(info.totalram  * info.mem_unit);
            pvals[1] = (jlong)(info.freeram   * info.mem_unit);
            pvals[2] = (jlong)(info.totalswap * info.mem_unit);
            pvals[3] = (jlong)(info.freeswap  * info.mem_unit);
            pvals[4] = (jlong)(info.sharedram * info.mem_unit);
            pvals[5] = (jlong)(info.bufferram * info.mem_unit);
            pvals[6] = (jlong)(100 - (info.freeram * 100 / info.totalram));
            rv = APR_SUCCESS;
        }
    }
#elif defined(sun)
    {
        /* static variables with basic procfs info */
        static long creation = 0;              /* unix timestamp of process creation */
        static int psinf_fd = 0;               /* file descriptor for the psinfo procfs file */
        static int prusg_fd = 0;               /* file descriptor for the usage procfs file */
        static size_t rss = 0;                 /* maximum of resident set size from previous calls */
        /* static variables with basic kstat info */
        static kstat_ctl_t *kstat_ctl = NULL;  /* kstat control object, only initialized once */
        static kstat_t *kstat_cpu[MAX_CPUS];   /* array of kstat objects for per cpu statistics */
        static int cpu_count = 0;              /* number of cpu structures found in kstat */
        static kid_t kid = 0;                  /* kstat ID, for which the kstat_ctl holds the correct chain */
        /* non-static variables - general use */
        int res = 0;                           /* general result state */
        /* non-static variables - sysinfo/swapctl use */
        long ret_sysconf;                      /* value returned from sysconf call */
        long tck_dividend;                     /* factor used by transforming tick numbers to milliseconds */
        long tck_divisor;                      /* divisor used by transforming tick numbers to milliseconds */
        long sys_pagesize = sysconf(_SC_PAGESIZE); /* size of a system memory page in bytes */
        long sys_clk_tck = sysconf(_SC_CLK_TCK); /* number of system ticks per second */
        struct anoninfo info;                  /* structure for information about sizes in anonymous memory system */
        /* non-static variables - procfs use */
        psinfo_t psinf;                        /* psinfo structure from procfs */
        prusage_t prusg;                       /* usage structure from procfs */
        size_t new_rss = 0;                    /* resident set size read from procfs */
        time_t now;                            /* time needed for calculating process creation time */
        /* non-static variables - kstat use */
        kstat_t *kstat = NULL;                 /* kstat working pointer */
        cpu_sysinfo_t cpu;                     /* cpu sysinfo working pointer */
        kid_t new_kid = 0;                     /* kstat ID returned from chain update */
        int new_kstat = 0;                     /* flag indicating, if kstat structure has changed since last call */

        rv = APR_SUCCESS;

        if (sys_pagesize <= 0) {
            rv = apr_get_os_error();
        }
        else {
            ret_sysconf = sysconf(_SC_PHYS_PAGES);
            if (ret_sysconf >= 0) {
                pvals[0] = (jlong)((jlong)sys_pagesize * ret_sysconf);
            }
            else {
                rv = apr_get_os_error();
            }
            ret_sysconf = sysconf(_SC_AVPHYS_PAGES);
            if (ret_sysconf >= 0) {
                pvals[1] = (jlong)((jlong)sys_pagesize * ret_sysconf);
            }
            else {
                rv = apr_get_os_error();
            }
            res=swapctl(SC_AINFO, &info);
            if (res >= 0) {
                pvals[2] = (jlong)((jlong)sys_pagesize * info.ani_max);
                pvals[3] = (jlong)((jlong)sys_pagesize * info.ani_free);
                pvals[6] = (jlong)(100 - (jlong)info.ani_free * 100 / info.ani_max);
            }
            else {
                rv = apr_get_os_error();
            }
        }

        if (psinf_fd == 0) {
            psinf_fd = proc_open("psinfo");
        }
        res = proc_read(&psinf, PSINFO_T_SZ, psinf_fd);
        if (res >= 0) {
            new_rss = psinf.pr_rssize*1024;
            pvals[13] = (jlong)(new_rss);
            if (new_rss > rss) {
                rss = new_rss;
            }
            pvals[14] = (jlong)(rss);
        }
        else {
            psinf_fd = 0;
            rv = apr_get_os_error();
        }
        if (prusg_fd == 0) {
            prusg_fd = proc_open("usage");
        }
        res = proc_read(&prusg, PRUSAGE_T_SZ, prusg_fd);
        if (res >= 0) {
            if (creation <= 0) {
                time(&now);
                creation = (long)(now - (prusg.pr_tstamp.tv_sec -
                                         prusg.pr_create.tv_sec));
            }
            pvals[10] = (jlong)(creation);
            pvals[11] = (jlong)((jlong)prusg.pr_stime.tv_sec * 1000 +
                                (prusg.pr_stime.tv_nsec / 1000000));
            pvals[12] = (jlong)((jlong)prusg.pr_utime.tv_sec * 1000 +
                                (prusg.pr_utime.tv_nsec / 1000000));
            pvals[15] = (jlong)(prusg.pr_majf);
        }
        else {
            prusg_fd = 0;
            rv = apr_get_os_error();
        }

        if (sys_clk_tck <= 0) {
            rv = apr_get_os_error();
        }
        else {
            tck_dividend = 1000;
            tck_divisor = sys_clk_tck;
            for (i = 0; i < 3; i++) {
                if (tck_divisor % 2 == 0) {
                    tck_divisor = tck_divisor / 2;
                    tck_dividend = tck_dividend / 2;
                }
                if (tck_divisor % 5 == 0) {
                    tck_divisor = tck_divisor / 5;
                    tck_dividend = tck_dividend / 5;
                }
            }
            if (kstat_ctl == NULL) {
                kstat_ctl = kstat_open();
                kid = kstat_ctl->kc_chain_id;
                new_kstat = 1;
            } else {
                new_kid = kstat_chain_update(kstat_ctl);
                if (new_kid < 0) {
                    res=kstat_close(kstat_ctl);
                    kstat_ctl = kstat_open();
                    kid = kstat_ctl->kc_chain_id;
                    new_kstat = 1;
                } else if (new_kid > 0 && kid != new_kid) {
                    kid = new_kid;
                    new_kstat = 1;
                }
            }
            if (new_kstat) {
                cpu_count = 0;
                for (kstat = kstat_ctl->kc_chain; kstat; kstat = kstat->ks_next) {
                    if (strncmp(kstat->ks_name, "cpu_stat", 8) == 0) {
                        kstat_cpu[cpu_count++]=kstat;
                    }
                }
            }
            for (i = 0; i < cpu_count; i++) {
                new_kid = kstat_read(kstat_ctl, kstat_cpu[i], NULL);
                if (new_kid >= 0) {
                    cpu = ((cpu_stat_t *)kstat_cpu[i]->ks_data)->cpu_sysinfo;
                    if ( tck_divisor == 1 ) {
                        pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_IDLE]) * tck_dividend);
                        pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_WAIT]) * tck_dividend);
                        pvals[8] += (jlong)(((jlong)cpu.cpu[CPU_KERNEL]) * tck_dividend);
                        pvals[9] += (jlong)(((jlong)cpu.cpu[CPU_USER]) * tck_dividend);
                    } else {
                        pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_IDLE]) * tck_dividend / tck_divisor);
                        pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_WAIT]) * tck_dividend / tck_divisor);
                        pvals[8] += (jlong)(((jlong)cpu.cpu[CPU_KERNEL]) * tck_dividend / tck_divisor);
                        pvals[9] += (jlong)(((jlong)cpu.cpu[CPU_USER]) * tck_dividend / tck_divisor);
                    }
                }
            }
        }

        /*
         * The next two are not implemented yet for Solaris
         * inf[4]  - Amount of shared memory
         * inf[5]  - Memory used by buffers
         *
         */
    }

#elif defined(DARWIN)

    uint64_t mem_total;
    size_t len = sizeof(mem_total);

    vm_statistics_data_t vm_info;
    mach_msg_type_number_t info_count = HOST_VM_INFO_COUNT;

    sysctlbyname("hw.memsize", &mem_total, &len, NULL, 0);
    pvals[0] = (jlong)mem_total;

    host_statistics(mach_host_self (), HOST_VM_INFO, (host_info_t)&vm_info, &info_count);
    pvals[1] = (jlong)(((double)vm_info.free_count)*vm_page_size);
    pvals[6] = (jlong)(100 - (pvals[1] * 100 / mem_total));
    rv = APR_SUCCESS;

/* DARWIN */
#else
    rv = APR_ENOTIMPL;
#endif
   (*e)->ReleaseLongArrayElements(e, inf, pvals, 0);
    return rv;
}