All of lore.kernel.org
 help / color / mirror / Atom feed
From: James Morse <james.morse-5wv7dgnIgG8@public.gmane.org>
To: Dave Martin <Dave.Martin-5wv7dgnIgG8@public.gmane.org>
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-arch-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>,
	Russell King <linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>,
	"Eric W. Biederman"
	<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>,
	Catalin Marinas <catalin.marinas-5wv7dgnIgG8@public.gmane.org>
Subject: Re: [RFC PATCH v2 3/3] arm64: signal: Ensure si_code is valid for all fault signals
Date: Tue, 13 Feb 2018 18:00:16 +0000	[thread overview]
Message-ID: <5A8327B0.7080204@arm.com> (raw)
In-Reply-To: <20180213152207.GP5862-M5GwZQ6tE7x5pKCnmE3YQBJ8xKzm50AiAL8bYrjMMd8@public.gmane.org>

Hi Dave,

On 13/02/18 15:22, Dave Martin wrote:
> On Tue, Feb 13, 2018 at 01:58:55PM +0000, James Morse wrote:
>> On 30/01/18 18:50, Dave Martin wrote:
>>> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
>>> index 9b7f89d..4baa922 100644
>>> --- a/arch/arm64/mm/fault.c
>>> +++ b/arch/arm64/mm/fault.c
>>> @@ -607,70 +607,70 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>> [..]
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 0 (translation table walk)"	},
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 1 (translation table walk)"	},
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 2 (translation table walk)"	},
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 3 (translation table walk)"	},
>>> +	{ do_sea,		SIGBUS,  BUS_OBJERR,	"synchronous parity or ECC error" },	// Reserved when RAS is implemented
>>
>> I agree the translation-table related external-aborts should end up with
>> SIGKILL: there is nothing user-space can do.
>>
>> You use the fault_info table to vary the signal and si_code that should be used,
>> but do_mem_abort() only uses these if the fn returns an error. For do_sea(),
>> regardless of the values in this table SIGBUS will be generated as it always
>> returns 0.
>>
>>
>>> @@ -596,7 +596,7 @@ static int do_sea(unsigned long addr, unsigned int esr,
>> struct pt_regs *regs)
>>>
>>>  	info.si_signo = SIGBUS;
>>>  	info.si_errno = 0;
>>> -	info.si_code  = 0;
>>> +	info.si_code  = BUS_OBJERR;
>>>  	if (esr & ESR_ELx_FnV)
>>>  		info.si_addr = NULL;
>>>  	else
>>
>> do_sea() has the right fault_info entry to hand, so I think these need to change
>> to inf->sig and inf->code. (I assume its not valid to set si_addr for SIGKILL...)
> 
> Yes, I guess that makes sense.
> 
> For SIGKILL, I'm assuming that it is harmless to populate si_addr: even
> though not strictly valid, the signal is never delivered to userspace.
> Even ptrace cannot see SIGKILL -- the trace just disappears and further
> ptrace calls fail with ESRCH.

Good point!


