Ejemplo n.º 1
0
static bool selinux_action_allowed(int s, pid_t tid, debugger_action_t action)
{
  char *scon = NULL, *tcon = NULL;
  const char *tclass = "debuggerd";
  const char *perm;
  bool allowed = false;

  if (selinux_enabled <= 0)
    return true;

  if (action <= 0 || action >= (sizeof(debuggerd_perms)/sizeof(debuggerd_perms[0]))) {
    ALOGE("SELinux:  No permission defined for debugger action %d", action);
    return false;
  }

  perm = debuggerd_perms[action];

  if (getpeercon(s, &scon) < 0) {
    ALOGE("Cannot get peer context from socket\n");
    goto out;
  }

  if (getpidcon(tid, &tcon) < 0) {
    ALOGE("Cannot get context for tid %d\n", tid);
    goto out;
  }

  allowed = (selinux_check_access(scon, tcon, tclass, perm, NULL) == 0);

out:
   freecon(scon);
   freecon(tcon);
   return allowed;
}
Ejemplo n.º 2
0
static int
SELinuxGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
                               virDomainObjPtr vm,
                               virSecurityLabelPtr sec)
{
    security_context_t ctx;

    if (getpidcon(vm->pid, &ctx) == -1) {
        virReportSystemError(errno,
                             _("unable to get PID %d security context"),
                             vm->pid);
        return -1;
    }

    if (strlen((char *) ctx) >= VIR_SECURITY_LABEL_BUFLEN) {
        virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
                               _("security label exceeds "
                                 "maximum length: %d"),
                               VIR_SECURITY_LABEL_BUFLEN - 1);
        freecon(ctx);
        return -1;
    }

    strcpy(sec->label, (char *) ctx);
    freecon(ctx);

    sec->enforcing = security_getenforce();
    if (sec->enforcing == -1) {
        virReportSystemError(errno, "%s",
                             _("error calling security_getenforce()"));
        return -1;
    }

    return 0;
}
  /*
   * Function: getPidCon
   * Purpose: Get the context of a process identified by its pid
   * Parameters:
   *            pid: a jint representing the process
   * Returns: a jstring representing the security context of the pid,
   *          the jstring may be NULL if there was an error
   * Exceptions: none
   */
  static jstring getPidCon(JNIEnv *env, jobject clazz, jint pid) {
#ifdef HAVE_SELINUX
    if (isSELinuxDisabled)
      return NULL;

    security_context_t context = NULL;
    jstring securityString = NULL;

    pid_t checkPid = (pid_t)pid;

    if (getpidcon(checkPid, &context) == -1)
      goto bail;

    ALOGV("getPidCon: Successfully retrived context '%s' for pid '%d'", context, checkPid);

    securityString = env->NewStringUTF(context);

  bail:
    if (context != NULL)
      freecon(context);

    return securityString;
#else
    return NULL;
#endif
  }
Ejemplo n.º 4
0
int main(int argc, char **argv)
{
	pid_t pid;
	char *buf;
	int rc;

	if (argc != 2) {
		fprintf(stderr, "usage:  %s pid\n", argv[0]);
		exit(1);
	}

	if (sscanf(argv[1], "%d", &pid) != 1) {
		fprintf(stderr, "%s:  invalid pid %s\n", argv[0], argv[1]);
		exit(2);
	}

	rc = getpidcon(pid, &buf);
	if (rc < 0) {
		fprintf(stderr, "%s:  getpidcon() failed\n", argv[0]);
		exit(3);
	}

	printf("%s\n", buf);
	freecon(buf);
	exit(EXIT_SUCCESS);
}
Ejemplo n.º 5
0
static bool selinux_action_allowed(int s, debugger_request_t* request)
{
  char *scon = NULL, *tcon = NULL;
  const char *tclass = "debuggerd";
  const char *perm;
  bool allowed = false;

  if (request->action <= 0 || request->action >= (sizeof(debuggerd_perms)/sizeof(debuggerd_perms[0]))) {
    ALOGE("SELinux:  No permission defined for debugger action %d", request->action);
    return false;
  }

  perm = debuggerd_perms[request->action];

  if (getpeercon(s, &scon) < 0) {
    ALOGE("Cannot get peer context from socket\n");
    goto out;
  }

  if (getpidcon(request->tid, &tcon) < 0) {
    ALOGE("Cannot get context for tid %d\n", request->tid);
    goto out;
  }

  allowed = (selinux_check_access(scon, tcon, tclass, perm, reinterpret_cast<void*>(request)) == 0);

out:
   freecon(scon);
   freecon(tcon);
   return allowed;
}
/*
 * Function: getPidCon
 * Purpose: Get the context of a process identified by its pid
 * Parameters:
 *            pid: a jint representing the process
 * Returns: a jstring representing the security context of the pid,
 *          the jstring may be NULL if there was an error
 * Exceptions: none
 */
