[CRIU] [PATCH 07/10] check: check PTRACE_PEEKSIGINFO and sigqueueinfo with positive si_code
Alexander Kartashov
alekskartashov at parallels.com
Thu Mar 7 11:26:35 EST 2013
On 03/05/2013 06:54 PM, Andrey Vagin wrote:
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
> cr-check.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 53 insertions(+)
>
> diff --git a/cr-check.c b/cr-check.c
> index 89a8589..539bb09 100644
> --- a/cr-check.c
> +++ b/cr-check.c
> @@ -5,6 +5,8 @@
> #include <sys/epoll.h>
> #include <sys/inotify.h>
> #include <sys/signalfd.h>
> +#include <sys/ptrace.h>
> +#include <sys/wait.h>
> #include <fcntl.h>
> #include <signal.h>
> #include <linux/if.h>
> @@ -22,6 +24,7 @@
> #include "proc_parse.h"
> #include "mount.h"
> #include "tty.h"
> +#include "ptrace.h"
>
> static int check_tty(void)
> {
> @@ -429,6 +432,54 @@ static int check_ipc(void)
> return -1;
> }
>
> +int check_sigqueuinfo()
> +{
> + siginfo_t info = { .si_code = 1 };
> +
> + signal(SIGUSR1, SIG_IGN);
> +
> + if (sys_rt_sigqueueinfo(getpid(), SIGUSR1, &info)) {
> + pr_perror("Unable to send siginfo with positive si_code to itself");
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +int check_ptrace_peeksiginfo()
> +{
> + struct ptrace_peeksiginfo_args arg;
> + siginfo_t siginfo;
> + pid_t pid, ret = 0;
> +
> + pid = fork();
> + if (pid < 0)
> + pr_perror("fork");
> + else if (pid == 0) {
> + while (1)
> + sleep(1000);
> + exit(1);
> + }
> +
> + if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1)
> + return 1;
> +
> + waitpid(pid, NULL, 0);
> +
> + arg.flags = 0;
> + arg.off = 0;
> + arg.nr = 1;
> +
> + if (ptrace(PTRACE_PEEKSIGINFO, pid, &arg, &siginfo) != 0) {
> + pr_perror("Unable to dump pending signals\n");
> + ret = 1;
> + }
> +
> + ptrace(PTRACE_KILL, pid, NULL, NULL);
> +
> + return ret;
> +}
> +
> int cr_check(void)
> {
> int ret = 0;
> @@ -454,6 +505,8 @@ int cr_check(void)
> ret |= check_tty();
> ret |= check_so_gets();
> ret |= check_ipc();
> + ret |= check_sigqueuinfo();
> + ret |= check_ptrace_peeksiginfo();
>
> if (!ret)
> pr_msg("Looks good.\n");
Is the corresponding kernel code is available in the linux-cr kernel
repository?
I got the following error:
(00.027464) Error (cr-check.c:442): Unable to send siginfo with positive
si_code to itself: Input/output error
(00.052480) Error (cr-check.c:474): Unable to dump pending signals
: Input/output error
The error message is deceiving since it's actually -EPERM.
This case is explicitly prohibited by the kernel:
SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig,
siginfo_t __user *, uinfo)
[...]
/* Not even root can pretend to send signals from the kernel.
* Nor can they impersonate a kill()/tgkill(), which adds source info.
*/
if (info.si_code >= 0 || info.si_code == SI_TKILL) {
/* We used to allow any < 0 si_code */
WARN_ON_ONCE(info.si_code < 0);
return -EPERM;
}
--
Sincerely yours,
Alexander Kartashov
Intern
Core team
www.parallels.com
Skype: aleksandr.kartashov
Email: alekskartashov at parallels.com
More information about the CRIU
mailing list