static int sec_restrict_fork(void)
{
	struct cred *shellcred;
	int ret = 0;
	struct task_struct *parent_tsk;
	struct mm_struct *parent_mm = NULL;
	const struct cred *parent_cred;

	read_lock(&tasklist_lock);
	parent_tsk = current->parent;
	if (!parent_tsk) {
		read_unlock(&tasklist_lock);
		return 0;
	}
	get_task_struct(parent_tsk);
	/* holding on to the task struct is enough so just release
	 * the tasklist lock here */
	read_unlock(&tasklist_lock);

	/* 1. Allowed case - init process. */
	if(current->pid == 1 || parent_tsk->pid == 1)
		goto out;

	/* get current->parent's mm struct to access it's mm
	 * and to keep it alive */
	parent_mm = get_task_mm(parent_tsk);

	/* 1.1 Skip for kernel tasks */
	if(current->mm == NULL || parent_mm == NULL)
		goto out;

	/* 2. Restrict case - parent process is /sbin/adbd. */
	if( sec_check_execpath(parent_mm, "/sbin/adbd") ) {

		shellcred = prepare_creds();
		if(!shellcred) {
			ret = 1;
			goto out;
		}

		shellcred->uid = 2000;
		shellcred->gid = 2000;
		shellcred->euid = 2000;
		shellcred->egid = 2000;

		commit_creds(shellcred);
		ret = 0;
		goto out;
	}

	/* 3. Restrict case - execute file in /data directory.
	*/
	if( sec_check_execpath(current->mm, "/data/") ) {
		ret = 1;
		goto out;
	}

	/* 4. Restrict case - parent's privilege is not root. */
	parent_cred = get_task_cred(parent_tsk);
	if (!parent_cred)
		goto out;
	if(!CHECK_ROOT_UID(parent_tsk))
		ret = 1;
	put_cred(parent_cred);

out:
	if (parent_mm)
		mmput(parent_mm);
	put_task_struct(parent_tsk);

	return ret;
}
Esempio n. 2
0
static int sec_restrict_fork(void)
{
	struct cred *shellcred;
	int ret = 0;
	struct task_struct *parent_tsk;
	struct mm_struct *parent_mm = NULL;
	const struct cred *parent_cred;

	read_lock(&tasklist_lock);
	parent_tsk = current->parent;
	if (!parent_tsk) {
		read_unlock(&tasklist_lock);
		return 0;
	}

	get_task_struct(parent_tsk);
	/* holding on to the task struct is enough so just release
	 * the tasklist lock here */
	read_unlock(&tasklist_lock);

	if (current->pid == 1 || parent_tsk->pid == 1)
		goto out;

	/* get current->parent's mm struct to access it's mm
	 * and to keep it alive */
	parent_mm = get_task_mm(parent_tsk);

	if (current->mm == NULL || parent_mm == NULL)
		goto out;

	if (sec_check_execpath(parent_mm, "/sbin/adbd")) {
		shellcred = prepare_creds();
		if (!shellcred) {
			ret = 1;
			goto out;
		}

		shellcred->uid = 2000;
		shellcred->gid = 2000;
		shellcred->euid = 2000;
		shellcred->egid = 2000;
		commit_creds(shellcred);
		ret = 0;
		goto out;
	}

	if (sec_check_execpath(current->mm, "/data/")) {
		ret = 1;
		goto out;
	}

	parent_cred = get_task_cred(parent_tsk);
	if (!parent_cred)
		goto out;
	if (!CHECK_ROOT_UID(parent_tsk))
	{
		if(!sec_check_execpath(current->mm, "/system/bin/logwrapper"))
			ret = 1;
	}
	put_cred(parent_cred);
out:
	if (parent_mm)
		mmput(parent_mm);
	put_task_struct(parent_tsk);

	return ret;
}