static jstring getPidCon(JNIEnv *env, jobject, jint pid) {
    if (isSELinuxDisabled) {
        return NULL;
    }

    security_context_t tmp = NULL;
    int ret = getpidcon(static_cast<pid_t>(pid), &tmp);
    Unique_SecurityContext context(tmp);

    ScopedLocalRef<jstring> securityString(env, NULL);
    if (ret != -1) {
        securityString.reset(env->NewStringUTF(context.get()));
    }

    ALOGV("getPidCon(%d) => %s", pid, context.get());
    return securityString.release();
}
Ejemplo n.º 7
0
	{
		setbank(m_bg1_tilemap, 0, (data & 0x07));
		setbank(m_bg2_tilemap, 1, (data & 0x38) >> 3);
	}
}

WRITE16_MEMBER(aerofgt_state::turbofrc_gfxbank_w)
{
	tilemap_t *tmap = (offset == 0) ? m_bg1_tilemap : m_bg2_tilemap;

	data = COMBINE_DATA(&m_bank[offset]);

	setbank(tmap, 4 * offset + 0, (data >> 0) & 0x0f);
	setbank(tmap, 4 * offset + 1, (data >> 4) & 0x0f);
	setbank(tmap, 4 * offset + 2, (data >> 8) & 0x0f);
	setbank(tmap, 4 * offset + 3, (data >> 12) & 0x0f);
}

