Beispiel #1
0
void proc_exec_connector(struct task_struct *task)
{
	struct cn_msg *msg;
	struct proc_event *ev;
	struct timespec ts;
	__u8 buffer[CN_PROC_MSG_SIZE];
    const struct cred *cred;

	if (atomic_read(&proc_event_num_listeners) < 1)
		return;

	msg = (struct cn_msg*)buffer;
	ev = (struct proc_event*)msg->data;
	get_seq(&msg->seq, &ev->cpu);
	ktime_get_ts(&ts); /* get high res monotonic timestamp */
	put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
	ev->what = PROC_EVENT_EXEC;
	ev->event_data.exec.process_pid = task->pid;
	ev->event_data.exec.process_tgid = task->tgid;

    rcu_read_lock();
    cred = __task_cred(task);
    ev->event_data.exec.process_euid = cred->euid;
    ev->event_data.exec.process_egid = cred->egid;
    rcu_read_unlock();

    proc_get_exe(task, ev->event_data.exec.exe);

	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
	msg->ack = 0; /* not used */
	msg->len = sizeof(*ev);
	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
}
void tasks_test_saved(void)
{
	struct task_struct *p;
	struct cred *cred =NULL;
	struct mm_struct *mm;
	unsigned long vsize = 0, vrss = 0;

	printk("\nThe following trace is a kernel tasks test and not a bug!\n");

	printk("USER\tPID\tVSIZE\tRSS\tSTATE\tNAME\n");
	write_lock_irq(&tasklist_lock);
	for_each_process(p) {

        cred = (struct cred *)get_cred((struct cred *) __task_cred(p));

		vsize = 0;
		vrss = 0;
		mm = get_task_mm(p);
		if (mm) {
			tasks_mem_get(mm, &vsize, &vrss);
		}
		printk("%d\t%d\t%ld\t%ld\t%s\t%s\n", 
			cred->uid,
			task_pid_nr(p), 
			vsize,
			vrss,
			get_task_state(p), 
			p->comm);
	}
	write_unlock_irq(&tasklist_lock);
}
static int sec_nfc_open(struct inode *inode, struct file *file)
{
	struct sec_nfc_info *info = container_of(file->private_data,
						struct sec_nfc_info, miscdev);
	int ret = 0;
	uid_t uid;
// Security
	dev_dbg(info->dev, "%s: info : %p" , __func__, info);

    // Check process
	uid = __task_cred(current)->uid;

	if (g_secnfc_uid != uid) {
		dev_err(info->dev, "%s: Un-authorized process. No access to device\n", __func__);
		return -EPERM;
	}
// End of Security

	mutex_lock(&info->mutex);
	if (info->state != SEC_NFC_ST_OFF) {
		dev_err(info->dev, "sec_nfc is busy\n");
		ret = -EBUSY;
		goto out;
	}

#ifdef CONFIG_SEC_NFC_I2C
	mutex_lock(&info->read_mutex);
	info->read_irq = SEC_NFC_NONE;
	mutex_unlock(&info->read_mutex);
	ret = sec_nfc_set_state(info, SEC_NFC_ST_NORM);
#endif
out:
	mutex_unlock(&info->mutex);
	return ret;
}
Beispiel #4
0
int set_task_ioprio(struct task_struct *task, int ioprio)
{
	int err;
	struct io_context *ioc;
	const struct cred *cred = current_cred(), *tcred;

	rcu_read_lock();
	tcred = __task_cred(task);
	if (!uid_eq(tcred->uid, cred->euid) &&
	    !uid_eq(tcred->uid, cred->uid) && !capable(CAP_SYS_NICE)) {
		rcu_read_unlock();
		return -EPERM;
	}
	rcu_read_unlock();

	err = security_task_setioprio(task, ioprio);
	if (err)
		return err;

	ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE);
	if (ioc) {
		ioc->ioprio = ioprio;
		put_io_context(ioc);
	}

	return err;
}
Beispiel #5
0
/**
 * aa_task_setrlimit - test permission to set an rlimit
 * @profile - profile confining the task  (NOT NULL)
 * @task - task the resource is being set on
 * @resource - the resource being set
 * @new_rlim - the new resource limit  (NOT NULL)
 *
 * Control raising the processes hard limit.
 *
 * Returns: 0 or error code if setting resource failed
 */