> If is matters, I guess we could prepopulate si_uid = si_pid = 0 for
> this case.  That's at least cleaner, so I might do that.
> 
> 
> For do_sea:
> 
> I was thinking of the fault_info[] table entries as for the fallback
> case only, but (a) I also try to use them to affect what do_sea() does
> (which, as you observe, doesn't work right now), and (b) there's no
> reason why they shouldn't inform what fn does.

Sure,


> However, rather than duplicate code I wonder whether we can just
> rearrange do_mem_abort() so that the lines
> 
> 	info.si_signo = inf->sig;
> 	info.si_errno = 0;
> 	info.si_code  = inf->code;
> 	info.si_addr  = (void __user *)addr;
> 
> are moved ahead of the call to inf->fn().
> 
> This would have the effect of pre-populating info with sane defaults
> while still allowing inf->fn() to override them if appropriate.

I like the idea. It's a bit strange that do_mem_abort() looks up the table entry
to call the handler, which looks up the table entry to find out what it should
do. (__do_user_fault() already does this).

This would change all of 'fn's prototypes, to save the struct-siginfo
duplication in do_sea() and __do_user_fault().

Should the 'leaf' helpers still send the signal, or update the siginfo and
return back to do_mem_abort()? Getting things like do_alignment_fault() in a
kernel stack trace is the only reason I can see...


Thanks,

James

WARNING: multiple messages have this Message-ID (diff)
From: James Morse <james.morse@arm.com>
To: Dave Martin <Dave.Martin@arm.com>
Cc: linux-arm-kernel@lists.infradead.org, linux-arch@vger.kernel.org,
	linux-api@vger.kernel.org, Will Deacon <will.deacon@arm.com>,
	Russell King <linux@armlinux.org.uk>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Catalin Marinas <catalin.marinas@arm.com>
Subject: Re: [RFC PATCH v2 3/3] arm64: signal: Ensure si_code is valid for all fault signals
Date: Tue, 13 Feb 2018 18:00:16 +0000	[thread overview]
Message-ID: <5A8327B0.7080204@arm.com> (raw)
Message-ID: <20180213180016.KAA98kH0FcbGgwCPt-wwb9p-LLvoGYC9d0oZeMJejRA@z> (raw)
In-Reply-To: <20180213152207.GP5862@e103592.cambridge.arm.com>

Hi Dave,

On 13/02/18 15:22, Dave Martin wrote:
> On Tue, Feb 13, 2018 at 01:58:55PM +0000, James Morse wrote:
>> On 30/01/18 18:50, Dave Martin wrote:
>>> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
>>> index 9b7f89d..4baa922 100644
>>> --- a/arch/arm64/mm/fault.c
>>> +++ b/arch/arm64/mm/fault.c
>>> @@ -607,70 +607,70 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>> [..]
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 0 (translation table walk)"	},
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 1 (translation table walk)"	},
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 2 (translation table walk)"	},
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 3 (translation table walk)"	},
>>> +	{ do_sea,		SIGBUS,  BUS_OBJERR,	"synchronous parity or ECC error" },	// Reserved when RAS is implemented
>>
>> I agree the translation-table related external-aborts should end up with
>> SIGKILL: there is nothing user-space can do.
>>
>> You use the fault_info table to vary the signal and si_code that should be used,
>> but do_mem_abort() only uses these if the fn returns an error. For do_sea(),
>> regardless of the values in this table SIGBUS will be generated as it always
>> returns 0.
>>
>>
>>> @@ -596,7 +596,7 @@ static int do_sea(unsigned long addr, unsigned int esr,
>> struct pt_regs *regs)
>>>
>>>  	info.si_signo = SIGBUS;
>>>  	info.si_errno = 0;
>>> -	info.si_code  = 0;
>>> +	info.si_code  = BUS_OBJERR;
>>>  	if (esr & ESR_ELx_FnV)
>>>  		info.si_addr = NULL;
>>>  	else
>>
>> do_sea() has the right fault_info entry to hand, so I think these need to change
>> to inf->sig and inf->code. (I assume its not valid to set si_addr for SIGKILL...)
> 
> Yes, I guess that makes sense.
> 
> For SIGKILL, I'm assuming that it is harmless to populate si_addr: even
> though not strictly valid, the signal is never delivered to userspace.
> Even ptrace cannot see SIGKILL -- the trace just disappears and further
> ptrace calls fail with ESRCH.

Good point!


> If is matters, I guess we could prepopulate si_uid = si_pid = 0 for
> this case.  That's at least cleaner, so I might do that.
> 
> 
> For do_sea:
> 
> I was thinking of the fault_info[] table entries as for the fallback
> case only, but (a) I also try to use them to affect what do_sea() does
> (which, as you observe, doesn't work right now), and (b) there's no
> reason why they shouldn't inform what fn does.

Sure,


> However, rather than duplicate code I wonder whether we can just
> rearrange do_mem_abort() so that the lines
> 
> 	info.si_signo = inf->sig;
> 	info.si_errno = 0;
> 	info.si_code  = inf->code;
> 	info.si_addr  = (void __user *)addr;
> 
> are moved ahead of the call to inf->fn().
> 
> This would have the effect of pre-populating info with sane defaults
> while still allowing inf->fn() to override them if appropriate.

I like the idea. It's a bit strange that do_mem_abort() looks up the table entry
to call the handler, which looks up the table entry to find out what it should
do. (__do_user_fault() already does this).

This would change all of 'fn's prototypes, to save the struct-siginfo
duplication in do_sea() and __do_user_fault().

Should the 'leaf' helpers still send the signal, or update the siginfo and
return back to do_mem_abort()? Getting things like do_alignment_fault() in a
kernel stack trace is the only reason I can see...


Thanks,

James

WARNING: multiple messages have this Message-ID (diff)
From: james.morse@arm.com (James Morse)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH v2 3/3] arm64: signal: Ensure si_code is valid for all fault signals
Date: Tue, 13 Feb 2018 18:00:16 +0000	[thread overview]
Message-ID: <5A8327B0.7080204@arm.com> (raw)
In-Reply-To: <20180213152207.GP5862@e103592.cambridge.arm.com>

Hi Dave,

On 13/02/18 15:22, Dave Martin wrote:
> On Tue, Feb 13, 2018 at 01:58:55PM +0000, James Morse wrote:
>> On 30/01/18 18:50, Dave Martin wrote:
>>> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
>>> index 9b7f89d..4baa922 100644
>>> --- a/arch/arm64/mm/fault.c
>>> +++ b/arch/arm64/mm/fault.c
>>> @@ -607,70 +607,70 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>> [..]
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 0 (translation table walk)"	},
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 1 (translation table walk)"	},
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 2 (translation table walk)"	},
>>> +	{ do_sea,		SIGKILL, SI_KERNEL,	"level 3 (translation table walk)"	},
>>> +	{ do_sea,		SIGBUS,  BUS_OBJERR,	"synchronous parity or ECC error" },	// Reserved when RAS is implemented
>>
>> I agree the translation-table related external-aborts should end up with
>> SIGKILL: there is nothing user-space can do.
>>
>> You use the fault_info table to vary the signal and si_code that should be used,
>> but do_mem_abort() only uses these if the fn returns an error. For do_sea(),
>> regardless of the values in this table SIGBUS will be generated as it always
>> returns 0.
>>
>>
>>> @@ -596,7 +596,7 @@ static int do_sea(unsigned long addr, unsigned int esr,
>> struct pt_regs *regs)
>>>
>>>  	info.si_signo = SIGBUS;
>>>  	info.si_errno = 0;
>>> -	info.si_code  = 0;
>>> +	info.si_code  = BUS_OBJERR;
>>>  	if (esr & ESR_ELx_FnV)
>>>  		info.si_addr = NULL;
>>>  	else
>>
>> do_sea() has the right fault_info entry to hand, so I think these need to change
>> to inf->sig and inf->code. (I assume its not valid to set si_addr for SIGKILL...)
> 
> Yes, I guess that makes sense.
> 
> For SIGKILL, I'm assuming that it is harmless to populate si_addr: even
> though not strictly valid, the signal is never delivered to userspace.
> Even ptrace cannot see SIGKILL -- the trace just disappears and further
> ptrace calls fail with ESRCH.

Good point!


> If is matters, I guess we could prepopulate si_uid = si_pid = 0 for
> this case.  That's at least cleaner, so I might do that.
> 
> 
> For do_sea:
> 
> I was thinking of the fault_info[] table entries as for the fallback
> case only, but (a) I also try to use them to affect what do_sea() does
> (which, as you observe, doesn't work right now), and (b) there's no
> reason why they shouldn't inform what fn does.

Sure,


> However, rather than duplicate code I wonder whether we can just
> rearrange do_mem_abort() so that the lines
> 
> 	info.si_signo = inf->sig;
> 	info.si_errno = 0;
> 	info.si_code  = inf->code;
> 	info.si_addr  = (void __user *)addr;
> 
> are moved ahead of the call to inf->fn().
> 
> This would have the effect of pre-populating info with sane defaults
> while still allowing inf->fn() to override them if appropriate.

I like the idea. It's a bit strange that do_mem_abort() looks up the table entry
to call the handler, which looks up the table entry to find out what it should
do. (__do_user_fault() already does this).

This would change all of 'fn's prototypes, to save the struct-siginfo
duplication in do_sea() and __do_user_fault().

Should the 'leaf' helpers still send the signal, or update the siginfo and
return back to do_mem_abort()? Getting things like do_alignment_fault() in a
kernel stack trace is the only reason I can see...


Thanks,

James

  parent reply	other threads:[~2018-02-13 18:00 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-30 18:50 [RFC PATCH v2 0/3] arm64: Fix invalid si_codes for fault signals Dave Martin
2018-01-30 18:50 ` Dave Martin
2018-01-30 18:50 ` Dave Martin
     [not found] ` <1517338243-9749-1-git-send-email-Dave.Martin-5wv7dgnIgG8@public.gmane.org>
2018-01-30 18:50   ` [RFC PATCH v2 1/3] signal: Add FPE_FLTUNK si_code for undiagnosable fp exceptions Dave Martin
2018-01-30 18:50     ` Dave Martin
2018-01-30 18:50     ` Dave Martin
2018-01-30 18:50   ` [RFC PATCH v2 2/3] arm64: fpsimd: Fix bad si_code for undiagnosed SIGFPE Dave Martin
2018-01-30 18:50     ` Dave Martin
2018-01-30 18:50     ` Dave Martin
2018-01-30 18:50   ` [RFC PATCH v2 3/3] arm64: signal: Ensure si_code is valid for all fault signals Dave Martin
2018-01-30 18:50     ` Dave Martin
2018-01-30 18:50     ` Dave Martin
2018-02-13 13:58     ` James Morse
2018-02-13 13:58       ` James Morse
2018-02-13 15:22       ` Dave Martin
2018-02-13 15:22         ` Dave Martin
     [not found]         ` <20180213152207.GP5862-M5GwZQ6tE7x5pKCnmE3YQBJ8xKzm50AiAL8bYrjMMd8@public.gmane.org>
2018-02-13 18:00           ` James Morse [this message]
2018-02-13 18:00             ` James Morse
2018-02-13 18:00             ` James Morse

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=5A8327B0.7080204@arm.com \
    --to=james.morse-5wv7dgnigg8@public.gmane.org \
    --cc=Dave.Martin-5wv7dgnIgG8@public.gmane.org \
    --cc=catalin.marinas-5wv7dgnIgG8@public.gmane.org \
    --cc=ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org \
    --cc=linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org \
    --cc=linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-arch-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=will.deacon-5wv7dgnIgG8@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.