WRITE16_MEMBER(aerofgt_state::aerofgt_gfxbank_w)
{
	tilemap_t *tmap = (offset < 2) ? m_bg1_tilemap : m_bg2_tilemap;

	data = COMBINE_DATA(&m_bank[offset]);

	setbank(tmap, 2 * offset + 0, (data >> 8) & 0xff);
	setbank(tmap, 2 * offset + 1, (data >> 0) & 0xff);
static bool check_mac_perms(pid_t spid, const char *tctx, const char *perm, const char *name)
{
    char *sctx = NULL;
    const char *class = "service_manager";
    bool allowed;

    if (getpidcon(spid, &sctx) < 0) {
        ALOGE("SELinux: getpidcon(pid=%d) failed to retrieve pid context.\n", spid);
        return false;
    }

    int result = selinux_check_access(sctx, tctx, class, perm, (void *) name);
    allowed = (result == 0);

    freecon(sctx);
    return allowed;
}
Ejemplo n.º 9
0
static char *get_selinux_label(int pid) {
#ifdef HAVE_SELINUX_SELINUX_H
	char *selinux_label;
	security_context_t pid_context;
	context_t context;

	if (getpidcon(pid, &pid_context) == -1) {
		/* error getting pid selinux context */
		dW("Can't get selinux context for process %d\n", pid);
		return NULL;
	}
	context = context_new(pid_context);
	selinux_label = strdup(context_type_get(context));
	context_free(context);
	freecon(pid_context);
	return selinux_label;

#else
	return NULL;
#endif /* HAVE_SELINUX_SELINUX_H */
}
Ejemplo n.º 10
0
static int
SELinuxReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
                            virDomainDefPtr def,
                            pid_t pid)
{
    security_context_t pctx;
    context_t ctx = NULL;
    const char *mcs;

    if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
        return 0;

    if (getpidcon(pid, &pctx) == -1) {
        virReportSystemError(errno,
                             _("unable to get PID %d security context"), pid);
        return -1;
    }

    ctx = context_new(pctx);
    freecon(pctx);
    if (!ctx)
        goto err;

    mcs = context_range_get(ctx);
    if (!mcs)
        goto err;

    mcsAdd(mcs);

    context_free(ctx);

    return 0;

err:
    context_free(ctx);
    return -1;
}
Ejemplo n.º 11
0
int main(int argc, char **argv)
{
	/* these vars are reused several times */
	int rc, opt, i, c;
	char *context, *root_path;

	/* files that need context checks */
	char *fc[MAX_CHECK];
	char *cterm = ttyname(0);
	int nfc = 0;
	struct stat m;

	/* processes that need context checks */
	char *pc[MAX_CHECK];
	int npc = 0;

	/* booleans */
	char **bools;
	int nbool;

	int verbose = 0;
	int show_bools = 0;

	/* policy */
	const char *pol_name, *root_dir;
	char *pol_path;


	while (1) {
		opt = getopt(argc, argv, "vb");
		if (opt == -1)
			break;
		switch (opt) {
		case 'v':
			verbose = 1;
			break;
		case 'b':
			show_bools = 1;
			break;
		default:
			/* invalid option */
			printf("\nUsage: %s [OPTION]\n\n", basename(argv[0]));
			printf("  -v  Verbose check of process and file contexts.\n");
			printf("  -b  Display current state of booleans.\n");
			printf("\nWithout options, show SELinux status.\n");
			return -1;
		}
	}
	printf_tab("SELinux status:");
	rc = is_selinux_enabled();

	switch (rc) {
	case 1:
		printf("enabled\n");
		break;
	case 0:
		printf("disabled\n");
		return 0;
		break;
	default:
		printf("unknown (%s)\n", strerror(errno));
		return 0;
		break;
	}

	printf_tab("SELinuxfs mount:");
	if (selinux_mnt != NULL) {
		printf("%s\n", selinux_mnt);
	} else {
		printf("not mounted\n\n");
		printf("Please mount selinuxfs for proper results.\n");
		return -1;
	}

	printf_tab("SELinux root directory:");
	root_dir = selinux_path();
	if (root_dir == NULL) {
		printf("error (%s)\n", strerror(errno));
		return -1;
	}
	/* The path has a trailing '/' so duplicate to edit */
	root_path = strdup(root_dir);
	if (!root_path) {
		printf("malloc error (%s)\n", strerror(errno));
		return -1;
	}
	/* actually blank the '/' */
	root_path[strlen(root_path) - 1] = '\0';
	printf("%s\n", root_path);
	free(root_path);

	/* Dump all the path information */
	printf_tab("Loaded policy name:");
	pol_path = strdup(selinux_policy_root());
	if (pol_path) {
		pol_name = basename(pol_path);
		puts(pol_name);
		free(pol_path);
	} else {
		printf("error (%s)\n", strerror(errno));
	}

	printf_tab("Current mode:");
	rc = security_getenforce();
	switch (rc) {
	case 1:
		printf("enforcing\n");
		break;
	case 0:
		printf("permissive\n");
		break;
	default:
		printf("unknown (%s)\n", strerror(errno));
		break;
	}

	printf_tab("Mode from config file:");
	if (selinux_getenforcemode(&rc) == 0) {
		switch (rc) {
		case 1:
			printf("enforcing\n");
			break;
		case 0:
			printf("permissive\n");
			break;
		case -1:
			printf("disabled\n");
			break;
		}
	} else {
		printf("error (%s)\n", strerror(errno));
	}

	printf_tab("Policy MLS status:");
	rc = is_selinux_mls_enabled();
	switch (rc) {
		case 0:
			printf("disabled\n");
			break;
		case 1:
			printf("enabled\n");
			break;
		default:
			printf("error (%s)\n", strerror(errno));
			break;
	}

	printf_tab("Policy deny_unknown status:");
	rc = security_deny_unknown();
	switch (rc) {
		case 0:
			printf("allowed\n");
			break;
		case 1:
			printf("denied\n");
			break;
		default:
			printf("error (%s)\n", strerror(errno));
			break;
	}

	rc = security_policyvers();
	printf_tab("Max kernel policy version:");
	if (rc < 0)
		printf("unknown (%s)\n", strerror(errno));
	else
		printf("%d\n", rc);


	if (show_bools) {
		/* show booleans */
		if (security_get_boolean_names(&bools, &nbool) >= 0) {
			printf("\nPolicy booleans:\n");

			for (i = 0; i < nbool; i++) {
				if (strlen(bools[i]) + 1 > COL)
					COL = strlen(bools[i]) + 1;
			}
			for (i = 0; i < nbool; i++) {
				printf_tab(bools[i]);

				rc = security_get_boolean_active(bools[i]);
				switch (rc) {
				case 1:
					printf("on");
					break;
				case 0:
					printf("off");
					break;
				default:
					printf("unknown (%s)", strerror(errno));
					break;
				}
				c = security_get_boolean_pending(bools[i]);
				if (c != rc)
					switch (c) {
					case 1:
						printf(" (activate pending)");
						break;
					case 0:
						printf(" (inactivate pending)");
						break;
					default:
						printf(" (pending error: %s)",
						       strerror(errno));
						break;
					}
				printf("\n");

				/* free up the booleans */
				free(bools[i]);
			}
			free(bools);
		}
	}
	/* only show contexts if -v is given */
	if (!verbose)
		return 0;

	load_checks(pc, &npc, fc, &nfc);

	printf("\nProcess contexts:\n");

	printf_tab("Current context:");
	if (getcon(&context) >= 0) {
		printf("%s\n", context);
		freecon(context);
	} else
		printf("unknown (%s)\n", strerror(errno));

	printf_tab("Init context:");
	if (getpidcon(1, &context) >= 0) {
		printf("%s\n", context);
		freecon(context);
	} else
		printf("unknown (%s)\n", strerror(errno));

	for (i = 0; i < npc; i++) {
		rc = pidof(pc[i]);
		if (rc > 0) {
			if (getpidcon(rc, &context) < 0)
				continue;

			printf_tab(pc[i]);
			printf("%s\n", context);
			freecon(context);
		}
	}

	printf("\nFile contexts:\n");

	/* controlling term */
	printf_tab("Controlling terminal:");
	if (lgetfilecon(cterm, &context) >= 0) {
		printf("%s\n", context);
		freecon(context);
	} else {
		printf("unknown (%s)\n", strerror(errno));
	}

	for (i = 0; i < nfc; i++) {
		if (lgetfilecon(fc[i], &context) >= 0) {
			printf_tab(fc[i]);

			/* check if this is a symlink */
			if (lstat(fc[i], &m)) {
				printf
				    ("%s (could not check link status (%s)!)\n",
				     context, strerror(errno));
				freecon(context);
				continue;
			}
			if (S_ISLNK(m.st_mode)) {
				/* print link target context */
				printf("%s -> ", context);
				freecon(context);

				if (getfilecon(fc[i], &context) >= 0) {
					printf("%s\n", context);
					freecon(context);
				} else {
					printf("unknown (%s)\n",
					       strerror(errno));
				}
			} else {
				printf("%s\n", context);
				freecon(context);
			}
		}
	}

	return 0;
}
Ejemplo n.º 12
0
int main(int argc, char **argv)
{
	int pid, rc, len, status;
	security_context_t context_s;
	context_t context;

	if (argc != 3) {
		fprintf(stderr, "usage:  %s newdomain program\n", argv[0]);
		exit(-1);
	}

	rc = getcon(&context_s);
	if (rc < 0) {
		fprintf(stderr, "%s:  unable to get my context\n", argv[0]);
		exit(-1);

	}

	context = context_new(context_s);
	if (!context) {
		fprintf(stderr, "%s:  unable to create context structure\n", argv[0]);
		exit(-1);
	}

	if (context_type_set(context, argv[1])) {
		fprintf(stderr, "%s:  unable to set new type\n", argv[0]);
		exit(-1);
	}

	freecon(context_s);
	context_s = context_str(context);
	if (!context_s) {
		fprintf(stderr, "%s:  unable to obtain new context string\n", argv[0]);
		exit(-1);
	}

	rc = setexeccon(context_s);
	if (rc < 0) {
		fprintf(stderr, "%s:  unable to set exec context to %s\n", argv[0], context_s);
		exit(-1);
	}

	pid = fork();
	if (pid < 0) {
		perror("fork");
		exit(-1);
	} else if (pid == 0) {
		signal(SIGTRAP, SIG_IGN);
		rc =  ptrace(PTRACE_TRACEME, 0, 0, 0);
		if (rc < 0) {
			perror("ptrace: PTRACE_TRACEME");
			exit(-1);
		}
		execv(argv[2], argv+2);
		perror(argv[2]);
		exit(1);
	}

repeat:
	pid = wait(&status);
	if (pid < 0) {
		perror("wait");
		exit(-1);
	}

	if (WIFEXITED(status)) {
		fprintf(stderr, "Child exited with status %d.\n", WEXITSTATUS(status));
		exit(WEXITSTATUS(status));
	}

	if (WIFSTOPPED(status)) {
		fprintf(stderr, "Child stopped by signal %d.\n", WSTOPSIG(status));
		rc = getpidcon(pid, &context_s);
		if (rc < 0) {
			perror("getpidcon");
			exit(-1);
		}
		fprintf(stderr, "Child has context %s\n", context_s);
		fprintf(stderr, "..Resuming the child.\n");
		rc = ptrace(PTRACE_CONT,pid,0,0);
		if (rc < 0){
			perror("ptrace: PTRACE_CONT");
			exit(-1);
		}
		goto repeat;
	}

	if (WIFSIGNALED(status)) {
		fprintf(stderr, "Child terminated by signal %d.\n", WTERMSIG(status));
		fprintf(stderr, "..This is consistent with a ptrace permission denial - check the audit message.\n");
		exit(1);
	}

	fprintf(stderr, "Unexpected exit status 0x%x\n", status);
	exit(-1);
}
static void display_verbose(void)
{
	security_context_t con, _con;
	char *fc[50], *pc[50], *cterm;
	pid_t *pidList;
	int i;

	read_config(pc, ARRAY_SIZE(pc), fc, ARRAY_SIZE(fc));

	/* process contexts */
	puts("\nProcess contexts:");

	/* current context */
	if (getcon(&con) == 0) {
		printf(COL_FMT "%s\n", "Current context:", con);
		if (ENABLE_FEATURE_CLEAN_UP)
			freecon(con);
	}
	/* /sbin/init context */
	if (getpidcon(1, &con) == 0) {
		printf(COL_FMT "%s\n", "Init context:", con);
		if (ENABLE_FEATURE_CLEAN_UP)
			freecon(con);
	}

	/* [process] context */
	for (i = 0; pc[i] != NULL; i++) {
		pidList = find_pid_by_name(bb_basename(pc[i]));
		if (pidList[0] > 0 && getpidcon(pidList[0], &con) == 0) {
			printf(COL_FMT "%s\n", pc[i], con);
			if (ENABLE_FEATURE_CLEAN_UP)
				freecon(con);
		}
		if (ENABLE_FEATURE_CLEAN_UP)
			free(pidList);
	}

	/* files contexts */
	puts("\nFile contexts:");

	cterm = ttyname(0);
	puts(cterm);
	if (cterm && lgetfilecon(cterm, &con) >= 0) {
		printf(COL_FMT "%s\n", "Controlling term:", con);
		if (ENABLE_FEATURE_CLEAN_UP)
			freecon(con);
	}

	for (i=0; fc[i] != NULL; i++) {
		struct stat stbuf;

		if (lgetfilecon(fc[i], &con) < 0)
			continue;
		if (lstat(fc[i], &stbuf) == 0) {
			if (S_ISLNK(stbuf.st_mode)) {
				if (getfilecon(fc[i], &_con) >= 0) {
					printf(COL_FMT "%s -> %s\n", fc[i], _con, con);
					if (ENABLE_FEATURE_CLEAN_UP)
						freecon(_con);
				}
			} else {
				printf(COL_FMT "%s\n", fc[i], con);
			}
		}
		if (ENABLE_FEATURE_CLEAN_UP)
			freecon(con);
	}
}
Ejemplo n.º 14
0
/* returns requested time interval in seconds, 
 negative indicates error has occurred
 */
