base.c (47a469421d792dcb91a1e73319d26134241953d2) base.c (5968cecedd7a09f23e9fcb5f9fb4e893712f35ba)
1/*
2 * linux/fs/proc/base.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 *
6 * proc base directory handling functions
7 *
8 * 1999, Al Viro. Rewritten. Now it covers the whole per-process part.

--- 182 unchanged lines hidden (view full) ---

191
192 if (task) {
193 result = get_task_root(task, path);
194 put_task_struct(task);
195 }
196 return result;
197}
198
1/*
2 * linux/fs/proc/base.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 *
6 * proc base directory handling functions
7 *
8 * 1999, Al Viro. Rewritten. Now it covers the whole per-process part.

--- 182 unchanged lines hidden (view full) ---

191
192 if (task) {
193 result = get_task_root(task, path);
194 put_task_struct(task);
195 }
196 return result;
197}
198
199static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
200 size_t _count, loff_t *pos)
199static int proc_pid_cmdline(struct seq_file *m, struct pid_namespace *ns,
200 struct pid *pid, struct task_struct *task)
201{
201{
202 struct task_struct *tsk;
203 struct mm_struct *mm;
204 char *page;
205 unsigned long count = _count;
206 unsigned long arg_start, arg_end, env_start, env_end;
207 unsigned long len1, len2, len;
208 unsigned long p;
209 char c;
210 ssize_t rv;
211
212 BUG_ON(*pos < 0);
213
214 tsk = get_proc_task(file_inode(file));
215 if (!tsk)
216 return -ESRCH;
217 mm = get_task_mm(tsk);
218 put_task_struct(tsk);
219 if (!mm)
220 return 0;
221 /* Check if process spawned far enough to have cmdline. */
222 if (!mm->env_end) {
223 rv = 0;
224 goto out_mmput;
225 }
226
227 page = (char *)__get_free_page(GFP_TEMPORARY);
228 if (!page) {
229 rv = -ENOMEM;
230 goto out_mmput;
231 }
232
233 down_read(&mm->mmap_sem);
234 arg_start = mm->arg_start;
235 arg_end = mm->arg_end;
236 env_start = mm->env_start;
237 env_end = mm->env_end;
238 up_read(&mm->mmap_sem);
239
240 BUG_ON(arg_start > arg_end);
241 BUG_ON(env_start > env_end);
242
243 len1 = arg_end - arg_start;
244 len2 = env_end - env_start;
245
246 /*
202 /*
247 * Inherently racy -- command line shares address space
248 * with code and data.
203 * Rely on struct seq_operations::show() being called once
204 * per internal buffer allocation. See single_open(), traverse().
249 */
205 */
250 rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0);
251 if (rv <= 0)
252 goto out_free_page;
253
254 rv = 0;
255
256 if (c == '\0') {
257 /* Command line (set of strings) occupies whole ARGV. */
258 if (len1 <= *pos)
259 goto out_free_page;
260
261 p = arg_start + *pos;
262 len = len1 - *pos;
263 while (count > 0 && len > 0) {
264 unsigned int _count;
265 int nr_read;
266
267 _count = min3(count, len, PAGE_SIZE);
268 nr_read = access_remote_vm(mm, p, page, _count, 0);
269 if (nr_read < 0)
270 rv = nr_read;
271 if (nr_read <= 0)
272 goto out_free_page;
273
274 if (copy_to_user(buf, page, nr_read)) {
275 rv = -EFAULT;
276 goto out_free_page;
277 }
278
279 p += nr_read;
280 len -= nr_read;
281 buf += nr_read;
282 count -= nr_read;
283 rv += nr_read;
284 }
285 } else {
286 /*
287 * Command line (1 string) occupies ARGV and maybe
288 * extends into ENVP.
289 */
290 if (len1 + len2 <= *pos)
291 goto skip_argv_envp;
292 if (len1 <= *pos)
293 goto skip_argv;
294
295 p = arg_start + *pos;
296 len = len1 - *pos;
297 while (count > 0 && len > 0) {
298 unsigned int _count, l;
299 int nr_read;
300 bool final;
301
302 _count = min3(count, len, PAGE_SIZE);
303 nr_read = access_remote_vm(mm, p, page, _count, 0);
304 if (nr_read < 0)
305 rv = nr_read;
306 if (nr_read <= 0)
307 goto out_free_page;
308
309 /*
310 * Command line can be shorter than whole ARGV
311 * even if last "marker" byte says it is not.
312 */
313 final = false;
314 l = strnlen(page, nr_read);
315 if (l < nr_read) {
316 nr_read = l;
317 final = true;
318 }
319
320 if (copy_to_user(buf, page, nr_read)) {
321 rv = -EFAULT;
322 goto out_free_page;
323 }
324
325 p += nr_read;
326 len -= nr_read;
327 buf += nr_read;
328 count -= nr_read;
329 rv += nr_read;
330
331 if (final)
332 goto out_free_page;
333 }
334skip_argv:
335 /*
336 * Command line (1 string) occupies ARGV and
337 * extends into ENVP.
338 */
339 if (len1 <= *pos) {
340 p = env_start + *pos - len1;
341 len = len1 + len2 - *pos;
342 } else {
343 p = env_start;
344 len = len2;
345 }
346 while (count > 0 && len > 0) {
347 unsigned int _count, l;
348 int nr_read;
349 bool final;
350
351 _count = min3(count, len, PAGE_SIZE);
352 nr_read = access_remote_vm(mm, p, page, _count, 0);
353 if (nr_read < 0)
354 rv = nr_read;
355 if (nr_read <= 0)
356 goto out_free_page;
357
358 /* Find EOS. */
359 final = false;
360 l = strnlen(page, nr_read);
361 if (l < nr_read) {
362 nr_read = l;
363 final = true;
364 }
365
366 if (copy_to_user(buf, page, nr_read)) {
367 rv = -EFAULT;
368 goto out_free_page;
369 }
370
371 p += nr_read;
372 len -= nr_read;
373 buf += nr_read;
374 count -= nr_read;
375 rv += nr_read;
376
377 if (final)
378 goto out_free_page;
379 }
380skip_argv_envp:
381 ;
382 }
383
384out_free_page:
385 free_page((unsigned long)page);
386out_mmput:
387 mmput(mm);
388 if (rv > 0)
389 *pos += rv;
390 return rv;
206 BUG_ON(m->size < PAGE_SIZE);
207 m->count += get_cmdline(task, m->buf, PAGE_SIZE);
208 return 0;
391}
392
209}
210
393static const struct file_operations proc_pid_cmdline_ops = {
394 .read = proc_pid_cmdline_read,
395 .llseek = generic_file_llseek,
396};
397
398static int proc_pid_auxv(struct seq_file *m, struct pid_namespace *ns,
399 struct pid *pid, struct task_struct *task)
400{
401 struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ);
402 if (mm && !IS_ERR(mm)) {
403 unsigned int nwords = 0;
404 do {
405 nwords += 2;

--- 80 unchanged lines hidden (view full) ---

486 unlock_trace(task);
487 }
488 kfree(entries);
489
490 return err;
491}
492#endif
493
211static int proc_pid_auxv(struct seq_file *m, struct pid_namespace *ns,
212 struct pid *pid, struct task_struct *task)
213{
214 struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ);
215 if (mm && !IS_ERR(mm)) {
216 unsigned int nwords = 0;
217 do {
218 nwords += 2;

--- 80 unchanged lines hidden (view full) ---

299 unlock_trace(task);
300 }
301 kfree(entries);
302
303 return err;
304}
305#endif
306
494#ifdef CONFIG_SCHEDSTATS
307#ifdef CONFIG_SCHED_INFO
495/*
496 * Provides /proc/PID/schedstat
497 */
498static int proc_pid_schedstat(struct seq_file *m, struct pid_namespace *ns,
499 struct pid *pid, struct task_struct *task)
500{
308/*
309 * Provides /proc/PID/schedstat
310 */
311static int proc_pid_schedstat(struct seq_file *m, struct pid_namespace *ns,
312 struct pid *pid, struct task_struct *task)
313{
501 seq_printf(m, "%llu %llu %lu\n",
314 if (unlikely(!sched_info_on()))
315 seq_printf(m, "0 0 0\n");
316 else
317 seq_printf(m, "%llu %llu %lu\n",
502 (unsigned long long)task->se.sum_exec_runtime,
503 (unsigned long long)task->sched_info.run_delay,
504 task->sched_info.pcount);
505
506 return 0;
507}
508#endif
509

--- 2244 unchanged lines hidden (view full) ---

2754#endif
2755#ifdef CONFIG_SCHED_AUTOGROUP
2756 REG("autogroup", S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations),
2757#endif
2758 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
2759#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2760 ONE("syscall", S_IRUSR, proc_pid_syscall),
2761#endif
318 (unsigned long long)task->se.sum_exec_runtime,
319 (unsigned long long)task->sched_info.run_delay,
320 task->sched_info.pcount);
321
322 return 0;
323}
324#endif
325

