linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Walt Drummond <walt@drummond.us>
To: Luis Chamberlain <mcgrof@kernel.org>,
	Kees Cook <keescook@chromium.org>,
	Iurii Zaikin <yzaikin@google.com>
Cc: linux-kernel@vger.kernel.org, Walt Drummond <walt@drummond.us>,
	linux-fsdevel@vger.kernel.org
Subject: [RFC PATCH 7/8] signals: Add signal debugging
Date: Mon,  3 Jan 2022 10:19:55 -0800	[thread overview]
Message-ID: <20220103181956.983342-8-walt@drummond.us> (raw)
In-Reply-To: <20220103181956.983342-1-walt@drummond.us>

Add CONFIG_SIGNALS_DEBUG, which provides /proc/sys/kern/sigset_size,
/proc/sys/kern/compat_sigset_size (if CONFIG_COMPAT is enabled),
/proc/sys/kern/max_sig and /proc/sys/kern/sigrtmax to indicate sigset
sizes, max signal number (_NSIG) and value of SIGRTMAX respectively.
This also adds /proc/<pid>/signal, which sends a signal number to
<pid> without going through libc.

Signed-off-by: Walt Drummond <walt@drummond.us>
---
 fs/proc/base.c         | 48 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/signal.h |  1 +
 kernel/signal.c        | 15 ++++++++-----
 kernel/sysctl.c        | 41 ++++++++++++++++++++++++++++++++++++
 lib/Kconfig.debug      | 10 +++++++++
 5 files changed, 110 insertions(+), 5 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 533d5836eb9a..75184abf9af1 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -3165,6 +3165,51 @@ static int proc_stack_depth(struct seq_file *m, struct pid_namespace *ns,
 }
 #endif /* CONFIG_STACKLEAK_METRICS */
 
+#ifdef CONFIG_SIGNALS_DEBUG
+static ssize_t proc_signal_write(struct file *file, const char __user *buf,
+				   size_t count, loff_t *ppos)
+{
+	struct inode *inode = file_inode(file);
+	struct task_struct *task = get_proc_task(inode);
+	int ret;
+	pid_t pid;
+	unsigned long sig = (unsigned long) -1;
+
+	if (!task)
+		return -ESRCH;
+	if (*ppos != 0)
+		/* No partial writes. */
+		return -EINVAL;
+
+	if (count > 4 || count <= 1)
+		return -EINVAL;
+
+	ret = kstrtoul_from_user(buf, count, 10, &sig);
+	if (ret != 0)
+		return -EINVAL;
+
+	if (!valid_signal(sig))
+		return -EINVAL;
+	if (sig == 0)
+		return count;
+
+	pid = pid_vnr(get_task_pid(task, PIDTYPE_PID));
+	if (pid == 0)
+		return -EINVAL;
+
+	ret = do_sys_kill(pid, sig);
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static const struct file_operations proc_signal_operations = {
+	.write		= proc_signal_write,
+	.llseek		= noop_llseek,
+};
+#endif	/* CONFIG_SIGNALS_DEBUG */
+
 /*
  * Thread groups
  */
@@ -3281,6 +3326,9 @@ static const struct pid_entry tgid_base_stuff[] = {
 #ifdef CONFIG_SECCOMP_CACHE_DEBUG
 	ONE("seccomp_cache", S_IRUSR, proc_pid_seccomp_cache),
 #endif
+#ifdef CONFIG_SIGNALS_DEBUG
+	REG("signal",  S_IWUSR, proc_signal_operations),
+#endif
 };
 
 static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx)
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 4084b765a6cc..b77f9472a37c 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -446,6 +446,7 @@ extern bool get_signal(struct ksignal *ksig);
 extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping);
 extern void exit_signals(struct task_struct *tsk);
 extern void kernel_sigaction(int, __sighandler_t);
+extern int do_sys_kill(pid_t pid, int sig);
 
 #define SIG_KTHREAD ((__force __sighandler_t)2)
 #define SIG_KTHREAD_KERNEL ((__force __sighandler_t)3)
diff --git a/kernel/signal.c b/kernel/signal.c
index 9c846a017201..1ed392df55fb 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3755,6 +3755,15 @@ static inline void prepare_kill_siginfo(int sig, struct kernel_siginfo *info)
 	info->si_uid = from_kuid_munged(current_user_ns(), current_uid());
 }
 