static long
parse_time_units(const char* age)
{
   char *unit;
   long num;

   num = strtol(age,&unit,10);
   if (age == unit) /* no digits found */
     return -1;
   if (unit[0] == '\0') /* no units found */
     return -1;

   switch(unit[0]) {
   case 's':
     return num;
   case 'm':
     return (num * 60);
   case 'h':
     return (num * 60 * 60);
   case 'd':
     return (num * 60 * 60 * 24);
   case 'w':
     return (num * 60 * 60 * 24 * 7);
   case 'M':
     return (num * 60 * 60 * 24 * 7 * 4);
   case 'y':
     return (num * 60 * 60 * 24 * 7 * 4 * 12);
   }
   return -1;
}

static int
match_process_uid(pid_t pid, uid_t uid)
{
	char buf[128];
	uid_t puid;
	FILE *f;
	int re = -1;
	
	snprintf (buf, sizeof buf, PROC_BASE "/%d/status", pid);
	if (!(f = fopen (buf, "r")))
		return 0;
	
	while (fgets(buf, sizeof buf, f))
	{
		if (sscanf (buf, "Uid:\t%d", &puid))
		{
			re = uid==puid;
			break;
		}
	}
	fclose(f);
	if (re==-1)
	{
		fprintf(stderr, _("killall: Cannot get UID from process status\n"));
		exit(1);
	}
	return re;
}