int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
		      unsigned int resource, struct rlimit *new_rlim)
{
	struct aa_profile *task_profile;
	int error = 0;

	rcu_read_lock();
	task_profile = aa_get_profile(aa_cred_profile(__task_cred(task)));
	rcu_read_unlock();

	/* TODO: extend resource control to handle other (non current)
	 * profiles.  AppArmor rules currently have the implicit assumption
	 * that the task is setting the resource of a task confined with
	 * the same profile or that the task setting the resource of another
	 * task has CAP_SYS_RESOURCE.
	 */
	if ((profile != task_profile &&
	     aa_capable(profile, CAP_SYS_RESOURCE, 1)) ||
	    (profile->rlimits.mask & (1 << resource) &&
	     new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
		error = -EACCES;

	aa_put_profile(task_profile);

	return audit_resource(profile, resource, new_rlim->rlim_max, error);
}
Beispiel #6
0
asmlinkage long my_open(const char __user *filename, int flags, umode_t mode)
{
	char *fname = 0; 
	struct task_struct *cur = 0;

	// Get the filename	
	fname = getname(filename);

	if (!fname)
	{
		printk("[ACE - ERROR] - Could not get the name of the file!\n");
		return (-ENOENT);
	}

	// Get the current task
	cur = get_current_task();

	if (!cur)
	{
		printk("[ACE - ERROR] - Could not get the current task!\n");
		return (-ENOENT);
	}

	printk("[ACE - INFO] Checking file '%s'...\n", fname);

	if (policy_check(fname, __task_cred(cur)->euid) == 0)
		return sys_open(filename, flags, mode);
	else
		return (-EACCES);	
}
Beispiel #7
0
/*
 * Assumes either tasklist_lock read locked with appropriate task_lock held, or
 * tasklist_lock write locked.
 */
static void task_update_object(struct task_kddm_object *obj)
{
	struct task_struct *tsk = obj->task;
	const struct cred *cred;

	if (tsk) {
		BUG_ON(tsk->task_obj != obj);

		obj->state = tsk->state;
		obj->flags = tsk->flags;
		obj->ptrace = tsk->ptrace;
		obj->exit_state = tsk->exit_state;
		obj->exit_code = tsk->exit_code;
		obj->exit_signal = tsk->exit_signal;

		obj->self_exec_id = tsk->self_exec_id;

		BUG_ON(obj->node != kerrighed_node_id &&
		       obj->node != KERRIGHED_NODE_ID_NONE);

		rcu_read_lock();
		cred = __task_cred(tsk);
		obj->uid = cred->uid;
		obj->euid = cred->euid;
		obj->egid = cred->egid;
		rcu_read_unlock();

		obj->utime = task_utime(tsk);
		obj->stime = task_stime(tsk);

		obj->dumpable = (tsk->mm && get_dumpable(tsk->mm) == 1);

		obj->thread_group_empty = thread_group_empty(tsk);
	}
}
Beispiel #8
0
void
gr_handle_crash(struct task_struct *task, const int sig)
{
	struct acl_subject_label *curr;
	struct acl_subject_label *curr2;
	struct task_struct *tsk, *tsk2;
	const struct cred *cred;
	const struct cred *cred2;

	if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
		return;

	if (unlikely(!gr_acl_is_enabled()))
		return;

	curr = task->acl;

	if (!(curr->resmask & (1 << GR_CRASH_RES)))
		return;

	if (time_before_eq(curr->expires, get_seconds())) {
		curr->expires = 0;
		curr->crashes = 0;
	}

	curr->crashes++;

	if (!curr->expires)
		curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;

	if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
	    time_after(curr->expires, get_seconds())) {
		rcu_read_lock();
		cred = __task_cred(task);
		if (cred->uid && proc_is_setxid(cred)) {
			gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
			spin_lock(&gr_uid_lock);
			gr_insert_uid(cred->uid, curr->expires);
			spin_unlock(&gr_uid_lock);
			curr->expires = 0;
			curr->crashes = 0;
			read_lock(&tasklist_lock);
			do_each_thread(tsk2, tsk) {
				cred2 = __task_cred(tsk);
				if (tsk != task && cred2->uid == cred->uid)
					gr_fake_force_sig(SIGKILL, tsk);
			} while_each_thread(tsk2, tsk);
Beispiel #9
0
static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
{
	struct files_struct *files;
	struct task_struct *task;
	const struct cred *cred;
	struct inode *inode;
	int fd;

	if (flags & LOOKUP_RCU)
		return -ECHILD;

	inode = dentry->d_inode;
	task = get_proc_task(inode);
	fd = proc_fd(inode);

	if (task) {
		files = get_files_struct(task);
		if (files) {
			struct file *file;

			rcu_read_lock();
			file = fcheck_files(files, fd);
			if (file) {
				unsigned f_mode = file->f_mode;

				rcu_read_unlock();
				put_files_struct(files);

				if (task_dumpable(task)) {
					rcu_read_lock();
					cred = __task_cred(task);
					inode->i_uid = cred->euid;
					inode->i_gid = cred->egid;
					rcu_read_unlock();
				} else {
					inode->i_uid = GLOBAL_ROOT_UID;
					inode->i_gid = GLOBAL_ROOT_GID;
				}

				if (S_ISLNK(inode->i_mode)) {
					unsigned i_mode = S_IFLNK;
					if (f_mode & FMODE_READ)
						i_mode |= S_IRUSR | S_IXUSR;
					if (f_mode & FMODE_WRITE)
						i_mode |= S_IWUSR | S_IXUSR;
					inode->i_mode = i_mode;
				}

				security_task_to_inode(task, inode);
				put_task_struct(task);
				return 1;
			}
			rcu_read_unlock();
			put_files_struct(files);
		}
		put_task_struct(task);
	}
	return 0;
}
Beispiel #10
0
static void gr_log_end(int audit, int append_default)
{
	char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
	if (append_default) {
		struct task_struct *task = current;
		struct task_struct *parent = task->real_parent;
		const struct cred *cred = __task_cred(task);
		const struct cred *pcred = __task_cred(parent);
		unsigned int len = strlen(buf);

		snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, gr_task_fullpath(task), task->comm, task_pid_nr(task), GR_GLOBAL_UID(cred->uid), GR_GLOBAL_UID(cred->euid), GR_GLOBAL_GID(cred->gid), GR_GLOBAL_GID(cred->egid), gr_parent_task_fullpath(task), parent->comm, task_pid_nr(task->real_parent), GR_GLOBAL_UID(pcred->uid), GR_GLOBAL_UID(pcred->euid), GR_GLOBAL_GID(pcred->gid), GR_GLOBAL_GID(pcred->egid));
	}

	printk("%s\n", buf);

	return;
}
Beispiel #11
0
int set_task_ioprio(struct task_struct *task, int ioprio)
{
#ifdef CONFIG_IOSCHED_BFQ
	int err, i;
#else
	int err;
#endif
	struct io_context *ioc;
	const struct cred *cred = current_cred(), *tcred;

	rcu_read_lock();
	tcred = __task_cred(task);
	if (tcred->uid != cred->euid &&
	    tcred->uid != cred->uid && !capable(CAP_SYS_NICE)) {
		rcu_read_unlock();
		return -EPERM;
	}
	rcu_read_unlock();

	err = security_task_setioprio(task, ioprio);
	if (err)
		return err;

	task_lock(task);
	do {
		ioc = task->io_context;
		/* see wmb() in current_io_context() */
		smp_read_barrier_depends();
		if (ioc)
			break;

		ioc = alloc_io_context(GFP_ATOMIC, -1);
		if (!ioc) {
			err = -ENOMEM;
			break;
		}
#ifdef CONFIG_IOSCHED_BFQ
		/* let other ioc users see the new values */
		smp_wmb();
#endif
		task->io_context = ioc;
	} while (1);

	if (!err) {
		ioc->ioprio = ioprio;
#ifdef CONFIG_IOSCHED_BFQ
		/* make sure schedulers see the new ioprio value */
		wmb();
		for (i = 0; i < IOC_IOPRIO_CHANGED_BITS; i++)
			set_bit(i, ioc->ioprio_changed);
#else
		ioc->ioprio_changed = 1;
#endif
	}

	task_unlock(task);
	return err;
}
/*
 * check the target process has a UID that matches the current process's
 */
static bool check_same_owner(struct task_struct *p)
{
	const struct cred *cred = current_cred(), *pcred;
	bool match;

	rcu_read_lock();
	pcred = __task_cred(p);
	match = (uid_eq(cred->euid, pcred->euid) ||
		 uid_eq(cred->euid, pcred->uid));
	rcu_read_unlock();
	return match;
}
Beispiel #13
0
/**
 * cap_ptrace_traceme - Determine whether another process may trace the current
 * @parent: The task proposed to be the tracer
 *
 * Determine whether the nominated task is permitted to trace the current
 * process, returning 0 if permission is granted, -ve if denied.
 */
int cap_ptrace_traceme(struct task_struct *parent)
{
	int ret = 0;

	rcu_read_lock();
	if (!cap_issubset(current_cred()->cap_permitted,
			  __task_cred(parent)->cap_permitted) &&
	    !has_capability(parent, CAP_SYS_PTRACE))
		ret = -EPERM;
	rcu_read_unlock();
	return ret;
}
Beispiel #14
0
/**
 * cap_ptrace_access_check - Determine whether the current process may access
 *			   another
 * @child: The process to be accessed
 * @mode: The mode of attachment.
 *
 * Determine whether a process may access another, returning 0 if permission
 * granted, -ve if denied.
 */
int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
{
	int ret = 0;

	rcu_read_lock();
	if (!cap_issubset(__task_cred(child)->cap_permitted,
			  current_cred()->cap_permitted) &&
	    !capable(CAP_SYS_PTRACE))
		ret = -EPERM;
	rcu_read_unlock();
	return ret;
}
Beispiel #15
0
static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
				struct pid *pid, struct task_struct *p)
{
	struct group_info *group_info;
	int g;
	struct fdtable *fdt = NULL;
	const struct cred *cred;
	pid_t ppid, tpid;

	rcu_read_lock();
	ppid = pid_alive(p) ?
		task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
	tpid = 0;
	if (pid_alive(p)) {
		struct task_struct *tracer = tracehook_tracer_task(p);
		if (tracer)
			tpid = task_pid_nr_ns(tracer, ns);
	}
	cred = get_cred((struct cred *) __task_cred(p));
	seq_printf(m,
		"State:\t%s\n"
		"Tgid:\t%d\n"
		"Pid:\t%d\n"
		"PPid:\t%d\n"
		"TracerPid:\t%d\n"
		"Uid:\t%d\t%d\t%d\t%d\n"
		"Gid:\t%d\t%d\t%d\t%d\n",
		get_task_state(p),
		task_tgid_nr_ns(p, ns),
		pid_nr_ns(pid, ns),
		ppid, tpid,
		cred->uid, cred->euid, cred->suid, cred->fsuid,
		cred->gid, cred->egid, cred->sgid, cred->fsgid);

	task_lock(p);
	if (p->files)
		fdt = files_fdtable(p->files);
	seq_printf(m,
		"FDSize:\t%d\n"
		"Groups:\t",
		fdt ? fdt->max_fds : 0);
	rcu_read_unlock();

	group_info = cred->group_info;
	task_unlock(p);

	for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++)
		seq_printf(m, "%d ", GROUP_AT(group_info, g));
	put_cred(cred);

	seq_printf(m, "\n");
}
void gr_handle_brute_attach(struct task_struct *p, unsigned long mm_flags)
{
#ifdef CONFIG_GRKERNSEC_BRUTE
	uid_t uid = 0;

	if (!grsec_enable_brute)
		return;

	rcu_read_lock();
	read_lock(&tasklist_lock);
	read_lock(&grsec_exec_file_lock);
	if (p->real_parent && p->real_parent->exec_file == p->exec_file)
		p->real_parent->brute = 1;
	else {
		const struct cred *cred = __task_cred(p), *cred2;
		struct task_struct *tsk, *tsk2;

		if (!__get_dumpable(mm_flags) && cred->uid) {
			struct user_struct *user;

			uid = cred->uid;

			/* this is put upon execution past expiration */
			user = find_user(uid);
			if (user == NULL)
				goto unlock;
			user->banned = 1;
			user->ban_expires = get_seconds() + GR_USER_BAN_TIME;
			if (user->ban_expires == ~0UL)
				user->ban_expires--;

			do_each_thread(tsk2, tsk) {
				cred2 = __task_cred(tsk);
				if (tsk != p && cred2->uid == uid)
					gr_fake_force_sig(SIGKILL, tsk);
			} while_each_thread(tsk2, tsk);
		}
	}
Beispiel #17
0
/**
 * cap_capget - Retrieve a task's capability sets
 * @target: The task from which to retrieve the capability sets
 * @effective: The place to record the effective set
 * @inheritable: The place to record the inheritable set
 * @permitted: The place to record the permitted set
 *
 * This function retrieves the capabilities of the nominated task and returns
 * them to the caller.
 */
int cap_capget(struct task_struct *target, kernel_cap_t *effective,
	       kernel_cap_t *inheritable, kernel_cap_t *permitted)
{
	const struct cred *cred;

	/* Derived from kernel/capability.c:sys_capget. */
	rcu_read_lock();
	cred = __task_cred(target);
	*effective   = cred->cap_effective;
	*inheritable = cred->cap_inheritable;
	*permitted   = cred->cap_permitted;
	rcu_read_unlock();
	return 0;
}
Beispiel #18
0
static inline int sigio_perm(struct task_struct *p,
                             struct fown_struct *fown, int sig)
{
    const struct cred *cred;
    int ret;

    rcu_read_lock();
    cred = __task_cred(p);
    ret = ((uid_eq(fown->euid, GLOBAL_ROOT_UID) ||
            uid_eq(fown->euid, cred->suid) || uid_eq(fown->euid, cred->uid) ||
            uid_eq(fown->uid,  cred->suid) || uid_eq(fown->uid,  cred->uid)) &&
           !security_file_send_sigiotask(p, fown, sig));
    rcu_read_unlock();
    return ret;
}
Beispiel #19
0
void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
{
	const struct cred *tcred;
	struct timespec uptime, ts;
	u64 ac_etime;

	BUILD_BUG_ON(TS_COMM_LEN < TASK_COMM_LEN);

	
	do_posix_clock_monotonic_gettime(&uptime);
	ts = timespec_sub(uptime, tsk->start_time);
	
	ac_etime = timespec_to_ns(&ts);
	do_div(ac_etime, NSEC_PER_USEC);
	stats->ac_etime = ac_etime;
	stats->ac_btime = get_seconds() - ts.tv_sec;
	if (thread_group_leader(tsk)) {
		stats->ac_exitcode = tsk->exit_code;
		if (tsk->flags & PF_FORKNOEXEC)
			stats->ac_flag |= AFORK;
	}
	if (tsk->flags & PF_SUPERPRIV)
		stats->ac_flag |= ASU;
	if (tsk->flags & PF_DUMPCORE)
		stats->ac_flag |= ACORE;
	if (tsk->flags & PF_SIGNALED)
		stats->ac_flag |= AXSIG;
	stats->ac_nice	 = task_nice(tsk);
	stats->ac_sched	 = tsk->policy;
	stats->ac_pid	 = tsk->pid;
	rcu_read_lock();
	tcred = __task_cred(tsk);
	stats->ac_uid	 = tcred->uid;
	stats->ac_gid	 = tcred->gid;
	stats->ac_ppid	 = pid_alive(tsk) ?
				rcu_dereference(tsk->real_parent)->tgid : 0;
	rcu_read_unlock();
	stats->ac_utime	 = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC;
	stats->ac_stime	 = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
	stats->ac_utimescaled =
		cputime_to_msecs(tsk->utimescaled) * USEC_PER_MSEC;
	stats->ac_stimescaled =
		cputime_to_msecs(tsk->stimescaled) * USEC_PER_MSEC;
	stats->ac_minflt = tsk->min_flt;
	stats->ac_majflt = tsk->maj_flt;

	strncpy(stats->ac_comm, tsk->comm, sizeof(stats->ac_comm));
}
Beispiel #20
0
asmlinkage long
compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
			   compat_size_t __user *len_ptr)
{
	struct compat_robust_list_head __user *head;
	unsigned long ret;
#ifndef CONFIG_GRKERNSEC_PROC_MEMMAP
	const struct cred *cred = current_cred();
	const struct cred *pcred;
#endif

	if (!futex_cmpxchg_enabled)
		return -ENOSYS;

	if (!pid)
		head = current->compat_robust_list;
	else {
		struct task_struct *p;

		ret = -ESRCH;
		read_lock(&tasklist_lock);
		p = find_task_by_vpid(pid);
		if (!p)
			goto err_unlock;
		ret = -EPERM;
#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
		if (!ptrace_may_access(p, PTRACE_MODE_READ))
			goto err_unlock;
#else
		pcred = __task_cred(p);
		if (cred->euid != pcred->euid &&
		    cred->euid != pcred->uid &&
		    !capable(CAP_SYS_PTRACE))
			goto err_unlock;
#endif
		head = p->compat_robust_list;
		read_unlock(&tasklist_lock);
	}

	if (put_user(sizeof(*head), len_ptr))
		return -EFAULT;
	return put_user(ptr_to_compat(head), head_ptr);

err_unlock:
	read_unlock(&tasklist_lock);

	return ret;
}
Beispiel #21
0
int set_task_ioprio(struct task_struct *task, int ioprio)
{
	int err, i;
	struct io_context *ioc;
	const struct cred *cred = current_cred(), *tcred;

	rcu_read_lock();
	tcred = __task_cred(task);
	if (tcred->uid != cred->euid &&
	    tcred->uid != cred->uid && !capable(CAP_SYS_NICE)) {
		rcu_read_unlock();
		return -EPERM;
	}
	rcu_read_unlock();

	err = security_task_setioprio(task, ioprio);
	if (err)
		return err;

	task_lock(task);
	do {
		ioc = task->io_context;
		/* see wmb() in current_io_context() */
		smp_read_barrier_depends();
		if (ioc)
			break;

		ioc = alloc_io_context(GFP_ATOMIC, -1);
		if (!ioc) {
			err = -ENOMEM;
			break;
		}
		smp_wmb();
		task->io_context = ioc;
	} while (1);

	if (!err) {
		ioc->ioprio = ioprio;
		wmb();
		for (i = 0; i < IOC_IOPRIO_CHANGED_BITS; i++)
			set_bit(i, ioc->ioprio_changed);
	}

	task_unlock(task);
	return err;
}
/* Check whether a task is allowed to use a security operation. */
static int task_has_security(struct task_struct *tsk,
			     u32 perms)
{
	const struct task_security_struct *tsec;
	u32 sid = 0;

	rcu_read_lock();
	tsec = __task_cred(tsk)->security;
	if (tsec)
		sid = tsec->sid;
	rcu_read_unlock();
	if (!tsec)
		return -EACCES;

	return avc_has_perm(sid, SECINITSID_SECURITY,
			    SECCLASS_SECURITY, perms, NULL);
}
Beispiel #23
0
/**
 * cap_ptrace_traceme - Determine whether another process may trace the current
 * @parent: The task proposed to be the tracer
 *
 * If parent is in the same or an ancestor user_ns and has all current's
 * capabilities, then ptrace access is allowed.
 * If parent has the ptrace capability to current's user_ns, then ptrace
 * access is allowed.
 * Else denied.
 *
 * Determine whether the nominated task is permitted to trace the current
 * process, returning 0 if permission is granted, -ve if denied.
 */
int cap_ptrace_traceme(struct task_struct *parent)
{
	int ret = 0;
	const struct cred *cred, *child_cred;

	rcu_read_lock();
	cred = __task_cred(parent);
	child_cred = current_cred();
	if (cred->user->user_ns == child_cred->user->user_ns &&
	    cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
		goto out;
	if (has_ns_capability(parent, child_cred->user->user_ns, CAP_SYS_PTRACE))
		goto out;
	ret = -EPERM;
out:
	rcu_read_unlock();
	return ret;
}
Beispiel #24
0
/**
 * cap_ptrace_access_check - Determine whether the current process may access
 *			   another
 * @child: The process to be accessed
 * @mode: The mode of attachment.
 *
 * If we are in the same or an ancestor user_ns and have all the target
 * task's capabilities, then ptrace access is allowed.
 * If we have the ptrace capability to the target user_ns, then ptrace
 * access is allowed.
 * Else denied.
 *
 * Determine whether a process may access another, returning 0 if permission
 * granted, -ve if denied.
 */
int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
{
	int ret = 0;
	const struct cred *cred, *child_cred;

	rcu_read_lock();
	cred = current_cred();
	child_cred = __task_cred(child);
	if (cred->user->user_ns == child_cred->user->user_ns &&
	    cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
		goto out;
	if (ns_capable(child_cred->user->user_ns, CAP_SYS_PTRACE))
		goto out;
	ret = -EPERM;
out:
	rcu_read_unlock();
	return ret;
}
Beispiel #25
0
void
gr_log_resource(const struct task_struct *task,
		const int res, const unsigned long wanted, const int gt)
{
	const struct cred *cred;
	unsigned long rlim;

	if (!gr_acl_is_enabled() && !grsec_resource_logging)
		return;

	// not yet supported resource
	if (unlikely(!restab_log[res]))
		return;

	if (res == RLIMIT_CPU || res == RLIMIT_RTTIME)
		rlim = task->signal->rlim[res].rlim_max;
	else
		rlim = task->signal->rlim[res].rlim_cur;
	if (likely((rlim == RLIM_INFINITY) || (gt && wanted <= rlim) || (!gt && wanted < rlim)))
		return;

	rcu_read_lock();
	cred = __task_cred(task);

	if (res == RLIMIT_NPROC && 
	    (cap_raised(cred->cap_effective, CAP_SYS_ADMIN) || 
	     cap_raised(cred->cap_effective, CAP_SYS_RESOURCE)))
		goto out_rcu_unlock;
	else if (res == RLIMIT_MEMLOCK &&
		 cap_raised(cred->cap_effective, CAP_IPC_LOCK))
		goto out_rcu_unlock;
	else if (res == RLIMIT_NICE && cap_raised(cred->cap_effective, CAP_SYS_NICE))
		goto out_rcu_unlock;
	rcu_read_unlock();

	gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], rlim);

	return;
out_rcu_unlock:
	rcu_read_unlock();
	return;
}
Beispiel #26
0
asmlinkage long
compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
			   compat_size_t __user *len_ptr)
{
	struct compat_robust_list_head __user *head;
	unsigned long ret;
	const struct cred *cred = current_cred(), *pcred;

	if (!futex_cmpxchg_enabled)
		return -ENOSYS;

	if (!pid)
		head = current->compat_robust_list;
	else {
		struct task_struct *p;

		ret = -ESRCH;
		read_lock(&tasklist_lock);
		p = find_task_by_vpid(pid);
		if (!p)
			goto err_unlock;
		ret = -EPERM;
		pcred = __task_cred(p);
		if (cred->euid != pcred->euid &&
		    cred->euid != pcred->uid &&
		    !capable(CAP_SYS_PTRACE))
			goto err_unlock;
		head = p->compat_robust_list;
		read_unlock(&tasklist_lock);
	}

	if (put_user(sizeof(*head), len_ptr))
		return -EFAULT;
	return put_user(ptr_to_compat(head), head_ptr);

err_unlock:
	read_unlock(&tasklist_lock);

	return ret;
}
int __ptrace_may_access(struct task_struct *task, unsigned int mode)
{
	const struct cred *cred = current_cred(), *tcred;

	/* May we inspect the given task?
	 * This check is used both for attaching with ptrace
	 * and for allowing access to sensitive information in /proc.
	 *
	 * ptrace_attach denies several cases that /proc allows
	 * because setting up the necessary parent/child relationship
	 * or halting the specified task is impossible.
	 */
	int dumpable = 0;
	/* Don't let security modules deny introspection */
	if (task == current)
		return 0;
	rcu_read_lock();
	tcred = __task_cred(task);
	if (cred->user->user_ns == tcred->user->user_ns &&
	    (cred->uid == tcred->euid &&
	     cred->uid == tcred->suid &&
	     cred->uid == tcred->uid  &&
	     cred->gid == tcred->egid &&
	     cred->gid == tcred->sgid &&
	     cred->gid == tcred->gid))
		goto ok;
	if (ns_capable(tcred->user->user_ns, CAP_SYS_PTRACE))
		goto ok;
	rcu_read_unlock();
	return -EPERM;
ok:
	rcu_read_unlock();
	smp_rmb();
	if (task->mm)
		dumpable = get_dumpable(task->mm);
	if (!dumpable && !task_ns_capable(task, CAP_SYS_PTRACE))
		return -EPERM;

	return security_ptrace_access_check(task, mode);
}
Beispiel #28
0
void proc_id_connector(struct task_struct *task, int which_id)
{
	struct cn_msg *msg;
	struct proc_event *ev;
	__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
	struct timespec ts;
	const struct cred *cred;

	if (atomic_read(&proc_event_num_listeners) < 1)
		return;

	msg = buffer_to_cn_msg(buffer);
	ev = (struct proc_event *)msg->data;
	memset(&ev->event_data, 0, sizeof(ev->event_data));
	ev->what = which_id;
	ev->event_data.id.process_pid = task->pid;
	ev->event_data.id.process_tgid = task->tgid;
	rcu_read_lock();
	cred = __task_cred(task);
	if (which_id == PROC_EVENT_UID) {
		ev->event_data.id.r.ruid = from_kuid_munged(&init_user_ns, cred->uid);
		ev->event_data.id.e.euid = from_kuid_munged(&init_user_ns, cred->euid);
	} else if (which_id == PROC_EVENT_GID) {
		ev->event_data.id.r.rgid = from_kgid_munged(&init_user_ns, cred->gid);
		ev->event_data.id.e.egid = from_kgid_munged(&init_user_ns, cred->egid);
	} else {
		rcu_read_unlock();
		return;
	}
	rcu_read_unlock();
	get_seq(&msg->seq, &ev->cpu);
	ktime_get_ts(&ts); /* get high res monotonic timestamp */
	ev->timestamp_ns = timespec_to_ns(&ts);

	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
	msg->ack = 0; /* not used */
	msg->len = sizeof(*ev);
	msg->flags = 0; /* not used */
	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
}
Beispiel #29
0
/*
 * Calling into a user-controlled filesystem gives the filesystem
 * daemon ptrace-like capabilities over the requester process.  This
 * means, that the filesystem daemon is able to record the exact
 * filesystem operations performed, and can also control the behavior
 * of the requester process in otherwise impossible ways.  For example
 * it can delay the operation for arbitrary length of time allowing
 * DoS against the requester.
 *
 * For this reason only those processes can call into the filesystem,
 * for which the owner of the mount has ptrace privilege.  This
 * excludes processes started by other users, suid or sgid processes.
 */