--- 2244 unchanged lines hidden (view full) ---

2570#endif
2571#ifdef CONFIG_SCHED_AUTOGROUP
2572 REG("autogroup", S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations),
2573#endif
2574 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
2575#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2576 ONE("syscall", S_IRUSR, proc_pid_syscall),
2577#endif
2762 REG("cmdline", S_IRUGO, proc_pid_cmdline_ops),
2578 ONE("cmdline", S_IRUGO, proc_pid_cmdline),
2763 ONE("stat", S_IRUGO, proc_tgid_stat),
2764 ONE("statm", S_IRUGO, proc_pid_statm),
2765 REG("maps", S_IRUGO, proc_pid_maps_operations),
2766#ifdef CONFIG_NUMA
2767 REG("numa_maps", S_IRUGO, proc_pid_numa_maps_operations),
2768#endif
2769 REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
2770 LNK("cwd", proc_cwd_link),

--- 11 unchanged lines hidden (view full) ---

2782 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
2783#endif
2784#ifdef CONFIG_KALLSYMS
2785 ONE("wchan", S_IRUGO, proc_pid_wchan),
2786#endif
2787#ifdef CONFIG_STACKTRACE
2788 ONE("stack", S_IRUSR, proc_pid_stack),
2789#endif
2579 ONE("stat", S_IRUGO, proc_tgid_stat),
2580 ONE("statm", S_IRUGO, proc_pid_statm),
2581 REG("maps", S_IRUGO, proc_pid_maps_operations),
2582#ifdef CONFIG_NUMA
2583 REG("numa_maps", S_IRUGO, proc_pid_numa_maps_operations),
2584#endif
2585 REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
2586 LNK("cwd", proc_cwd_link),