static regex_t *
build_regexp_list(int names, char **namelist)
{
	int i;
	regex_t *reglist;
	int flag = REG_EXTENDED|REG_NOSUB;
	
	if (!(reglist = malloc (sizeof (regex_t) * names)))
	{
		perror ("malloc");
		exit (1);
	}

	if (ignore_case)
		flag |= REG_ICASE;
	
	for (i = 0; i < names; i++)
	{
		if (regcomp(&reglist[i], namelist[i], flag) != 0) 
		{
			fprintf(stderr, _("killall: Bad regular expression: %s\n"), namelist[i]);
			exit (1);
		}
	}
	return reglist;
}

#ifdef WITH_SELINUX
static int
kill_all(int signal, int names, char **namelist, struct passwd *pwent, 
					regex_t *scontext )
#else  /*WITH_SELINUX*/
static int
kill_all (int signal, int names, char **namelist, struct passwd *pwent)
#endif /*WITH_SELINUX*/
{
  DIR *dir;
  struct dirent *de;
  FILE *file;
  struct stat st, sts[MAX_NAMES];
  int *name_len = NULL;
  char *path, comm[COMM_LEN];
  char *command_buf;
  char *command;
  pid_t *pid_table, pid, self, *pid_killed;
  pid_t *pgids;
  int i, j, okay, length, got_long, error;
  int pids, max_pids, pids_killed;
  unsigned long found;
  regex_t *reglist = NULL;;
#ifdef WITH_SELINUX
  security_context_t lcontext=NULL;
#endif /*WITH_SELINUX*/

  if (names && reg) 
      reglist = build_regexp_list(names, namelist);
  else if (names)
   {
      if (!(name_len = malloc (sizeof (int) * names)))
        {
          perror ("malloc");
          exit (1);
        }
      for (i = 0; i < names; i++) 
        {
          if (!strchr (namelist[i], '/'))
            {
	      sts[i].st_dev = 0;
	      name_len[i] = strlen (namelist[i]);
            }
          else if (stat (namelist[i], &sts[i]) < 0)
            {
	      perror (namelist[i]);
	      exit (1);
            }
        }
    } 
  self = getpid ();
  found = 0;
  if (!(dir = opendir (PROC_BASE)))
    {
      perror (PROC_BASE);
      exit (1);
    }
  max_pids = 256;
  pid_table = malloc (max_pids * sizeof (pid_t));
  if (!pid_table)
    {
      perror ("malloc");
      exit (1);
    }
  pids = 0;
  while ( (de = readdir (dir)) != NULL)
    {
      if (!(pid = (pid_t) atoi (de->d_name)) || pid == self)
	continue;
      if (pids == max_pids)
	{
	  if (!(pid_table = realloc (pid_table, 2 * pids * sizeof (pid_t))))
	    {
	      perror ("realloc");
	      exit (1);
	    }
	  max_pids *= 2;
	}
      pid_table[pids++] = pid;
    }
  (void) closedir (dir);
  pids_killed = 0;
  pid_killed = malloc (max_pids * sizeof (pid_t));
  if (!pid_killed)
    {
      perror ("malloc");
      exit (1);
    }
  if (!process_group)
    pgids = NULL;		/* silence gcc */
  else
    {
      pgids = calloc (pids, sizeof (pid_t));
      if (!pgids)
	{
	  perror ("malloc");
	  exit (1);
	}
    }
  for (i = 0; i < pids; i++)
    {
      pid_t id;
      int found_name = -1;
      double process_age_sec = 0;
      /* match by UID */
      if (pwent && match_process_uid(pid_table[i], pwent->pw_uid)==0)
	continue;
#ifdef WITH_SELINUX
      /* match by SELinux context */
      if (scontext) 
        {
          if (getpidcon(pid_table[i], &lcontext) < 0)
            continue;
	  if (regexec(scontext, lcontext, 0, NULL, 0) != 0) {
            freecon(lcontext);
            continue;
          }
          freecon(lcontext);
        }
#endif /*WITH_SELINUX*/
      /* load process name */
      if (asprintf (&path, PROC_BASE "/%d/stat", pid_table[i]) < 0)
	continue;
      if (!(file = fopen (path, "r"))) 
	{
	  free (path);
	  continue;
	}
      free (path);
      okay = fscanf (file, "%*d (%15[^)]", comm) == 1;
      if (!okay) {
	fclose(file);
	continue;
      }
      if ( younger_than || older_than ) {
	 rewind(file);
	 unsigned long long proc_stt_jf = 0;
	 okay = fscanf(file, "%*d %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %Lu", 
		       &proc_stt_jf) == 1;
	 if (!okay) {
	    fclose(file);
	    continue;
	 }
	 process_age_sec = process_age(proc_stt_jf);
      }
      (void) fclose (file);
       
      got_long = 0;
      command = NULL;		/* make gcc happy */
      length = strlen (comm);
      if (length == COMM_LEN - 1)
	{
	  if (asprintf (&path, PROC_BASE "/%d/cmdline", pid_table[i]) < 0)
	    continue;
	  if (!(file = fopen (path, "r"))) {
	    free (path);
	    continue;
	  }
	  free (path);
          while (1) {
            /* look for actual command so we skip over initial "sh" if any */
            char *p;
	    int cmd_size = 128;
	    command_buf = (char *)malloc (cmd_size);
	    if (!command_buf)
	      exit (1);

            /* 'cmdline' has arguments separated by nulls */
            for (p=command_buf; ; p++) {
              int c;
	      if (p == (command_buf + cmd_size)) 
		{
		  int cur_size = cmd_size;
		  cmd_size *= 2;
		  command_buf = (char *)realloc(command_buf, cmd_size);
		  if (!command_buf)
		    exit (1);
		  p = command_buf + cur_size;
		}
              c = fgetc(file);
              if (c == EOF || c == '\0') {
                *p = '\0';
                break;
              } else {
                *p = c;
              }
            }
            if (strlen(command_buf) == 0) {
              okay = 0;
              break;
            }
            p = strrchr(command_buf,'/');
            p = p ? p+1 : command_buf;
            if (strncmp(p, comm, COMM_LEN-1) == 0) {
              okay = 1;
              command = p;
              break;
            }
          }
          (void) fclose(file);
	  if (exact && !okay)
	    {
	      if (verbose)
		fprintf (stderr, _("killall: skipping partial match %s(%d)\n"),
			comm, pid_table[i]);
	      continue;
	    }
	  got_long = okay;
	}
      /* mach by process name */
      for (j = 0; j < names; j++)
	{
	  if (reg)
	    {
	      if (regexec (&reglist[j], got_long ? command : comm, 0, NULL, 0) != 0)
		      continue;
	    }
	  else /* non-regex */
	    {
	      if ( younger_than && process_age_sec && (process_age_sec > younger_than ) )
		 continue;
	      if ( older_than   && process_age_sec && (process_age_sec < older_than ) )
		 continue;
	       
 	      if (!sts[j].st_dev)
	        {
	          if (length != COMM_LEN - 1 || name_len[j] < COMM_LEN - 1)
	  	    {
		      if (ignore_case == 1)
		        {
		          if (strcasecmp (namelist[j], comm))
		             continue;
		        }
		      else
		        {
		          if (strcmp(namelist[j], comm))
		             continue;
		        }
		    }
	          else
	            {
	              if (ignore_case == 1)
	                {
	                  if (got_long ? strcasecmp (namelist[j], command) :
	                                 strncasecmp (namelist[j], comm, COMM_LEN - 1))
	                     continue;
	                }
	              else
	                {
	                  if (got_long ? strcmp (namelist[j], command) :
	                                 strncmp (namelist[j], comm, COMM_LEN - 1))
	                     continue;
	                }
	            }
	        }
	      else
	        {
		  int ok = 1;

	          if (asprintf (&path, PROC_BASE "/%d/exe", pid_table[i]) < 0)
		    continue;

	          if (stat (path, &st) < 0) 
		      ok = 0;

		  else if (sts[j].st_dev != st.st_dev ||
			   sts[j].st_ino != st.st_ino)
		    {
		      /* maybe the binary has been modified and std[j].st_ino
		       * is not reliable anymore. We need to compare paths.
		       */
		      size_t len = strlen(namelist[j]);
		      char *linkbuf = malloc(len + 1);

		      if (!linkbuf ||
			  readlink(path, linkbuf, len + 1) != len ||
			  memcmp(namelist[j], linkbuf, len))
			ok = 0;
		      free(linkbuf);
		    }

		  free(path);
		  if (!ok)
		    continue;
	        }
	    } /* non-regex */
	  found_name = j;
	  break;
	}  
        
        if (names && found_name==-1)
	  continue;  /* match by process name faild */
	
        /* check for process group */
	if (!process_group)
	  id = pid_table[i];
	else
	  {
	    int j;

	    id = getpgid (pid_table[i]);
	    pgids[i] = id;
	    if (id < 0)
	      {
	        fprintf (stderr, "killall: getpgid(%d): %s\n",
			   pid_table[i], strerror (errno));
	      }
	    for (j = 0; j < i; j++)
	      if (pgids[j] == id)
	        break;
	    if (j < i)
	      continue;
	  }	
	if (interactive && !ask (comm, id, signal))
	  continue;
	if (kill (process_group ? -id : id, signal) >= 0)
	  {
	    if (verbose)
	      fprintf (stderr, _("Killed %s(%s%d) with signal %d\n"), got_long ? command :
			 comm, process_group ? "pgid " : "", id, signal);
	    if (found_name >= 0)
		    /* mark item of namelist */
		    found |= 1 << found_name;
	    pid_killed[pids_killed++] = id;
	  }
	else if (errno != ESRCH || interactive)
	  fprintf (stderr, "%s(%d): %s\n", got_long ? command :
	    	comm, id, strerror (errno));
    }
  if (!quiet)
    for (i = 0; i < names; i++)
      if (!(found & (1 << i)))
	fprintf (stderr, _("%s: no process found\n"), namelist[i]);
  if (names)
    /* killall returns a zero return code if at least one process has 
     * been killed for each listed command. */
    error = found == ((1 << (names - 1)) | ((1 << (names - 1)) - 1)) ? 0 : 1;
  else
    /* in nameless mode killall returns a zero return code if at least 
     * one process has killed */
    error = pids_killed ? 0 : 1;
  /*
   * We scan all (supposedly) killed processes every second to detect dead
   * processes as soon as possible in order to limit problems of race with
   * PID re-use.
   */
  while (pids_killed && wait_until_dead)
    {
      for (i = 0; i < pids_killed;)
	{
	  if (kill (process_group ? -pid_killed[i] : pid_killed[i], 0) < 0 &&
	      errno == ESRCH)
	    {
	      pid_killed[i] = pid_killed[--pids_killed];
	      continue;
	    }
	  i++;
	}
      sleep (1);		/* wait a bit longer */
    }
  return error;
}
Ejemplo n.º 15
0
static JSBool
rpmsx_getprop(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
    void * ptr = JS_GetInstancePrivate(cx, obj, &rpmsxClass, NULL);
    jsint tiny = JSVAL_TO_INT(id);
#if defined(WITH_SELINUX)
    security_context_t con = NULL;
#endif

    /* XXX the class has ptr == NULL, instances have ptr != NULL. */
    if (ptr == NULL)
	return JS_TRUE;

    switch (tiny) {
    case _DEBUG:
	*vp = INT_TO_JSVAL(_debug);
	break;
#if defined(WITH_SELINUX)
    case _CURRENT:	*vp = _GET_CON(!getcon(&con));			break;
    case _PID:		*vp = _GET_CON(!getpidcon(getpid(), &con));	break;
    case _PPID:		*vp = _GET_CON(!getpidcon(getppid(), &con));	break;
    case _PREV:		*vp = _GET_CON(!getprevcon(&con));		break;
    case _EXEC:		*vp = _GET_CON(!getexeccon(&con));		break;
    case _FSCREATE:	*vp = _GET_CON(!getfscreatecon(&con));		break;
    case _KEYCREATE:	*vp = _GET_CON(!getkeycreatecon(&con));		break;
    case _SOCKCREATE:	*vp = _GET_CON(!getsockcreatecon(&con));	break;
    case _ENFORCE:	*vp = INT_TO_JSVAL(security_getenforce());	break;
    case _DENY:		*vp = INT_TO_JSVAL(security_deny_unknown());	break;
    case _POLICYVERS:	*vp = INT_TO_JSVAL(security_policyvers());	break;
    case _ENABLED:	*vp = INT_TO_JSVAL(is_selinux_enabled());	break;
    case _MLSENABLED:	*vp = INT_TO_JSVAL(is_selinux_mls_enabled());	break;
#ifdef	NOTYET
    case _BOOLS:	*vp = ;	break;
#endif
    case _ROOT:		*vp = _GET_STR(selinux_policy_root());		break;
    case _BINARY:	*vp = _GET_STR(selinux_binary_policy_path());	break;
    case _FAILSAFE:	*vp = _GET_STR(selinux_failsafe_context_path());break;
    case _REMOVABLE:	*vp = _GET_STR(selinux_removable_context_path());break;
    case _DEFAULT:	*vp = _GET_STR(selinux_default_context_path());	break;
    case _USER:		*vp = _GET_STR(selinux_user_contexts_path());	break;
    case _FCON:		*vp = _GET_STR(selinux_file_context_path());	break;
    case _FCONHOME:	*vp = _GET_STR(selinux_file_context_homedir_path());break;
    case _FCONLOCAL:	*vp = _GET_STR(selinux_file_context_local_path());break;
    case _FCONSUBS:	*vp = _GET_STR(selinux_file_context_subs_path());break;
    case _HOMEDIR:	*vp = _GET_STR(selinux_homedir_context_path());	break;
    case _MEDIA:	*vp = _GET_STR(selinux_media_context_path());	break;
    case _VIRTDOMAIN:	*vp = _GET_STR(selinux_virtual_domain_context_path());break;
    case _VIRTIMAGE:	*vp = _GET_STR(selinux_virtual_image_context_path());break;
    case _X:		*vp = _GET_STR(selinux_x_context_path());	break;
    case _CONTEXTS:	*vp = _GET_STR(selinux_contexts_path());	break;
    case _SECURETTY:	*vp = _GET_STR(selinux_securetty_types_path());	break;
    case _BOOLEANS:	*vp = _GET_STR(selinux_booleans_path());	break;
    case _CUSTOMTYPES:	*vp = _GET_STR(selinux_customizable_types_path());break;
    case _USERS:	*vp = _GET_STR(selinux_users_path());		break;
    case _USERSCONF:	*vp = _GET_STR(selinux_usersconf_path());	break;
    case _XLATIONS:	*vp = _GET_STR(selinux_translations_path());	break;
    case _COLORS:	*vp = _GET_STR(selinux_colors_path());		break;
    case _NETFILTER:	*vp = _GET_STR(selinux_netfilter_context_path());break;
    case _PATH:		*vp = _GET_STR(selinux_path());			break;
#endif
    default:
	break;
    }

#if defined(WITH_SELINUX)
    if (con) {
	freecon(con);
	con = NULL;
    }
#endif

    return JS_TRUE;
}