Пример #1
0
/***** kill or nice a process */
static void hurt_proc(int tty, int uid, int pid, char *cmd){
  int failed;
  int saved_errno;
  char dn_buf[1000];
  dev_to_tty(dn_buf, 999, tty, pid, ABBREV_DEV);
  if(i_flag){
    char buf[8];
    fprintf(stderr, "%-8.8s %-8.8s %5d %-16.16s   ? ",
      (char*)dn_buf,user_from_uid(uid),pid,cmd
    );
    if(!fgets(buf,7,stdin)){
      printf("\n");
      exit(0);
    }
    if(*buf!='y' && *buf!='Y') return;
  }
  /* do the actual work */
  if(program==PROG_SKILL) failed=kill(pid,sig_or_pri);
  else                    failed=setpriority(PRIO_PROCESS,pid,sig_or_pri);
  saved_errno = errno;
  if(w_flag && failed){
    fprintf(stderr, "%-8.8s %-8.8s %5d %-16.16s   ",
      (char*)dn_buf,user_from_uid(uid),pid,cmd
    );
    errno = saved_errno;
    perror("");
    return;
  }
  if(i_flag) return;
  if(v_flag){
    printf("%-8.8s %-8.8s %5d %-16.16s\n",
      (char*)dn_buf,user_from_uid(uid),pid,cmd
    );
    return;
  }
  if(n_flag){
   printf("%d\n",pid);
   return;
  }
}
Пример #2
0
	/*
	 * Displays infos for a single task
	 */
