浏览代码

Merge branch 'core-debug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull wchan kernel address hiding from Ingo Molnar:
 "This fixes a wchan related information leak in /proc/PID/stat.

  There's a bit of an ABI twist to it: instead of setting the wchan
  field to 0 (which is our usual technique) we set it conditionally to a
  0/1 flag to keep ABI compatibility with older procps versions that
  only fetches /proc/PID/wchan (symbolic names) if the absolute wchan
  address is nonzero"

* 'core-debug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  fs/proc, core/debug: Don't expose absolute kernel addresses via wchan
Linus Torvalds 9 年之前
父节点
当前提交
7eeef2abe8
共有 3 个文件被更改,包括 20 次插入10 次删除
  1. 3 2
      Documentation/filesystems/proc.txt
  2. 14 2
      fs/proc/array.c
  3. 3 6
      fs/proc/base.c

+ 3 - 2
Documentation/filesystems/proc.txt

@@ -140,7 +140,8 @@ Table 1-1: Process specific entries in /proc
  stat		Process status
  stat		Process status
  statm		Process memory status information
  statm		Process memory status information
  status		Process status in human readable form
  status		Process status in human readable form
- wchan		If CONFIG_KALLSYMS is set, a pre-decoded wchan
+ wchan		Present with CONFIG_KALLSYMS=y: it shows the kernel function
+		symbol the task is blocked in - or "0" if not blocked.
  pagemap	Page table
  pagemap	Page table
  stack		Report full stack trace, enable via CONFIG_STACKTRACE
  stack		Report full stack trace, enable via CONFIG_STACKTRACE
  smaps		a extension based on maps, showing the memory consumption of
  smaps		a extension based on maps, showing the memory consumption of
@@ -310,7 +311,7 @@ Table 1-4: Contents of the stat files (as of 2.6.30-rc7)
   blocked       bitmap of blocked signals
   blocked       bitmap of blocked signals
   sigign        bitmap of ignored signals
   sigign        bitmap of ignored signals
   sigcatch      bitmap of caught signals
   sigcatch      bitmap of caught signals
-  wchan         address where process went to sleep
+  0		(place holder, used to be the wchan address, use /proc/PID/wchan instead)
   0             (place holder)
   0             (place holder)
   0             (place holder)
   0             (place holder)
   exit_signal   signal to send to parent thread on exit
   exit_signal   signal to send to parent thread on exit

+ 14 - 2
fs/proc/array.c

@@ -375,7 +375,7 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task, int whole)
 			struct pid *pid, struct task_struct *task, int whole)
 {
 {
-	unsigned long vsize, eip, esp, wchan = ~0UL;
+	unsigned long vsize, eip, esp, wchan = 0;
 	int priority, nice;
 	int priority, nice;
 	int tty_pgrp = -1, tty_nr = 0;
 	int tty_pgrp = -1, tty_nr = 0;
 	sigset_t sigign, sigcatch;
 	sigset_t sigign, sigcatch;
@@ -507,7 +507,19 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
 	seq_put_decimal_ull(m, ' ', task->blocked.sig[0] & 0x7fffffffUL);
 	seq_put_decimal_ull(m, ' ', task->blocked.sig[0] & 0x7fffffffUL);
 	seq_put_decimal_ull(m, ' ', sigign.sig[0] & 0x7fffffffUL);
 	seq_put_decimal_ull(m, ' ', sigign.sig[0] & 0x7fffffffUL);
 	seq_put_decimal_ull(m, ' ', sigcatch.sig[0] & 0x7fffffffUL);
 	seq_put_decimal_ull(m, ' ', sigcatch.sig[0] & 0x7fffffffUL);
-	seq_put_decimal_ull(m, ' ', wchan);
+
+	/*
+	 * We used to output the absolute kernel address, but that's an
+	 * information leak - so instead we show a 0/1 flag here, to signal
+	 * to user-space whether there's a wchan field in /proc/PID/wchan.
+	 *
+	 * This works with older implementations of procps as well.
+	 */
+	if (wchan)
+		seq_puts(m, " 1");
+	else
+		seq_puts(m, " 0");
+
 	seq_put_decimal_ull(m, ' ', 0);
 	seq_put_decimal_ull(m, ' ', 0);
 	seq_put_decimal_ull(m, ' ', 0);
 	seq_put_decimal_ull(m, ' ', 0);
 	seq_put_decimal_ll(m, ' ', task->exit_signal);
 	seq_put_decimal_ll(m, ' ', task->exit_signal);

+ 3 - 6
fs/proc/base.c

@@ -430,13 +430,10 @@ static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
 
 
 	wchan = get_wchan(task);
 	wchan = get_wchan(task);
 
 
-	if (lookup_symbol_name(wchan, symname) < 0) {
-		if (!ptrace_may_access(task, PTRACE_MODE_READ))
-			return 0;
-		seq_printf(m, "%lu", wchan);
-	} else {
+	if (wchan && ptrace_may_access(task, PTRACE_MODE_READ) && !lookup_symbol_name(wchan, symname))
 		seq_printf(m, "%s", symname);
 		seq_printf(m, "%s", symname);
-	}
+	else
+		seq_putc(m, '0');
 
 
 	return 0;
 	return 0;
 }
 }