Revert "exec: Transform exec_update_mutex into a rw_semaphore"

This reverts commit 117433236a which is
commit f7cfd871ae0c5008d94b6f66834e7845caa93c15 upstream.

It breaks the API and we don't need it right now in the 5.4 tree.

Bug: 161946584
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: Ia4d89b6dfbb92d6bd48b36b1f85559a8dfb331c6
This commit is contained in:
Greg Kroah-Hartman 2021-01-11 14:31:42 +01:00
commit 116bf1afff
8 changed files with 43 additions and 44 deletions

View file

@ -1009,8 +1009,8 @@ EXPORT_SYMBOL(read_code);
/*
* Maps the mm_struct mm into the current task struct.
* On success, this function returns with exec_update_lock
* held for writing.
* On success, this function returns with the mutex
* exec_update_mutex locked.
*/
static int exec_mmap(struct mm_struct *mm)
{
@ -1023,7 +1023,7 @@ static int exec_mmap(struct mm_struct *mm)
old_mm = current->mm;
exec_mm_release(tsk, old_mm);
ret = down_write_killable(&tsk->signal->exec_update_lock);
ret = mutex_lock_killable(&tsk->signal->exec_update_mutex);
if (ret)
return ret;
@ -1038,7 +1038,7 @@ static int exec_mmap(struct mm_struct *mm)
down_read(&old_mm->mmap_sem);
if (unlikely(old_mm->core_state)) {
up_read(&old_mm->mmap_sem);
up_write(&tsk->signal->exec_update_lock);
mutex_unlock(&tsk->signal->exec_update_mutex);
return -EINTR;
}
}
@ -1450,7 +1450,7 @@ static void free_bprm(struct linux_binprm *bprm)
free_arg_pages(bprm);
if (bprm->cred) {
if (bprm->called_exec_mmap)
up_write(&current->signal->exec_update_lock);
mutex_unlock(&current->signal->exec_update_mutex);
mutex_unlock(&current->signal->cred_guard_mutex);
abort_creds(bprm->cred);
}
@ -1500,7 +1500,7 @@ void install_exec_creds(struct linux_binprm *bprm)
* credentials; any time after this it may be unlocked.
*/
security_bprm_committed_creds(bprm);
up_write(&current->signal->exec_update_lock);
mutex_unlock(&current->signal->exec_update_mutex);
mutex_unlock(&current->signal->cred_guard_mutex);
}
EXPORT_SYMBOL(install_exec_creds);

View file

