aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c70
1 files changed, 50 insertions, 20 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 60316b52d659..9298324325ed 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -75,6 +75,7 @@
75#include <linux/ptrace.h> 75#include <linux/ptrace.h>
76#include <linux/tracehook.h> 76#include <linux/tracehook.h>
77#include <linux/printk.h> 77#include <linux/printk.h>
78#include <linux/cache.h>
78#include <linux/cgroup.h> 79#include <linux/cgroup.h>
79#include <linux/cpuset.h> 80#include <linux/cpuset.h>
80#include <linux/audit.h> 81#include <linux/audit.h>
@@ -100,6 +101,8 @@
100#include "internal.h" 101#include "internal.h"
101#include "fd.h" 102#include "fd.h"
102 103
104#include "../../lib/kstrtox.h"
105
103/* NOTE: 106/* NOTE:
104 * Implementing inode permission operations in /proc is almost 107 * Implementing inode permission operations in /proc is almost
105 * certainly an error. Permission checks need to happen during 108 * certainly an error. Permission checks need to happen during
@@ -110,8 +113,8 @@
110 * in /proc for a task before it execs a suid executable. 113 * in /proc for a task before it execs a suid executable.
111 */ 114 */
112 115
113static u8 nlink_tid; 116static u8 nlink_tid __ro_after_init;
114static u8 nlink_tgid; 117static u8 nlink_tgid __ro_after_init;
115 118
116struct pid_entry { 119struct pid_entry {
117 const char *name; 120 const char *name;
@@ -1370,7 +1373,7 @@ static ssize_t proc_fail_nth_write(struct file *file, const char __user *buf,
1370 task = get_proc_task(file_inode(file)); 1373 task = get_proc_task(file_inode(file));
1371 if (!task) 1374 if (!task)
1372 return -ESRCH; 1375 return -ESRCH;
1373 WRITE_ONCE(task->fail_nth, n); 1376 task->fail_nth = n;
1374 put_task_struct(task); 1377 put_task_struct(task);
1375 1378
1376 return count; 1379 return count;
@@ -1386,8 +1389,7 @@ static ssize_t proc_fail_nth_read(struct file *file, char __user *buf,
1386 task = get_proc_task(file_inode(file)); 1389 task = get_proc_task(file_inode(file));
1387 if (!task) 1390 if (!task)
1388 return -ESRCH; 1391 return -ESRCH;
1389 len = snprintf(numbuf, sizeof(numbuf), "%u\n", 1392 len = snprintf(numbuf, sizeof(numbuf), "%u\n", task->fail_nth);
1390 READ_ONCE(task->fail_nth));
1391 len = simple_read_from_buffer(buf, count, ppos, numbuf, len); 1393 len = simple_read_from_buffer(buf, count, ppos, numbuf, len);
1392 put_task_struct(task); 1394 put_task_struct(task);
1393 1395
@@ -1907,8 +1909,33 @@ end_instantiate:
1907static int dname_to_vma_addr(struct dentry *dentry, 1909static int dname_to_vma_addr(struct dentry *dentry,
1908 unsigned long *start, unsigned long *end) 1910 unsigned long *start, unsigned long *end)
1909{ 1911{
1910 if (sscanf(dentry->d_name.name, "%lx-%lx", start, end) != 2) 1912 const char *str = dentry->d_name.name;
1913 unsigned long long sval, eval;
1914 unsigned int len;
1915
1916 len = _parse_integer(str, 16, &sval);
1917 if (len & KSTRTOX_OVERFLOW)
1918 return -EINVAL;
1919 if (sval != (unsigned long)sval)
1911 return -EINVAL; 1920 return -EINVAL;
1921 str += len;
1922
1923 if (*str != '-')
1924 return -EINVAL;
1925 str++;
1926
1927 len = _parse_integer(str, 16, &eval);
1928 if (len & KSTRTOX_OVERFLOW)
1929 return -EINVAL;
1930 if (eval != (unsigned long)eval)
1931 return -EINVAL;
1932 str += len;
1933
1934 if (*str != '\0')
1935 return -EINVAL;
1936
1937 *start = sval;
1938 *end = eval;
1912 1939
1913 return 0; 1940 return 0;
1914} 1941}
@@ -2000,9 +2027,9 @@ out:
2000} 2027}
2001 2028
2002struct map_files_info { 2029struct map_files_info {
2030 unsigned long start;
2031 unsigned long end;
2003 fmode_t mode; 2032 fmode_t mode;
2004 unsigned int len;
2005 unsigned char name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */
2006}; 2033};
2007 2034
2008/* 2035/*
@@ -2172,10 +2199,9 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
2172 if (++pos <= ctx->pos) 2199 if (++pos <= ctx->pos)
2173 continue; 2200 continue;
2174 2201
2202 info.start = vma->vm_start;
2203 info.end = vma->vm_end;
2175 info.mode = vma->vm_file->f_mode; 2204 info.mode = vma->vm_file->f_mode;
2176 info.len = snprintf(info.name,
2177 sizeof(info.name), "%lx-%lx",
2178 vma->vm_start, vma->vm_end);
2179 if (flex_array_put(fa, i++, &info, GFP_KERNEL)) 2205 if (flex_array_put(fa, i++, &info, GFP_KERNEL))
2180 BUG(); 2206 BUG();
2181 } 2207 }
@@ -2183,9 +2209,13 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
2183 up_read(&mm->mmap_sem); 2209 up_read(&mm->mmap_sem);
2184 2210
2185 for (i = 0; i < nr_files; i++) { 2211 for (i = 0; i < nr_files; i++) {
2212 char buf[4 * sizeof(long) + 2]; /* max: %lx-%lx\0 */
2213 unsigned int len;
2214
2186 p = flex_array_get(fa, i); 2215 p = flex_array_get(fa, i);
2216 len = snprintf(buf, sizeof(buf), "%lx-%lx", p->start, p->end);
2187 if (!proc_fill_cache(file, ctx, 2217 if (!proc_fill_cache(file, ctx,
2188 p->name, p->len, 2218 buf, len,
2189 proc_map_files_instantiate, 2219 proc_map_files_instantiate,
2190 task, 2220 task,
2191 (void *)(unsigned long)p->mode)) 2221 (void *)(unsigned long)p->mode))
@@ -3018,11 +3048,11 @@ static const struct inode_operations proc_tgid_base_inode_operations = {
3018static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) 3048static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
3019{ 3049{
3020 struct dentry *dentry, *leader, *dir; 3050 struct dentry *dentry, *leader, *dir;
3021 char buf[PROC_NUMBUF]; 3051 char buf[10 + 1];
3022 struct qstr name; 3052 struct qstr name;
3023 3053
3024 name.name = buf; 3054 name.name = buf;
3025 name.len = snprintf(buf, sizeof(buf), "%d", pid); 3055 name.len = snprintf(buf, sizeof(buf), "%u", pid);
3026 /* no ->d_hash() rejects on procfs */ 3056 /* no ->d_hash() rejects on procfs */
3027 dentry = d_hash_and_lookup(mnt->mnt_root, &name); 3057 dentry = d_hash_and_lookup(mnt->mnt_root, &name);
3028 if (dentry) { 3058 if (dentry) {
@@ -3034,7 +3064,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
3034 return; 3064 return;
3035 3065
3036 name.name = buf; 3066 name.name = buf;
3037 name.len = snprintf(buf, sizeof(buf), "%d", tgid); 3067 name.len = snprintf(buf, sizeof(buf), "%u", tgid);
3038 leader = d_hash_and_lookup(mnt->mnt_root, &name); 3068 leader = d_hash_and_lookup(mnt->mnt_root, &name);
3039 if (!leader) 3069 if (!leader)
3040 goto out; 3070 goto out;
@@ -3046,7 +3076,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
3046 goto out_put_leader; 3076 goto out_put_leader;
3047 3077
3048 name.name = buf; 3078 name.name = buf;
3049 name.len = snprintf(buf, sizeof(buf), "%d", pid); 3079 name.len = snprintf(buf, sizeof(buf), "%u", pid);
3050 dentry = d_hash_and_lookup(dir, &name); 3080 dentry = d_hash_and_lookup(dir, &name);
3051 if (dentry) { 3081 if (dentry) {
3052 d_invalidate(dentry); 3082 d_invalidate(dentry);
@@ -3225,14 +3255,14 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx)
3225 for (iter = next_tgid(ns, iter); 3255 for (iter = next_tgid(ns, iter);
3226 iter.task; 3256 iter.task;
3227 iter.tgid += 1, iter = next_tgid(ns, iter)) { 3257 iter.tgid += 1, iter = next_tgid(ns, iter)) {
3228 char name[PROC_NUMBUF]; 3258 char name[10 + 1];
3229 int len; 3259 int len;
3230 3260
3231 cond_resched(); 3261 cond_resched();
3232 if (!has_pid_permissions(ns, iter.task, HIDEPID_INVISIBLE)) 3262 if (!has_pid_permissions(ns, iter.task, HIDEPID_INVISIBLE))
3233 continue; 3263 continue;
3234 3264
3235 len = snprintf(name, sizeof(name), "%d", iter.tgid); 3265 len = snprintf(name, sizeof(name), "%u", iter.tgid);
3236 ctx->pos = iter.tgid + TGID_OFFSET; 3266 ctx->pos = iter.tgid + TGID_OFFSET;
3237 if (!proc_fill_cache(file, ctx, name, len, 3267 if (!proc_fill_cache(file, ctx, name, len,
3238 proc_pid_instantiate, iter.task, NULL)) { 3268 proc_pid_instantiate, iter.task, NULL)) {
@@ -3560,10 +3590,10 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx)
3560 for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns); 3590 for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns);
3561 task; 3591 task;
3562 task = next_tid(task), ctx->pos++) { 3592 task = next_tid(task), ctx->pos++) {
3563 char name[PROC_NUMBUF]; 3593 char name[10 + 1];
3564 int len; 3594 int len;
3565 tid = task_pid_nr_ns(task, ns); 3595 tid = task_pid_nr_ns(task, ns);
3566 len = snprintf(name, sizeof(name), "%d", tid); 3596 len = snprintf(name, sizeof(name), "%u", tid);
3567 if (!proc_fill_cache(file, ctx, name, len, 3597 if (!proc_fill_cache(file, ctx, name, len,
3568 proc_task_instantiate, task, NULL)) { 3598 proc_task_instantiate, task, NULL)) {
3569 /* returning this tgid failed, save it as the first 3599 /* returning this tgid failed, save it as the first