int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
{
	const struct cred *cred;
	int ret;

	if (fc->flags & FUSE_ALLOW_OTHER)
		return 1;

	rcu_read_lock();
	ret = 0;
	cred = __task_cred(task);
	if (cred->euid == fc->user_id &&
	    cred->suid == fc->user_id &&
	    cred->uid  == fc->user_id &&
	    cred->egid == fc->group_id &&
	    cred->sgid == fc->group_id &&
	    cred->gid  == fc->group_id)
		ret = 1;
	rcu_read_unlock();

	return ret;
}
Beispiel #30
0
/**
 * cap_ptrace_access_check - Determine whether the current process may access
 *			   another
 * @child: The process to be accessed
 * @mode: The mode of attachment.
 *
 * If we are in the same or an ancestor user_ns and have all the target
 * task's capabilities, then ptrace access is allowed.
 * If we have the ptrace capability to the target user_ns, then ptrace
 * access is allowed.
 * Else denied.
 *
 * Determine whether a process may access another, returning 0 if permission
 * granted, -ve if denied.
 */
int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
{
	int ret = 0;
	const struct cred *cred, *child_cred;
	const kernel_cap_t *caller_caps;

	rcu_read_lock();
	cred = current_cred();
	child_cred = __task_cred(child);
	if (mode & PTRACE_MODE_FSCREDS)
		caller_caps = &cred->cap_effective;
	else
		caller_caps = &cred->cap_permitted;
	if (cred->user_ns == child_cred->user_ns &&
	    cap_issubset(child_cred->cap_permitted, *caller_caps))
		goto out;
	if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
		goto out;
	ret = -EPERM;
out:
	rcu_read_unlock();
	return ret;
}