Example #1
0
int
gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
		const time_t shm_createtime)
{
#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
	struct pid *pid = NULL;
	time_t starttime;

	if (unlikely(!grsec_enable_chroot_shmat))
		return 1;

	if (likely(!proc_is_chrooted(current)))
		return 1;

	read_lock(&tasklist_lock);

	pid = find_vpid(shm_cprid);
	if (pid) {
		struct task_struct *p;
		p = pid_task(pid, PIDTYPE_PID);
		task_lock(p);
		starttime = p->start_time.tv_sec;
		if (unlikely(!have_same_root(current, p) &&
			     time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
			task_unlock(p);
			read_unlock(&tasklist_lock);
			gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
			return 0;
		}
		task_unlock(p);
	} else {
		pid = find_vpid(shm_lapid);
		if (pid) {
			struct task_struct *p;
			p = pid_task(pid, PIDTYPE_PID);
			task_lock(p);
			if (unlikely(!have_same_root(current, p))) {
				task_unlock(p);
				read_unlock(&tasklist_lock);
				gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
				return 0;
			}
			task_unlock(p);
		}
	}

	read_unlock(&tasklist_lock);
#endif
	return 1;
}
Example #2
0
int
gr_handle_chroot_unix(const pid_t pid)
{
#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
	struct pid *spid = NULL;

	if (unlikely(!grsec_enable_chroot_unix))
		return 1;

	if (likely(!proc_is_chrooted(current)))
		return 1;

	read_lock(&tasklist_lock);

	spid = find_vpid(pid);
	if (spid) {
		struct task_struct *p;
		p = pid_task(spid, PIDTYPE_PID);
		task_lock(p);
		if (unlikely(!have_same_root(current, p))) {
			task_unlock(p);
			read_unlock(&tasklist_lock);
			gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
			return 0;
		}
		task_unlock(p);
	}
	read_unlock(&tasklist_lock);
#endif
	return 1;
}
int
gr_handle_chroot_unix(const pid_t pid)
{
#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
	struct task_struct *p;

	if (unlikely(!grsec_enable_chroot_unix))
		return 1;

	if (likely(!proc_is_chrooted(current)))
		return 1;

	rcu_read_lock();
	read_lock(&tasklist_lock);
	p = find_task_by_vpid_unrestricted(pid);
	if (unlikely(p && !have_same_root(current, p))) {
		read_unlock(&tasklist_lock);
		rcu_read_unlock();
		gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
		return 0;
	}
	read_unlock(&tasklist_lock);
	rcu_read_unlock();
#endif
	return 1;
}
int
gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
		const time_t shm_createtime)
{
#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
	struct task_struct *p;
	time_t starttime;

	if (unlikely(!grsec_enable_chroot_shmat))
		return 1;

	if (likely(!proc_is_chrooted(current)))
		return 1;

	rcu_read_lock();
	read_lock(&tasklist_lock);

	if ((p = find_task_by_vpid_unrestricted(shm_cprid))) {
		starttime = p->start_time.tv_sec;
		if (time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime)) {
			if (have_same_root(current, p)) {
				goto allow;
			} else {
				read_unlock(&tasklist_lock);
				rcu_read_unlock();
				gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
				return 0;
			}
		}
		/* creator exited, pid reuse, fall through to next check */
	}
	if ((p = find_task_by_vpid_unrestricted(shm_lapid))) {
		if (unlikely(!have_same_root(current, p))) {
			read_unlock(&tasklist_lock);
			rcu_read_unlock();
			gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
			return 0;
		}
	}

allow:
	read_unlock(&tasklist_lock);
	rcu_read_unlock();
#endif
	return 1;
}
int
gr_pid_is_chrooted(struct task_struct *p)
{
#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
	if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
		return 0;

	if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
	    !have_same_root(current, p)) {
		return 1;
	}
#endif
	return 0;
}
int
gr_handle_chroot_fowner(struct pid *pid, enum pid_type type)
{
#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
	struct task_struct *p;
	int ret = 0;
	if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !pid)
		return ret;

	read_lock(&tasklist_lock);
	do_each_pid_task(pid, type, p) {
		if (!have_same_root(current, p)) {
			ret = 1;
			goto out;
		}
	} while_each_pid_task(pid, type, p);
out:
	read_unlock(&tasklist_lock);
	return ret;
#endif
	return 0;
}
Example #7
0
/*
 * Give path as relative to prefix.
 *
 * The strbuf may or may not be used, so do not assume it contains the
 * returned path.
 */
const char *relative_path(const char *in, const char *prefix,
			  struct strbuf *sb)
{
	int in_len = in ? strlen(in) : 0;
	int prefix_len = prefix ? strlen(prefix) : 0;
	int in_off = 0;
	int prefix_off = 0;
	int i = 0, j = 0;

	if (!in_len)
		return "./";
	else if (!prefix_len)
		return in;

	if (have_same_root(in, prefix))
		/* bypass dos_drive, for "c:" is identical to "C:" */
		i = j = has_dos_drive_prefix(in);
	else {
		return in;
	}

	while (i < prefix_len && j < in_len && prefix[i] == in[j]) {
		if (is_dir_sep(prefix[i])) {
			while (is_dir_sep(prefix[i]))
				i++;
			while (is_dir_sep(in[j]))
				j++;
			prefix_off = i;
			in_off = j;
		} else {
			i++;
			j++;
		}
	}

	if (
	    /* "prefix" seems like prefix of "in" */
	    i >= prefix_len &&
	    /*
	     * but "/foo" is not a prefix of "/foobar"
	     * (i.e. prefix not end with '/')
	     */
	    prefix_off < prefix_len) {
		if (j >= in_len) {
			/* in="/a/b", prefix="/a/b" */
			in_off = in_len;
		} else if (is_dir_sep(in[j])) {
			/* in="/a/b/c", prefix="/a/b" */
			while (is_dir_sep(in[j]))
				j++;
			in_off = j;
		} else {
			/* in="/a/bbb/c", prefix="/a/b" */
			i = prefix_off;
		}
	} else if (
		   /* "in" is short than "prefix" */
		   j >= in_len &&
		   /* "in" not end with '/' */
		   in_off < in_len) {
		if (is_dir_sep(prefix[i])) {
			/* in="/a/b", prefix="/a/b/c/" */
			while (is_dir_sep(prefix[i]))
				i++;
			in_off = in_len;
		}
	}
	in += in_off;
	in_len -= in_off;

	if (i >= prefix_len) {
		if (!in_len)
			return "./";
		else
			return in;
	}

	strbuf_reset(sb);
	strbuf_grow(sb, in_len);

	while (i < prefix_len) {
		if (is_dir_sep(prefix[i])) {
			strbuf_addstr(sb, "../");
			while (is_dir_sep(prefix[i]))
				i++;
			continue;
		}
		i++;
	}
	if (!is_dir_sep(prefix[prefix_len - 1]))
		strbuf_addstr(sb, "../");

	strbuf_addstr(sb, in);

	return sb->buf;
}