--- 11 unchanged lines hidden (view full) ---

2598 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
2599#endif
2600#ifdef CONFIG_KALLSYMS
2601 ONE("wchan", S_IRUGO, proc_pid_wchan),
2602#endif
2603#ifdef CONFIG_STACKTRACE
2604 ONE("stack", S_IRUSR, proc_pid_stack),
2605#endif
2790#ifdef CONFIG_SCHEDSTATS
2606#ifdef CONFIG_SCHED_INFO
2791 ONE("schedstat", S_IRUGO, proc_pid_schedstat),
2792#endif
2793#ifdef CONFIG_LATENCYTOP
2794 REG("latency", S_IRUGO, proc_lstats_operations),
2795#endif
2796#ifdef CONFIG_PROC_PID_CPUSET
2797 ONE("cpuset", S_IRUGO, proc_cpuset_show),
2798#endif

--- 301 unchanged lines hidden (view full) ---

3100 ONE("limits", S_IRUGO, proc_pid_limits),
3101#ifdef CONFIG_SCHED_DEBUG
3102 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
3103#endif
3104 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
3105#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
3106 ONE("syscall", S_IRUSR, proc_pid_syscall),
3107#endif
2607 ONE("schedstat", S_IRUGO, proc_pid_schedstat),
2608#endif
2609#ifdef CONFIG_LATENCYTOP
2610 REG("latency", S_IRUGO, proc_lstats_operations),
2611#endif
2612#ifdef CONFIG_PROC_PID_CPUSET
2613 ONE("cpuset", S_IRUGO, proc_cpuset_show),
2614#endif

