All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stas Sergeev <stsp-cmBhpYW9OiY@public.gmane.org>
To: Oleg Nesterov <oleg-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Linux kernel
	<linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>,
	Ingo Molnar <mingo-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
	Peter Zijlstra <peterz-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>,
	Andrew Morton
	<akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>,
	Amanieu d'Antras
	<amanieu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Richard Weinberger <richard-/L3Ra7n9ekc@public.gmane.org>,
	Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	"Kirill A. Shutemov"
	<kirill.shutemov-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>,
	Jason Low <jason.low2-VXdhtT5mjnY@public.gmane.org>,
	Heinrich Schuchardt <xypron.glpk-Mmb7MZpHnFY@public.gmane.org>,
	Andrea Arcangeli
	<aarcange-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
	Konstantin Khlebnikov
	<khlebnikov-XoJtRXgx1JseBXzfvpsJ4g@public.gmane.org>,
	Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>,
	"Eric W. Biederman"
	<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>,
	Aleksa Sarai <cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org>,
	Paul Moore <pmoore-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
	Palmer Dabbelt <palmer-96lFi9zoCfxBDgjK7y7TUQ@public.gmane.org>,
	Vladimir Davydov
	<vdavydov-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
Subject: Re: [PATCH 4/4] sigaltstack: allow disabling and re-enabling sas within sighandler
Date: Mon, 1 Feb 2016 19:57:45 +0300	[thread overview]
Message-ID: <56AF8E89.5090400@list.ru> (raw)
In-Reply-To: <20160201160625.GA18276-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

01.02.2016 19:06, Oleg Nesterov пишет:
> Honestly, I am not sure I understand what this patch does and why, and it is
> white space damaged, please fix.
Arrr.

> On 01/31, Stas Sergeev wrote:
>> linux implements the sigaltstack() in a way that makes it impossible to
>> use with swapcontext(). Per the man page, sigaltstack is allowed to return
>> EPERM if the process is altering its sigaltstack while running on
>> sigaltstack.
>> This is likely needed to consistently return oss->ss_flags, that indicates
>> whether the process is being on sigaltstack or not.
>> Unfortunately, linux takes that permission to return EPERM too literally:
>> it returns EPERM even if you don't want to change to another sigaltstack,
>> but only want to temporarily disable sigaltstack with SS_DISABLE.
>> You can't use swapcontext() without disabling sigaltstack first, or the
>> stack will be re-used and overwritten by a subsequent signal.
> So iiuc you want to switch the stack from the signal handler running on the
> alt stack, and you need to ensure that another SA_ONSTACK signal won't corrupt
> the alt stack in between, right?
Yes.

> Perhaps you can update the changelog to explain why do we want this change.
Beyond the fact that swapcontext() is then usable for switching
in/out of sigaltstack? But this is already mentioned and I have no
other reason for getting this in.