void show_task_info(proc_t *task, int pmem)
{
    int i,j;
    unsigned int t;
    char *cmdptr;
    char tmp[2048], tmp2[2048] = "", tmp3[2048] = "", *p;

    for (i = 0; i < Numfields; i++) {
	tmp[0] = 0;
	switch (pflags[i]) {
	  case P_PID:
	    sprintf(tmp, "%5d ", task->pid);
	    break;
	  case P_PPID:
	    sprintf(tmp, "%5d ", task->ppid);
	    break;
	  case P_EUID:
	    sprintf(tmp, "%4d ", task->euid);
	    break;
	  case P_EUSER:
	    sprintf(tmp, "%-8.8s ", task->euser);
	    break;
	  case P_PCPU:
	    sprintf(tmp, "%4.1f ", (float)task->pcpu / 10);
	    break;
	  case P_LCPU:
	    sprintf(tmp, "%2d ", task->lproc);
	    break;
	  case P_PMEM:
	    sprintf(tmp, "%4.1f ", (float)pmem / 10);
	    break;
	  case P_TTY: {
	      char outbuf[9];
	      dev_to_tty(outbuf, 8, task->tty, task->pid, ABBREV_DEV);
	      sprintf(tmp, "%-8.8s ", outbuf);
	    }
	    break;
	  case P_PRI:
	    sprintf(tmp, "%3.3s ", scale_k(task->priority, 3, 0));
	    break;
	  case P_NICE:
	    sprintf(tmp, "%3.3s ", scale_k(task->nice, 3, 0));
	    break;
	  case P_PAGEIN:
	    sprintf(tmp, "%6.6s ", scale_k(task->maj_flt, 6, 0));
	    break;
	  case P_TSIZ:
	    sprintf(tmp, "%5.5s ",
		scale_k(((task->end_code - task->start_code) / 1024), 5, 1));
	    break;
	  case P_DSIZ:
	    sprintf(tmp, "%5.5s ",
		scale_k(((task->vsize - task->end_code) / 1024), 5, 1));
	    break;
	  case P_SIZE:
	    sprintf(tmp, "%5.5s ", scale_k((task->size << CL_pg_shift), 5, 1));
	    break;
	  case P_TRS:
	    sprintf(tmp, "%4.4s ", scale_k((task->trs << CL_pg_shift), 4, 1));
	    break;
	  case P_SWAP:
	    sprintf(tmp, "%4.4s ",
		scale_k(((task->size - task->resident) << CL_pg_shift), 4, 1));
	    break;
	  case P_SHARE:
	    sprintf(tmp, "%5.5s ", scale_k((task->share << CL_pg_shift), 5, 1));
	    break;
	  case P_A:
	    sprintf(tmp, "%3.3s ", "NYI");
	    break;
	  case P_WP:
	    sprintf(tmp, "%3.3s ", "NYI");
	    break;
	  case P_DT:
	    sprintf(tmp, "%3.3s ", scale_k(task->dt, 3, 0));
	    break;
	  case P_RSS:	/* resident not rss, it seems to be more correct. */
	    sprintf(tmp, "%4.4s ",
		scale_k((task->resident << CL_pg_shift), 4, 1));
	    break;
	  case P_WCHAN:
	    if (!CL_wchan_nout)
		sprintf(tmp, "%-9.9s ", wchan(task->wchan));
	    else
		sprintf(tmp, "%-9lx", task->wchan);
	    break;
	  case P_STAT:
	    sprintf(tmp, "%-4.4s ", status(task));
	    break;
	  case P_TIME:
	    t = (task->utime + task->stime) / Hertz;
	    if (Cumulative)
		t += (task->cutime + task->cstime) / Hertz;
	    sprintf(tmp, "%6.6s ", scale_time(t,6));
	    break;
	  case P_COMMAND:
	    if (!show_cmd && task->cmdline && *(task->cmdline)) {
	        j=0;
	        while(((task->cmdline)[j] != NULL) && (strlen(tmp3)<1020)){
/* #if 0 */ /* This is useless? FIXME */
		    if (j > 0)
			strcat(tmp3, " ");
/* #endif */
		    strncat(tmp3, (task->cmdline)[j], 1000);
		    j++; 
	        }
	        cmdptr = tmp3;
	    } else {
		cmdptr = task->cmd;
	    }
	    if (strlen(cmdptr) > Maxcmd)
		cmdptr[Maxcmd - 1] = 0;
	    sprintf(tmp, "%s", cmdptr);
	    tmp3[0]=0;
	    break;
	  case P_FLAGS:
	    sprintf(tmp, "%8lx ", task->flags);
	    break;
	}
	strcat(tmp2, tmp);
    }
    if (strlen(tmp2) > Cols - 1)
	tmp2[Cols - 1] = 0;

    /* take care of cases like:
       perl -e 'foo
          bar foo bar
          foo
          # end of perl script'
    */
    for (p=tmp2;*p;++p)
        if (!isgraph(*p))
            *p=' ';

    printf("\n%s", tmp2);
    PUTP(top_clrtoeol);
}
Пример #3
0
static int read_process(SEXP_t *cmd_ent, probe_ctx *ctx)
{
	int err = 1;
	DIR *d;
	struct dirent *ent;

	d = opendir("/proc");
	if (d == NULL)
		return err;

	// Get the time tick hertz
	ticks = (unsigned long)sysconf(_SC_CLK_TCK);
	get_boot_time();

	// Scan the directories
	while (( ent = readdir(d) )) {
		int fd, len;
		char buf[256];
		char *tmp, cmd[16], state, tty_dev[128];
		int pid, ppid, pgrp, session, tty_nr, tpgid;
		unsigned flags, sched_policy;
		unsigned long minflt, cminflt, majflt, cmajflt, uutime, ustime;
		long cutime, cstime, priority, cnice, nthreads, itrealvalue;
		unsigned long long start;
		SEXP_t *cmd_sexp;

		// Skip non-process dir entries
		if(*ent->d_name<'0' || *ent->d_name>'9')
			continue;
		errno = 0;
		pid = strtol(ent->d_name, NULL, 10);
		if (errno || pid == 2) // skip err & kthreads
			continue;

		// Parse up the stat file for the proc
		snprintf(buf, 32, "/proc/%d/stat", pid);
		fd = open(buf, O_RDONLY, 0);
		if (fd < 0)
			continue;
		len = read(fd, buf, sizeof buf - 1);
		close(fd);
		if (len < 40)
			continue;
		buf[len] = 0;
		tmp = strrchr(buf, ')');
		if (tmp)
			*tmp = 0;
		else
			continue;
		memset(cmd, 0, sizeof(cmd));
		sscanf(buf, "%d (%15c", &ppid, cmd);
		sscanf(tmp+2,	"%c %d %d %d %d %d "
				"%u %lu %lu %lu %lu "
				"%lu %lu %lu %ld %ld "
				"%ld %ld %ld %llu",
			&state, &ppid, &pgrp, &session, &tty_nr, &tpgid,
			&flags, &minflt, &cminflt, &majflt, &cmajflt,
			&uutime, &ustime, &cutime, &cstime, &priority,
			&cnice, &nthreads, &itrealvalue, &start
		);

		// Skip kthreads
		if (ppid == 2)
			continue;

		err = 0; // If we get this far, no permission problems
		dI("Have command: %s\n", cmd);
		cmd_sexp = SEXP_string_newf("%s", cmd);
		if (probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) {
			struct result_info r;
			unsigned long t = uutime/ticks + ustime/ticks;
			char tbuf[32], sbuf[32];
			int tday,tyear;
			time_t s_time;
			struct tm *proc, *now;
			const char *fmt;

			// Now get scheduler policy
			sched_policy = sched_getscheduler(pid);
			switch (sched_policy) {
				case SCHED_OTHER:
					r.scheduling_class = "TS";
					break;
				case SCHED_BATCH:
					r.scheduling_class = "B";
					break;
#ifdef SCHED_IDLE
				case SCHED_IDLE:
					r.scheduling_class = "#5";
					break;
#endif
				case SCHED_FIFO:
					r.scheduling_class = "FF";
					break;
				case SCHED_RR:
					r.scheduling_class = "RR";
					break;
				default:
					r.scheduling_class = "?";
					break;
			}

			// Calculate the start time
			s_time = time(NULL);
			now = localtime(&s_time);
			tyear = now->tm_year;
			tday = now->tm_yday;
			s_time = boot + (start / ticks);
			proc = localtime(&s_time);

			// Select format based on how long we've been running
			//
			// FROM THE SPEC:
			// "This is the time of day the process started formatted in HH:MM:SS if
			// the same day the process started or formatted as MMM_DD (Ex.: Feb_5)
			// if process started the previous day or further in the past."
			//
			if (tday != proc->tm_yday || tyear != proc->tm_year)
				fmt = "%b_%d";
			else
				fmt = "%H:%M:%S";
			strftime(sbuf, sizeof(sbuf), fmt, proc);

			r.command = cmd;
			r.exec_time = convert_time(t, tbuf, sizeof(tbuf));
			r.pid = pid;
			r.ppid = ppid;
			r.priority = priority;
			r.start_time = sbuf;

                        dev_to_tty(tty_dev, sizeof(tty_dev), (dev_t) tty_nr, pid, ABBREV_DEV);
                        r.tty = tty_dev;

			get_uids(pid, &r);
			report_finding(&r, ctx);
		}
		SEXP_free(cmd_sexp);
	}
        closedir(d);

	return err;
}
Пример #4
0
static int read_process(SEXP_t *cmd_ent, SEXP_t *pid_ent, probe_ctx *ctx)
{
	int err = 1, max_cap_id;
	DIR *d;
	struct dirent *ent;
	oval_version_t oval_version;

	d = opendir("/proc");
	if (d == NULL)
		return err;

	// Get the time tick hertz
	ticks = (unsigned long)sysconf(_SC_CLK_TCK);
	get_boot_time();

	oval_version = probe_obj_get_schema_version(probe_ctx_getobject(ctx));
	if (oval_version_cmp(oval_version, OVAL_VERSION(5.11)) < 0) {
		max_cap_id = OVAL_5_8_MAX_CAP_ID;
	} else {
		max_cap_id = OVAL_5_11_MAX_CAP_ID;
	}

	struct oscap_buffer *cmdline_buffer = oscap_buffer_new();
	
	char cmd_buffer[1 + 15 + 11 + 1]; // Format:" [ cmd:15 ] <defunc>"
	cmd_buffer[0] = '[';

	// Scan the directories
	while (( ent = readdir(d) )) {
		int fd, len;
		char buf[256];
		char *tmp, state, tty_dev[128];
		int pid, ppid, pgrp, session, tty_nr, tpgid;
		unsigned flags, sched_policy;
		unsigned long minflt, cminflt, majflt, cmajflt, uutime, ustime;
		long cutime, cstime, priority, cnice, nthreads, itrealvalue;
		unsigned long long start;
		SEXP_t *cmd_sexp = NULL, *pid_sexp = NULL;

		// Skip non-process58 dir entries
		if(*ent->d_name<'0' || *ent->d_name>'9')
			continue;
		errno = 0;
		pid = strtol(ent->d_name, NULL, 10);
		if (errno || pid == 2) // skip err & kthreads
			continue;

		// Parse up the stat file for the proc
		snprintf(buf, 32, "/proc/%d/stat", pid);
		fd = open(buf, O_RDONLY, 0);
		if (fd < 0)
			continue;
		len = read(fd, buf, sizeof buf - 1);
		close(fd);
		if (len < 40)
			continue;
		buf[len] = 0;
		tmp = strrchr(buf, ')');
		if (tmp)
			*tmp = 0;
		else
			continue;
		memset(cmd_buffer + 1, 0, sizeof(cmd_buffer)-1); // clear cmd after starting '['
		sscanf(buf, "%d (%15c", &ppid, cmd_buffer + 1);
		sscanf(tmp+2,	"%c %d %d %d %d %d "
				"%u %lu %lu %lu %lu "
				"%lu %lu %lu %ld %ld "
				"%ld %ld %ld %llu",
			&state, &ppid, &pgrp, &session, &tty_nr, &tpgid,
			&flags, &minflt, &cminflt, &majflt, &cmajflt,
			&uutime, &ustime, &cutime, &cstime, &priority,
			&cnice, &nthreads, &itrealvalue, &start
		);

		// Skip kthreads
		if (ppid == 2)
			continue;

		const char* cmd;
		if (state == 'Z') { // zombie
			cmd = make_defunc_str(cmd_buffer);
		} else {
			snprintf(buf, 32, "/proc/%d/cmdline", pid);
			if (get_process_cmdline(buf, cmdline_buffer)) {
				cmd = oscap_buffer_get_raw(cmdline_buffer); // use full cmdline
			} else {
				cmd = cmd_buffer + 1;
			}
		}


		err = 0; // If we get this far, no permission problems
		dI("Have command: %s\n", cmd);
		cmd_sexp = SEXP_string_newf("%s", cmd);
		pid_sexp = SEXP_number_newu_32(pid);
		if ((cmd_sexp == NULL || probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) &&
		    (pid_sexp == NULL || probe_entobj_cmp(pid_ent, pid_sexp) == OVAL_RESULT_TRUE)
		) {
			struct result_info r;
			unsigned long t = uutime/ticks + ustime/ticks;
			char tbuf[32], sbuf[32], *selinux_domain_label, **posix_capabilities;
			int tday,tyear;
			time_t s_time;
			struct tm *proc, *now;
			const char *fmt;

			// Now get scheduler policy
			sched_policy = sched_getscheduler(pid);
			switch (sched_policy) {
				case SCHED_OTHER:
					r.scheduling_class = "TS";
					break;
				case SCHED_BATCH:
					r.scheduling_class = "B";
					break;
#ifdef SCHED_IDLE
				case SCHED_IDLE:
					r.scheduling_class = "#5";
					break;
#endif
				case SCHED_FIFO:
					r.scheduling_class = "FF";
					break;
				case SCHED_RR:
					r.scheduling_class = "RR";
					break;
				default:
					r.scheduling_class = "?";
					break;
			}

			// Calculate the start time
			s_time = time(NULL);
			now = localtime(&s_time);
			tyear = now->tm_year;
			tday = now->tm_yday;
			s_time = boot + (start / ticks);
			proc = localtime(&s_time);

			// Select format based on how long we've been running
			//
			// FROM THE SPEC:
			// "This is the time of day the process started formatted in HH:MM:SS if
			// the same day the process started or formatted as MMM_DD (Ex.: Feb_5)
			// if process started the previous day or further in the past."
			//
			if (tday != proc->tm_yday || tyear != proc->tm_year)
				fmt = "%b_%d";
			else
				fmt = "%H:%M:%S";
			strftime(sbuf, sizeof(sbuf), fmt, proc);

			r.command_line = cmd;
			r.exec_time = convert_time(t, tbuf, sizeof(tbuf));
			r.pid = pid;
			r.ppid = ppid;
			r.priority = priority;
			r.start_time = sbuf;

			dev_to_tty(tty_dev, sizeof(tty_dev), (dev_t) tty_nr, pid, ABBREV_DEV);
			r.tty = tty_dev;

			r.exec_shield = (get_exec_shield_status(pid) > 0);

			selinux_domain_label = get_selinux_label(pid);
			r.selinux_domain_label = selinux_domain_label;

			posix_capabilities = get_posix_capability(pid, max_cap_id);
			r.posix_capability = posix_capabilities;

			r.session_id = session;

			get_uids(pid, &r);
			report_finding(&r, ctx);

			if (selinux_domain_label != NULL)
				free(selinux_domain_label);

			if (posix_capabilities != NULL) {
				char **posix_capabilities_p = posix_capabilities;
				while (*posix_capabilities_p)
					free(*posix_capabilities_p++);
				free(posix_capabilities);
			}
		}
		SEXP_free(cmd_sexp);
		SEXP_free(pid_sexp);
	}
        closedir(d);
	oscap_buffer_free(cmdline_buffer);
	return err;
}