Skip to content

Commit d8a1f74

Browse files
ljskernelgregkh
authored andcommitted
mm: refactor mm_access() to not return NULL
[ Upstream commit cd3f846 ] mm_access() can return NULL if the mm is not found, but this is handled the same as an error in all callers, with some translating this into an -ESRCH error. Only proc_mem_open() returns NULL if no mm is found, however in this case it is clearer and makes more sense to explicitly handle the error. Additionally we take the opportunity to refactor the function to eliminate unnecessary nesting. Simplify things by simply returning -ESRCH if no mm is found - this both eliminates confusing use of the IS_ERR_OR_NULL() macro, and simplifies callers which would return -ESRCH by returning this error directly. [lorenzo.stoakes@oracle.com: prefer neater pointer error comparison] Link: https://lkml.kernel.org/r/2fae1834-749a-45e1-8594-5e5979cf7103@lucifer.local Link: https://lkml.kernel.org/r/20240924201023.193135-1-lorenzo.stoakes@oracle.com Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Suggested-by: Arnd Bergmann <arnd@arndb.de> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent c559648 commit d8a1f74

4 files changed

Lines changed: 21 additions & 18 deletions

File tree

fs/proc/base.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -811,19 +811,21 @@ static const struct file_operations proc_single_file_operations = {
811811
struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode)
812812
{
813813
struct task_struct *task = get_proc_task(inode);
814-
struct mm_struct *mm = ERR_PTR(-ESRCH);
814+
struct mm_struct *mm;
815815

816-
if (task) {
817-
mm = mm_access(task, mode | PTRACE_MODE_FSCREDS);
818-
put_task_struct(task);
816+
if (!task)
817+
return ERR_PTR(-ESRCH);
819818

820-
if (!IS_ERR_OR_NULL(mm)) {
821-
/* ensure this mm_struct can't be freed */
822-
mmgrab(mm);
823-
/* but do not pin its memory */
824-
mmput(mm);
825-
}
826-
}
819+
mm = mm_access(task, mode | PTRACE_MODE_FSCREDS);
820+
put_task_struct(task);
821+
822+
if (IS_ERR(mm))
823+
return mm == ERR_PTR(-ESRCH) ? NULL : mm;
824+
825+
/* ensure this mm_struct can't be freed */
826+
mmgrab(mm);
827+
/* but do not pin its memory */
828+
mmput(mm);
827829

828830
return mm;
829831
}
@@ -2201,7 +2203,7 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
22012203
goto out_notask;
22022204

22032205
mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
2204-
if (IS_ERR_OR_NULL(mm))
2206+
if (IS_ERR(mm))
22052207
goto out;
22062208

22072209
if (!dname_to_vma_addr(dentry, &vm_start, &vm_end)) {

kernel/fork.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,8 +1570,9 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
15701570
return ERR_PTR(err);
15711571

15721572
mm = get_task_mm(task);
1573-
if (mm && mm != current->mm &&
1574-
!ptrace_may_access(task, mode)) {
1573+
if (!mm) {
1574+
mm = ERR_PTR(-ESRCH);
1575+
} else if (mm != current->mm && !ptrace_may_access(task, mode)) {
15751576
mmput(mm);
15761577
mm = ERR_PTR(-EACCES);
15771578
}

mm/madvise.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,8 +1492,8 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec,
14921492

14931493
/* Require PTRACE_MODE_READ to avoid leaking ASLR metadata. */
14941494
mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
1495-
if (IS_ERR_OR_NULL(mm)) {
1496-
ret = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH;
1495+
if (IS_ERR(mm)) {
1496+
ret = PTR_ERR(mm);
14971497
goto release_task;
14981498
}
14991499

mm/process_vm_access.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ static ssize_t process_vm_rw_core(pid_t pid, struct iov_iter *iter,
200200
}
201201

202202
mm = mm_access(task, PTRACE_MODE_ATTACH_REALCREDS);
203-
if (!mm || IS_ERR(mm)) {
204-
rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH;
203+
if (IS_ERR(mm)) {
204+
rc = PTR_ERR(mm);
205205
/*
206206
* Explicitly map EACCES to EPERM as EPERM is a more
207207
* appropriate error code for process_vw_readv/writev

0 commit comments

Comments
 (0)