>> @@ -2550,8 +2551,11 @@ static inline int sas_ss_flags(unsigned long sp)
>>   {
>>       if (!current->sas_ss_size)
>>           return SS_DISABLE;
>> -
>> -    return on_sig_stack(sp) ? SS_ONSTACK : 0;
>> +    if (on_sig_stack(sp))
>> +        return SS_ONSTACK;
>> +    if (current->sas_ss_flags == SS_DISABLE)
>> +        return SS_DISABLE;
>> +    return 0;
> So this always return SS_ONSTACK if on_sig_stack(), see below.
>
>> +        onsigstack = on_sig_stack(sp);
>> +        if (ss_size == 0) {
>> +            switch (ss_flags) {
>> +            case 0:
>> +                error = -EPERM;
>> +                if (onsigstack)
>> +                    goto out;
>> +                current->sas_ss_sp = 0;
>> +                current->sas_ss_size = 0;
>> +                current->sas_ss_flags = SS_DISABLE;
>> +                break;
>> +            case SS_ONSTACK:
>> +                /* re-enable previously disabled sas */
>> +                error = -EINVAL;
>> +                if (current->sas_ss_size == 0)
>> +                    goto out;
>> +                break;
>> +            default:
>> +                break;
>> +            }
> and iiuc the "default" case allows you to write SS_DISABLE into ->sas_ss_flags
> even if on_sig_stack().
>
> So the sequence is
>
> 	// running on alt stack
>
> 	sigaltstack(SS_DISABLE);
>
> 	temporary_run_on_another_stack();
>
> 	sigaltstack(SS_ONSTACK);
>
> and SS_DISABLE saves us from another SA_ONSTACK signal, right?
Yes.
Note: there is a test-case in that patch serie from which
you can see or copy/paste the sample code.

> But afaics it can only help after we change the stack. Suppose that SA_ONSTACK signal
> comess before temporary_run_on_another_stack(). get_sigframe() should be fine after
> your changes (afaics), it won't pick the alt stack after SS_DISABLE.
>
> However, unless I missed something save_altstack_ex() will record SS_ONSTACK in
> uc_stack->ss_flags, and after return from signal handler restore_altstack() will
> enable alt stack again?
I don't think so. Please see the following hunk:

diff --git a/include/linux/signal.h b/include/linux/signal.h
index 92557bb..844b113 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -432,7 +432,7 @@ int __save_altstack(stack_t __user *, unsigned long);
      stack_t __user *__uss = uss; \
      struct task_struct *t = current; \
      put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \
-    put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \
+    put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \
      put_user_ex(t->sas_ss_size, &__uss->ss_size); \
  } while (0);

It pretends as if it changes __save_altstack(), but the reality
is that it actually changes save_altstack_ex(). This is some bug
in git perhaps (or it can't parse macros), I didn't apply any manual
editing to the patch.
The hunk that really modifies __save_altstack() also exists btw:

@@ -3168,7 +3186,7 @@ int __save_altstack(stack_t __user *uss, unsigned 
long sp)
  {
      struct task_struct *t = current;
      return  __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) |
-        __put_user(sas_ss_flags(sp), &uss->ss_flags) |
+        __put_user(t->sas_ss_flags, &uss->ss_flags) |
          __put_user(t->sas_ss_size, &uss->ss_size);
  }

So I understand this is very confusing, but I think the patch
is correct.

Do you think adding the SS_FORCE flag would be a better solution?

WARNING: multiple messages have this Message-ID (diff)
From: Stas Sergeev <stsp@list.ru>
To: Oleg Nesterov <oleg@redhat.com>
Cc: Linux kernel <linux-kernel@vger.kernel.org>,
	linux-api@vger.kernel.org, Andy Lutomirski <luto@amacapital.net>,
	Ingo Molnar <mingo@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	"Amanieu d'Antras" <amanieu@gmail.com>,
	Richard Weinberger <richard@nod.at>, Tejun Heo <tj@kernel.org>,
	"Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>,
	Jason Low <jason.low2@hp.com>,
	Heinrich Schuchardt <xypron.glpk@gmx.de>,
	Andrea Arcangeli <aarcange@redhat.com>,
	Konstantin Khlebnikov <khlebnikov@yandex-team.ru>,
	Josh Triplett <josh@joshtriplett.org>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Aleksa Sarai <cyphar@cyphar.com>, Paul Moore <pmoore@redhat.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Vladimir Davydov <vdavydov@parallels.com>
Subject: Re: [PATCH 4/4] sigaltstack: allow disabling and re-enabling sas within sighandler
Date: Mon, 1 Feb 2016 19:57:45 +0300	[thread overview]
Message-ID: <56AF8E89.5090400@list.ru> (raw)
In-Reply-To: <20160201160625.GA18276@redhat.com>

01.02.2016 19:06, Oleg Nesterov пишет:
> Honestly, I am not sure I understand what this patch does and why, and it is
> white space damaged, please fix.
Arrr.

> On 01/31, Stas Sergeev wrote:
>> linux implements the sigaltstack() in a way that makes it impossible to
>> use with swapcontext(). Per the man page, sigaltstack is allowed to return
>> EPERM if the process is altering its sigaltstack while running on
>> sigaltstack.
>> This is likely needed to consistently return oss->ss_flags, that indicates
>> whether the process is being on sigaltstack or not.
>> Unfortunately, linux takes that permission to return EPERM too literally:
>> it returns EPERM even if you don't want to change to another sigaltstack,
>> but only want to temporarily disable sigaltstack with SS_DISABLE.
>> You can't use swapcontext() without disabling sigaltstack first, or the
>> stack will be re-used and overwritten by a subsequent signal.
> So iiuc you want to switch the stack from the signal handler running on the
> alt stack, and you need to ensure that another SA_ONSTACK signal won't corrupt
> the alt stack in between, right?
Yes.

> Perhaps you can update the changelog to explain why do we want this change.
Beyond the fact that swapcontext() is then usable for switching
in/out of sigaltstack? But this is already mentioned and I have no
other reason for getting this in.

>> @@ -2550,8 +2551,11 @@ static inline int sas_ss_flags(unsigned long sp)
>>   {
>>       if (!current->sas_ss_size)
>>           return SS_DISABLE;
>> -
>> -    return on_sig_stack(sp) ? SS_ONSTACK : 0;
>> +    if (on_sig_stack(sp))
>> +        return SS_ONSTACK;
>> +    if (current->sas_ss_flags == SS_DISABLE)
>> +        return SS_DISABLE;
>> +    return 0;
> So this always return SS_ONSTACK if on_sig_stack(), see below.
>
>> +        onsigstack = on_sig_stack(sp);
>> +        if (ss_size == 0) {
>> +            switch (ss_flags) {
>> +            case 0:
>> +                error = -EPERM;
>> +                if (onsigstack)
>> +                    goto out;
>> +                current->sas_ss_sp = 0;
>> +                current->sas_ss_size = 0;
>> +                current->sas_ss_flags = SS_DISABLE;
>> +                break;
>> +            case SS_ONSTACK:
>> +                /* re-enable previously disabled sas */
>> +                error = -EINVAL;
>> +                if (current->sas_ss_size == 0)
>> +                    goto out;
>> +                break;
>> +            default:
>> +                break;
>> +            }
> and iiuc the "default" case allows you to write SS_DISABLE into ->sas_ss_flags
> even if on_sig_stack().
>
> So the sequence is
>
> 	// running on alt stack
>
> 	sigaltstack(SS_DISABLE);
>
> 	temporary_run_on_another_stack();
>
> 	sigaltstack(SS_ONSTACK);
>
> and SS_DISABLE saves us from another SA_ONSTACK signal, right?
Yes.
Note: there is a test-case in that patch serie from which
you can see or copy/paste the sample code.

> But afaics it can only help after we change the stack. Suppose that SA_ONSTACK signal
> comess before temporary_run_on_another_stack(). get_sigframe() should be fine after
> your changes (afaics), it won't pick the alt stack after SS_DISABLE.
>
> However, unless I missed something save_altstack_ex() will record SS_ONSTACK in
> uc_stack->ss_flags, and after return from signal handler restore_altstack() will
> enable alt stack again?
I don't think so. Please see the following hunk:

diff --git a/include/linux/signal.h b/include/linux/signal.h
index 92557bb..844b113 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -432,7 +432,7 @@ int __save_altstack(stack_t __user *, unsigned long);
      stack_t __user *__uss = uss; \
      struct task_struct *t = current; \
      put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \
-    put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \
+    put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \
      put_user_ex(t->sas_ss_size, &__uss->ss_size); \
  } while (0);

It pretends as if it changes __save_altstack(), but the reality
is that it actually changes save_altstack_ex(). This is some bug
in git perhaps (or it can't parse macros), I didn't apply any manual
editing to the patch.
The hunk that really modifies __save_altstack() also exists btw:

@@ -3168,7 +3186,7 @@ int __save_altstack(stack_t __user *uss, unsigned 
long sp)
  {
      struct task_struct *t = current;
      return  __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) |
-        __put_user(sas_ss_flags(sp), &uss->ss_flags) |
+        __put_user(t->sas_ss_flags, &uss->ss_flags) |
          __put_user(t->sas_ss_size, &uss->ss_size);
  }

So I understand this is very confusing, but I think the patch
is correct.

Do you think adding the SS_FORCE flag would be a better solution?

  parent reply	other threads:[~2016-02-01 16:57 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-31 16:16 [PATCH 0/4] make sigaltstack() compatible with swapcontext() Stas Sergeev
2016-01-31 16:16 ` Stas Sergeev
2016-01-31 16:21 ` [PATCH 2/4] score: signal: fix sigaltstack check Stas Sergeev
2016-02-02 19:07   ` Lennox Wu
2016-01-31 16:24 ` [PATCH 3/4] x86: signal: unify the sigaltstack check with other arches Stas Sergeev
2016-01-31 16:58   ` Andy Lutomirski
2016-01-31 18:03     ` Stas Sergeev
     [not found] ` <56AE3369.2090709-cmBhpYW9OiY@public.gmane.org>
2016-01-31 16:18   ` [PATCH 1/4] selftests: Add test for sigaltstack(SS_DISABLE) inside sighandler Stas Sergeev
2016-01-31 16:18     ` Stas Sergeev
2016-02-12 16:12     ` Shuah Khan
     [not found]       ` <56BE046D.4080203-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
2016-02-12 16:17         ` Stas Sergeev
2016-02-12 16:17           ` Stas Sergeev
2016-01-31 16:28   ` [PATCH 4/4] sigaltstack: allow disabling and re-enabling sas within sighandler Stas Sergeev
2016-01-31 16:28     ` Stas Sergeev
     [not found]     ` <56AE3626.7080706-cmBhpYW9OiY@public.gmane.org>
2016-01-31 17:00       ` Andy Lutomirski
2016-01-31 17:00         ` Andy Lutomirski
2016-01-31 17:33         ` Stas Sergeev
     [not found]           ` <56AE4567.9000403-cmBhpYW9OiY@public.gmane.org>
2016-01-31 19:03             ` Andy Lutomirski
2016-01-31 19:03               ` Andy Lutomirski
     [not found]               ` <CALCETrUVODhNRwvbAfC0q3RVJAFw-ZFGhsww2uQsk3UZjLynnQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-01-31 20:08                 ` Stas Sergeev
2016-01-31 20:08                   ` Stas Sergeev
     [not found]                   ` <56AE69AD.6090005-cmBhpYW9OiY@public.gmane.org>
2016-01-31 20:11                     ` Andy Lutomirski
2016-01-31 20:11                       ` Andy Lutomirski
     [not found]                       ` <CALCETrXPYLqunBNxjS8bpmpg+jG_MXbSyZtUVK3X3m+pGSQ1Og-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-01-31 22:36                         ` Stas Sergeev
2016-01-31 22:36                           ` Stas Sergeev
     [not found]                           ` <56AE8C80.6030408-cmBhpYW9OiY@public.gmane.org>
2016-01-31 22:44                             ` Andy Lutomirski
2016-01-31 22:44                               ` Andy Lutomirski
     [not found]                               ` <CALCETrU2u7h98oqtMcgvU54j21-bpTfBXUEJNQO9r1w5FHc-HQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-01-31 23:45                                 ` Stas Sergeev
2016-01-31 23:45                                   ` Stas Sergeev
2016-02-01 16:06       ` Oleg Nesterov
2016-02-01 16:06         ` Oleg Nesterov
     [not found]         ` <20160201160625.GA18276-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-02-01 16:57           ` Stas Sergeev [this message]
2016-02-01 16:57             ` Stas Sergeev
     [not found]             ` <56AF8E89.5090400-cmBhpYW9OiY@public.gmane.org>
2016-02-01 17:27               ` Oleg Nesterov
2016-02-01 17:27                 ` Oleg Nesterov
2016-02-01 17:09           ` Oleg Nesterov
2016-02-01 17:09             ` Oleg Nesterov
2016-02-01 17:26             ` Stas Sergeev
2016-02-01 18:04               ` Oleg Nesterov
     [not found]                 ` <20160201180443.GA21064-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-02-01 18:16                   ` Stas Sergeev
2016-02-01 18:16                     ` Stas Sergeev
     [not found]                     ` <56AFA0E2.1030302-cmBhpYW9OiY@public.gmane.org>
2016-02-01 18:28                       ` Andy Lutomirski
2016-02-01 18:28                         ` Andy Lutomirski
     [not found]                         ` <CALCETrWv87BS5hH20qKd7WGuf6EAEb4f78Myq+6fqXgSJWoiew-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-02-01 18:40                           ` Stas Sergeev
2016-02-01 18:40                             ` Stas Sergeev
2016-02-01 18:52                       ` Oleg Nesterov
2016-02-01 18:52                         ` Oleg Nesterov
     [not found]                         ` <20160201185223.GA21136-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-02-01 19:01                           ` Stas Sergeev
2016-02-01 19:01                             ` Stas Sergeev
2016-02-01 19:29                             ` Oleg Nesterov
     [not found]                               ` <20160201192936.GA21214-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-02-01 19:46                                 ` Stas Sergeev
2016-02-01 19:46                                   ` Stas Sergeev
2016-02-01 20:41                                   ` Oleg Nesterov
     [not found]                                     ` <20160201204114.GA21638-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-02-01 23:06                                       ` Stas Sergeev
2016-02-01 23:06                                         ` Stas Sergeev
  -- strict thread matches above, loose matches on Subject: below --
2016-01-31 19:10 [PATCH v2 0/4] make sigaltstack() compatible with swapcontext() Stas Sergeev
     [not found] ` <56AE5C08.6010403-cmBhpYW9OiY@public.gmane.org>
2016-01-31 19:18   ` [PATCH 4/4] sigaltstack: allow disabling and re-enabling sas within sighandler Stas Sergeev
2016-01-31 19:18     ` Stas Sergeev

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=56AF8E89.5090400@list.ru \
    --to=stsp-cmbhpyw9oiy@public.gmane.org \
    --cc=aarcange-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org \
    --cc=amanieu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org \
    --cc=ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org \
    --cc=jason.low2-VXdhtT5mjnY@public.gmane.org \
    --cc=josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org \
    --cc=khlebnikov-XoJtRXgx1JseBXzfvpsJ4g@public.gmane.org \
    --cc=kirill.shutemov-VuQAYsv1563Yd54FQh9/CA@public.gmane.org \
    --cc=linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org \
    --cc=mingo-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=oleg-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=palmer-96lFi9zoCfxBDgjK7y7TUQ@public.gmane.org \
    --cc=peterz-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org \
    --cc=pmoore-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=richard-/L3Ra7n9ekc@public.gmane.org \
    --cc=tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=vdavydov-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org \
    --cc=xypron.glpk-Mmb7MZpHnFY@public.gmane.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.