On Mon, Apr 22, 2024 at 10:25:40AM +0200, Jan Beulich wrote:
> On 22.04.2024 09:54, Roger Pau Monné wrote:
> > On Fri, Apr 19, 2024 at 04:34:41PM +0200, Jan Beulich wrote:
> >> On 19.04.2024 12:50, Roger Pau Monné wrote:
> >>> On Fri, Apr 19, 2024 at 12:15:19PM +0200, Jan Beulich wrote:
> >>>> On 19.04.2024 12:02, Roger Pau Monne wrote:
> >>>>> Livepatch payloads containing symbols that belong to init sections can 
> >>>>> only
> >>>>> lead to page faults later on, as by the time the livepatch is loaded 
> >>>>> init
> >>>>> sections have already been freed.
> >>>>>
> >>>>> Refuse to resolve such symbols and return an error instead.
> >>>>>
> >>>>> Note such resolutions are only relevant for symbols that point to 
> >>>>> undefined
> >>>>> sections (SHN_UNDEF), as that implies the symbol is not in the current 
> >>>>> payload
> >>>>> and hence must either be a Xen or a different livepatch payload symbol.
> >>>>>
> >>>>> Do not allow to resolve symbols that point to __init_begin, as that 
> >>>>> address is
> >>>>> also unmapped.  On the other hand, __init_end is not unmapped, and 
> >>>>> hence allow
> >>>>> resolutions against it.
> >>>>>
> >>>>> Signed-off-by: Roger Pau Monné <roger....@citrix.com>
> >>>>> ---
> >>>>> Changes since v1:
> >>>>>  - Fix off-by-one in range checking.
> >>>>
> >>>> Which means you addressed Andrew's comment while at the same time 
> >>>> extending
> >>>> the scope of ...
> >>>>
> >>>>> @@ -310,6 +311,21 @@ int livepatch_elf_resolve_symbols(struct 
> >>>>> livepatch_elf *elf)
> >>>>>                      break;
> >>>>>                  }
> >>>>>              }
> >>>>> +
> >>>>> +            /*
> >>>>> +             * Ensure not an init symbol.  Only applicable to Xen 
> >>>>> symbols, as
> >>>>> +             * livepatch payloads don't have init sections or 
> >>>>> equivalent.
> >>>>> +             */
> >>>>> +            else if ( st_value >= (uintptr_t)&__init_begin &&
> >>>>> +                      st_value < (uintptr_t)&__init_end )
> >>>>> +            {
> >>>>> +                printk(XENLOG_ERR LIVEPATCH
> >>>>> +                       "%s: symbol %s is in init section, not 
> >>>>> resolving\n",
> >>>>> +                       elf->name, elf->sym[i].name);
> >>>>
> >>>> ... what I raised concern about (and I had not seen any verbal reply to 
> >>>> that,
> >>>> I don't think).
> >>>
> >>> I've extended the commit message to explicitly mention the handling of
> >>> bounds for __init_{begin,end} checks.  Let me know if you are not fine
> >>> with it (or maybe you expected something else?).
> >>
> >> Well, you mention the two symbols you care about, but you don't mention
> >> at all that these two may alias other symbols which might be legal to
> >> reference from a livepatch.
> > 
> > I'm having a hard time understanding why a livepatch would want to
> > reference those, or any symbol in the .init sections for that matter.
> > __init_{begin,end} are exclusively used to unmap the init region after
> > boot.  What's the point in livepatch referencing data that's no
> > longer there?  The only application I would think of is to calculate
> > some kind of offsets, but that would better be done using other
> > symbols instead.
> > 
> > Please bear with me, it would be easier for me to understand if you
> > could provide a concrete example.
> 
> The issue is that you do comparison by address, not by name. Let's assume
> that .rodata ends exactly where .init.* starts. Then &__init_begin ==
> &_erodata == &__2M_rodata_end. Access to the latter two symbols wants to
> be permitted; only __init_begin and whatever ends up being the very first
> symbol in .init.* ought to not be referenced.

Hm, I guess I could add comparison by name additionally, but it looks
fragile to me.

So when st_value == __init_begin check if the name matches
"__init_begin" or "__2M_init_start" or "_sinittext", and fail
resolution, otherwise allow it?

> Worse (but contrived) would be cases of "constructed" symbols derived from
> ones ahead of __init_begin, with an offset large enough to actually point
> into .init.*. Such are _still_ valid to be used in calculations, as long
> as no deref occurs for anything at or past __init_begin.

But one would have to craft such a symbol specifically, at which point
I consider this out of the scope of what this patch is attempting to
protect against.  The aim is not to prevent malicious livepatches, and
there are far easier ways to trigger a page-fault from a livepatch.

Thanks, Roger.

Reply via email to