--- 301 unchanged lines hidden (view full) ---

2916 ONE("limits", S_IRUGO, proc_pid_limits),
2917#ifdef CONFIG_SCHED_DEBUG
2918 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
2919#endif
2920 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
2921#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2922 ONE("syscall", S_IRUSR, proc_pid_syscall),
2923#endif
3108 REG("cmdline", S_IRUGO, proc_pid_cmdline_ops),
2924 ONE("cmdline", S_IRUGO, proc_pid_cmdline),
3109 ONE("stat", S_IRUGO, proc_tid_stat),
3110 ONE("statm", S_IRUGO, proc_pid_statm),
3111 REG("maps", S_IRUGO, proc_tid_maps_operations),
2925 ONE("stat", S_IRUGO, proc_tid_stat),
2926 ONE("statm", S_IRUGO, proc_pid_statm),
2927 REG("maps", S_IRUGO, proc_tid_maps_operations),
3112#ifdef CONFIG_PROC_CHILDREN
2928#ifdef CONFIG_CHECKPOINT_RESTORE
3113 REG("children", S_IRUGO, proc_tid_children_operations),
3114#endif
3115#ifdef CONFIG_NUMA
3116 REG("numa_maps", S_IRUGO, proc_tid_numa_maps_operations),
3117#endif
3118 REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
3119 LNK("cwd", proc_cwd_link),
3120 LNK("root", proc_root_link),

--- 9 unchanged lines hidden (view full) ---

3130 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
3131#endif
3132#ifdef CONFIG_KALLSYMS
3133 ONE("wchan", S_IRUGO, proc_pid_wchan),
3134#endif
3135#ifdef CONFIG_STACKTRACE
3136 ONE("stack", S_IRUSR, proc_pid_stack),
3137#endif
2929 REG("children", S_IRUGO, proc_tid_children_operations),
2930#endif
2931#ifdef CONFIG_NUMA
2932 REG("numa_maps", S_IRUGO, proc_tid_numa_maps_operations),
2933#endif
2934 REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
2935 LNK("cwd", proc_cwd_link),
2936 LNK("root", proc_root_link),

--- 9 unchanged lines hidden (view full) ---

2946 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
2947#endif
2948#ifdef CONFIG_KALLSYMS
2949 ONE("wchan", S_IRUGO, proc_pid_wchan),
2950#endif
2951#ifdef CONFIG_STACKTRACE
2952 ONE("stack", S_IRUSR, proc_pid_stack),
2953#endif
3138#ifdef CONFIG_SCHEDSTATS
2954#ifdef CONFIG_SCHED_INFO
3139 ONE("schedstat", S_IRUGO, proc_pid_schedstat),
3140#endif
3141#ifdef CONFIG_LATENCYTOP
3142 REG("latency", S_IRUGO, proc_lstats_operations),
3143#endif
3144#ifdef CONFIG_PROC_PID_CPUSET
3145 ONE("cpuset", S_IRUGO, proc_cpuset_show),
3146#endif

--- 255 unchanged lines hidden ---
2955 ONE("schedstat", S_IRUGO, proc_pid_schedstat),
2956#endif
2957#ifdef CONFIG_LATENCYTOP
2958 REG("latency", S_IRUGO, proc_lstats_operations),
2959#endif
2960#ifdef CONFIG_PROC_PID_CPUSET
2961 ONE("cpuset", S_IRUGO, proc_cpuset_show),
2962#endif

--- 255 unchanged lines hidden ---