All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christophe LEROY <christophe.leroy@c-s.fr>
To: Michael Neuling <mikey@neuling.org>, mpe@ellerman.id.au
Cc: linuxppc-dev@lists.ozlabs.org,
	"Nicholas Piggin" <npiggin@gmail.com>,
	paulus@ozlabs.org, "Haren Myneni" <haren@linux.vnet.ibm.com>,
	"Michal Suchánek" <msuchanek@suse.de>
Subject: Re: [PATCH v2] powerpc: Avoid code patching freed init sections
Date: Thu, 13 Sep 2018 07:45:44 +0200	[thread overview]
Message-ID: <3cc9302c-4399-50cc-0ec2-87552eb2080c@c-s.fr> (raw)
In-Reply-To: <29d3467a9314f5b80f93d241ae2566c48b546bfe.camel@neuling.org>



Le 13/09/2018 à 02:36, Michael Neuling a écrit :
> 
>>> --- a/arch/powerpc/lib/code-patching.c
>>> +++ b/arch/powerpc/lib/code-patching.c
>>> @@ -23,11 +23,33 @@
>>>    #include <asm/code-patching.h>
>>>    #include <asm/setup.h>
>>>    
>>> +
>>
>> This blank line is not needed
> 
> Ack
> 
>>
>>> +static inline bool in_init_section(unsigned int *patch_addr)
>>> +{
>>> +	if (patch_addr < (unsigned int *)__init_begin)
>>> +		return false;
>>> +	if (patch_addr >= (unsigned int *)__init_end)
>>> +		return false;
>>> +	return true;
>>> +}
>>
>> Can we use the existing function init_section_contains() instead of this
>> new function ?
> 
> Nice, I was looking for something like that...
> 
>>> +
>>> +static inline bool init_freed(void)
>>> +{
>>> +	return (system_state >= SYSTEM_RUNNING);
>>> +}
>>> +
>>
>> I would call this function differently, for instance init_is_finished(),
>> because as you mentionned it doesn't exactly mean that init memory is freed.
> 
> Talking to Nick and mpe offline I think we are going to have to add a flag when
> we free init mem rather than doing what we have now since what we have now has a
> potential race. That change will eliminate the function entirely.
> 
>>>    static int __patch_instruction(unsigned int *exec_addr, unsigned int
>>> instr,
>>>    			       unsigned int *patch_addr)
>>>    {
>>>    	int err;
>>>    
>>> +	/* Make sure we aren't patching a freed init section */
>>> +	if (in_init_section(patch_addr) && init_freed()) {
>>
>> The test must be done on exec_addr, not on patch_addr, as patch_addr is
>> the address where the instruction as been remapped RW for allowing its
>> modification.
> 
> Thanks for the catch
> 
>> Also I think it should be tested the other way round, because the
>> init_freed() is a simpler test which will be false most of the time once
>> the system is running so it should be checked first.
> 
> ok, I'll change.
> 
>>> +		printk(KERN_DEBUG "Skipping init section patching addr:
>>> 0x%lx\n",
>>
>> Maybe use pr_debug() instead.
> 
> Sure.
> 
>>
>>> +			(unsigned long)patch_addr);
>>
>> Please align second line as per Codying style.
> 
> Sorry I can't see what's wrong. You're (or Cody :-P) going to have to spell it
> this out for me...
> 
>>
>>> +		return 0;
>>> +	}
>>> +
>>>    	__put_user_size(instr, patch_addr, 4, err);
>>>    	if (err)
>>>    		return err;
>>>
>>
>> I think it would be better to put this verification in
>> patch_instruction() instead, to avoid RW mapping/unmapping the
>> instruction to patch when we are not going to do the patching.
> 
> If we do it there then we miss the raw_patch_intruction case.

raw_patch_instruction() can only be used during init. Once kernel memory 
has been marked readonly, raw_patch_instruction() cannot be used 
anymore. And mark_readonly() is called immediately after free_initmem()

Christophe


> 
> IMHO I don't think we need to optimise this rare and non-critical path.
> 
> Mikey
> 

      parent reply	other threads:[~2018-09-13  5:45 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-12  5:20 [PATCH v2] powerpc: Avoid code patching freed init sections Michael Neuling
2018-09-12  6:23 ` Christophe LEROY
2018-09-13  0:36   ` Michael Neuling
2018-09-13  1:21     ` Tyrel Datwyler
2018-09-13  5:38       ` Christophe LEROY
2018-09-13  5:48         ` Michael Neuling
2018-09-13  5:45     ` Christophe LEROY [this message]

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=3cc9302c-4399-50cc-0ec2-87552eb2080c@c-s.fr \
    --to=christophe.leroy@c-s.fr \
    --cc=haren@linux.vnet.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mikey@neuling.org \
    --cc=mpe@ellerman.id.au \
    --cc=msuchanek@suse.de \
    --cc=npiggin@gmail.com \
    --cc=paulus@ozlabs.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.