+int do_sys_kill(pid_t pid, int sig)
+{
+	struct kernel_siginfo info;
+
+	prepare_kill_siginfo(sig, &info);
+
+	return kill_something_info(sig, &info, pid);
+}
+
 /**
  *  sys_kill - send a signal to a process
  *  @pid: the PID of the process
@@ -3762,11 +3771,7 @@ static inline void prepare_kill_siginfo(int sig, struct kernel_siginfo *info)
  */
 SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
 {
-	struct kernel_siginfo info;
-
-	prepare_kill_siginfo(sig, &info);
-
-	return kill_something_info(sig, &info, pid);
+	return do_sys_kill(pid, sig);
 }
 
 /*
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 083be6af29d7..0d7e1d16b75b 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -139,6 +139,15 @@ static int minolduid;
 static int ngroups_max = NGROUPS_MAX;
 static const int cap_last_cap = CAP_LAST_CAP;
 
+#ifdef CONFIG_SIGNALS_DEBUG
+static int max_signal = _NSIG;
+static int sigrtmax = SIGRTMAX;
+static int sigset_size = sizeof(sigset_t);
+# ifdef CONFIG_COMPAT
+static int compat_sigset_size = sizeof(compat_sigset_t);
+# endif
+#endif
+
 /*
  * This is needed for proc_doulongvec_minmax of sysctl_hung_task_timeout_secs
  * and hung_task_check_interval_secs
@@ -2717,6 +2726,38 @@ static struct ctl_table kern_table[] = {
 		.extra1		= SYSCTL_ZERO,
 		.extra2		= SYSCTL_ONE,
 	},
+#endif
+#ifdef CONFIG_SIGNALS_DEBUG
+	{
+		.procname	= "max_signal",
+		.data		= &max_signal,
+		.maxlen		= sizeof(int),
+		.mode		= 0444,
+		.proc_handler	= proc_dointvec,
+	},
+	{
+		.procname	= "sigrtmax",
+		.data		= &sigrtmax,
+		.maxlen		= sizeof(int),
+		.mode		= 0444,
+		.proc_handler	= proc_dointvec,
+	},
+	{
+		.procname	= "sigset_size",
+		.data		= &sigset_size,
+		.maxlen		= sizeof(int),
+		.mode		= 0444,
+		.proc_handler	= proc_dointvec,
+	},
+# ifdef CONFIG_COMPAT
+	{
+		.procname	= "compat_sigset_size",
+		.data		= &compat_sigset_size,
+		.maxlen		= sizeof(int),
+		.mode		= 0444,
+		.proc_handler	= proc_dointvec,
+	},
+# endif
 #endif
 	{ }
 };
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 2a9b6dcdac4f..c433356c1070 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2639,4 +2639,14 @@ endmenu # "Kernel Testing and Coverage"
 
 source "Documentation/Kconfig"
 
+config SIGNALS_DEBUG
+       bool "Enable basic signals debugging"
+       default n
+       help
+	 Provides several files in /proc to aid in debugging changes to
+	 the signals code: /proc/sys/kernel/max_signal,
+	 /proc/sys/kernel/sigrtmax and /proc/sys/kernel/sigset_size.
+	 Also adds /proc/<pid>/signal to allow sending a signal number
+	 to <pid> without going through libc.
+
 endmenu # Kernel hacking
-- 
2.30.2


  parent reply	other threads:[~2022-01-03 18:34 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-03 18:19 [RFC PATCH 0/8] signals: Support more than 64 signals Walt Drummond
2022-01-03 18:19 ` [RFC PATCH 1/8] signals: Make the real-time signal system calls accept different sized sigset_t from user space Walt Drummond
2022-01-03 18:19 ` [RFC PATCH 2/8] signals: Put the full signal mask on the signal stack for x86_64, X32 and ia32 compatibility mode Walt Drummond
2022-01-03 18:19 ` [RFC PATCH 3/8] signals: Use a helper function to test if a signal is a real-time signal Walt Drummond
2022-01-03 18:19 ` [RFC PATCH 4/8] signals: Remove sigmask() macro Walt Drummond
2022-01-03 18:19 ` [RFC PATCH 5/8] signals: Better support cases where _NSIG_WORDS is greater than 2 Walt Drummond
2022-01-03 18:19 ` [RFC PATCH 6/8] signals: Round up _NSIG_WORDS Walt Drummond
2022-01-03 18:19 ` Walt Drummond [this message]
2022-01-03 18:19 ` [RFC PATCH 8/8] signals: Support BSD VSTATUS, KERNINFO and SIGINFO Walt Drummond
2022-01-04  7:27   ` Greg Kroah-Hartman
2022-01-07 21:48   ` Arseny Maslennikov
2022-01-07 21:52     ` Walt Drummond
2022-01-07 22:39       ` Arseny Maslennikov
2022-01-08 14:38   ` Arseny Maslennikov
2022-01-03 18:48 ` [RFC PATCH 0/8] signals: Support more than 64 signals Al Viro
2022-01-04  1:00   ` Walt Drummond
2022-01-04  1:16     ` Al Viro
2022-01-04  1:49       ` Al Viro
2022-01-04 18:00 ` Eric W. Biederman
2022-01-04 20:52   ` Theodore Ts'o
2022-01-04 21:33     ` Walt Drummond
2022-01-04 22:05     ` Eric W. Biederman
2022-01-04 22:23       ` Theodore Ts'o
2022-01-04 22:31         ` Walt Drummond
2022-01-07 19:29           ` Arseny Maslennikov
2022-05-19 12:27             ` Pavel Machek
2022-01-07 19:19     ` Arseny Maslennikov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220103181956.983342-8-walt@drummond.us \
    --to=walt@drummond.us \
    --cc=keescook@chromium.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mcgrof@kernel.org \
    --cc=yzaikin@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).