@ -404,11 +404,11 @@ print0:
static int lock_trace(struct task_struct *task)
{
int err = down_read_killable(&task->signal->exec_update_lock);
int err = mutex_lock_killable(&task->signal->exec_update_mutex);
if (err)
return err;
if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
up_read(&task->signal->exec_update_lock);
mutex_unlock(&task->signal->exec_update_mutex);
return -EPERM;
}
return 0;
@ -416,7 +416,7 @@ static int lock_trace(struct task_struct *task)
static void unlock_trace(struct task_struct *task)
{
up_read(&task->signal->exec_update_lock);
mutex_unlock(&task->signal->exec_update_mutex);
}
#ifdef CONFIG_STACKTRACE
@ -2770,7 +2770,7 @@ static int do_io_accounting(struct task_struct *task, struct seq_file *m, int wh
unsigned long flags;
int result;
result = down_read_killable(&task->signal->exec_update_lock);
result = mutex_lock_killable(&task->signal->exec_update_mutex);
if (result)
return result;
@ -2806,7 +2806,7 @@ static int do_io_accounting(struct task_struct *task, struct seq_file *m, int wh
result = 0;
out_unlock:
up_read(&task->signal->exec_update_lock);
mutex_unlock(&task->signal->exec_update_mutex);
return result;
}

View file

@ -227,13 +227,12 @@ struct signal_struct {
* credential calculations
* (notably. ptrace)
* Deprecated do not use in new code.
* Use exec_update_lock instead.
* Use exec_update_mutex instead.
*/
struct mutex exec_update_mutex; /* Held while task_struct is being
* updated during exec, and may have
* inconsistent permissions.
*/
struct rw_semaphore exec_update_lock; /* Held while task_struct is
* being updated during exec,
* and may have inconsistent
* permissions.
*/
ANDROID_KABI_RESERVE(1);
ANDROID_KABI_RESERVE(2);
ANDROID_KABI_RESERVE(3);

View file

@ -27,7 +27,7 @@ static struct signal_struct init_signals = {
.multiprocess = HLIST_HEAD_INIT,
.rlim = INIT_RLIMITS,
.cred_guard_mutex = __MUTEX_INITIALIZER(init_signals.cred_guard_mutex),
.exec_update_lock = __RWSEM_INITIALIZER(init_signals.exec_update_lock),
.exec_update_mutex = __MUTEX_INITIALIZER(init_signals.exec_update_mutex),
#ifdef CONFIG_POSIX_TIMERS
.posix_timers = LIST_HEAD_INIT(init_signals.posix_timers),
.cputimer = {

View file

@ -1254,7 +1254,7 @@ static void put_ctx(struct perf_event_context *ctx)
* function.
*
* Lock order:
* exec_update_lock
* exec_update_mutex
* task_struct::perf_event_mutex
* perf_event_context::mutex
* perf_event::child_mutex;
@ -11163,14 +11163,14 @@ SYSCALL_DEFINE5(perf_event_open,
}
if (task) {
err = down_read_interruptible(&task->signal->exec_update_lock);
err = mutex_lock_interruptible(&task->signal->exec_update_mutex);
if (err)
goto err_file;
/*
* Preserve ptrace permission check for backwards compatibility.
*
* We must hold exec_update_lock across this and any potential
* We must hold exec_update_mutex across this and any potential
* perf_install_in_context() call for this new event to
* serialize against exec() altering our credentials (and the
* perf_event_exit_task() that could imply).
@ -11333,7 +11333,7 @@ SYSCALL_DEFINE5(perf_event_open,
mutex_unlock(&ctx->mutex);
if (task) {
up_read(&task->signal->exec_update_lock);
mutex_unlock(&task->signal->exec_update_mutex);
put_task_struct(task);
}
@ -11357,7 +11357,7 @@ err_locked:
mutex_unlock(&ctx->mutex);
err_cred:
if (task)
up_read(&task->signal->exec_update_lock);
mutex_unlock(&task->signal->exec_update_mutex);
err_file:
fput(event_file);
err_context:
@ -11674,7 +11674,7 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
/*
* When a child task exits, feed back event values to parent events.
*
* Can be called with exec_update_lock held when called from
* Can be called with exec_update_mutex held when called from
* install_exec_creds().
*/
void perf_event_exit_task(struct task_struct *child)

View file

@ -1232,7 +1232,7 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
struct mm_struct *mm;
int err;
err = down_read_killable(&task->signal->exec_update_lock);
err = mutex_lock_killable(&task->signal->exec_update_mutex);
if (err)
return ERR_PTR(err);
@ -1242,7 +1242,7 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
mmput(mm);
mm = ERR_PTR(-EACCES);
}
up_read(&task->signal->exec_update_lock);
mutex_unlock(&task->signal->exec_update_mutex);
return mm;
}
@ -1597,7 +1597,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
sig->oom_score_adj_min = current->signal->oom_score_adj_min;
mutex_init(&sig->cred_guard_mutex);
init_rwsem(&sig->exec_update_lock);
mutex_init(&sig->exec_update_mutex);
return 0;
}

View file

@ -75,25 +75,25 @@ get_file_raw_ptr(struct task_struct *task, unsigned int idx)
return file;
}
static void kcmp_unlock(struct rw_semaphore *l1, struct rw_semaphore *l2)
static void kcmp_unlock(struct mutex *m1, struct mutex *m2)
{
if (likely(l2 != l1))
up_read(l2);
up_read(l1);
if (likely(m2 != m1))
mutex_unlock(m2);
mutex_unlock(m1);
}
static int kcmp_lock(struct rw_semaphore *l1, struct rw_semaphore *l2)
static int kcmp_lock(struct mutex *m1, struct mutex *m2)
{
int err;
if (l2 > l1)
swap(l1, l2);
if (m2 > m1)
swap(m1, m2);
err = down_read_killable(l1);
if (!err && likely(l1 != l2)) {
err = down_read_killable_nested(l2, SINGLE_DEPTH_NESTING);
err = mutex_lock_killable(m1);
if (!err && likely(m1 != m2)) {
err = mutex_lock_killable_nested(m2, SINGLE_DEPTH_NESTING);
if (err)
up_read(l1);
mutex_unlock(m1);
}
return err;
@ -173,8 +173,8 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t, pid2, int, type,
/*
* One should have enough rights to inspect task details.
*/
ret = kcmp_lock(&task1->signal->exec_update_lock,
&task2->signal->exec_update_lock);
ret = kcmp_lock(&task1->signal->exec_update_mutex,
&task2->signal->exec_update_mutex);
if (ret)
goto err;
if (!ptrace_may_access(task1, PTRACE_MODE_READ_REALCREDS) ||
@ -229,8 +229,8 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t, pid2, int, type,
}
err_unlock:
kcmp_unlock(&task1->signal->exec_update_lock,
&task2->signal->exec_update_lock);
kcmp_unlock(&task1->signal->exec_update_mutex,
&task2->signal->exec_update_mutex);
err:
put_task_struct(task1);
put_task_struct(task2);

View file

@ -1538,7 +1538,7 @@ int __sched down_read_interruptible(struct rw_semaphore *sem)
rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_);
if (LOCK_CONTENDED_RETURN(sem, __down_read_trylock, __down_read_interruptible)) {
rwsem_release(&sem->dep_map, 1, _RET_IP_);
rwsem_release(&sem->dep_map, _RET_IP_);
return -EINTR;
}
@ -1664,7 +1664,7 @@ int down_read_killable_nested(struct rw_semaphore *sem, int subclass)
rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_);
if (LOCK_CONTENDED_RETURN(sem, __down_read_trylock, __down_read_killable)) {
rwsem_release(&sem->dep_map, 1, _RET_IP_);
rwsem_release(&sem->dep_map, _RET_IP_);
return -EINTR;
}