[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