[Crash-utility] Re: [PATCH] symbols: handle module symbols outside strbuf

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2023/12/06 11:11, Stephen Brennan wrote:
> HAGIO KAZUHITO(萩尾 一仁)	<k-hagio-ab@xxxxxxx> writes:
> 
>> On 2023/11/28 23:57, Stephen Brennan wrote:
>>> Module symbol names can get overwritten by live patches or ksplice in
>>> odd corner cases, so that the pointer no longer points within the string
>>> buffer. Gracefully fallback to reading the string directly from the
>>> kernel image in these cases, to avoid possible segmentation faults
>>> reading outside the bounds of strbuf.
>>>
>>> Signed-off-by: Stephen Brennan <stephen.s.brennan@xxxxxxxxxx>
>>> ---
>>>
>>> Hi folks - I encountered a segfault on a vmcore which had a module
>>> symbol that had gotten its name overwritten by a ksplice (live patch).
>>> It seems like there's not a guarantee that module symbol names _must_
>>> live within the same symbol buffer, and there is even logic to prevent
>>> reading too much data into strbuf in those cases.
>>
>> Thank you for the report and patch.
>>
>> To me, it seems like the logic is just to cap the buffer size because of
>> adding BUFSIZE.
>>
>> If "last" is outside of a module range, your patch can fix it.  But if
>> "first" is far outside (lower) of the module range, strbuflen becomes
>> huge and crash tries to allocate a huge memory?  Is it possible by ksplice?
> 
> Hi Kazu, thanks for taking a look.
> 
> You're right, if first is far below the module range, then there would
> be a separate bug, and my patch won't address it. I haven't seen a case
> where the symbol name points below the module address range, but I
> believe it's possible.
> 
> The replacement string comes from the ksplice module. So if the ksplice
> module gets allocated to an address below the current module
> (lm->mod_base), the case would happen.

Thanks for the explanation, understood.

> 
> A simple way to address this would be to abort the loop which calculates
> first/last, if we encounter a string which is outside the module address
> range. Something like this:
> 
>   for (i = first = last = 0; i < ngplsyms; i++) {
>   	modsym = (union kernel_symbol *)
>   	    (modsymbuf + (i * kernel_symbol_size));
> +	if (modsym_name(gpl_syms, modsym, i) < lm->mod_base ||
> +            modsym_name(gpl_syms, modsym, i) >= lm->mod_base + lm->mod_size) {
> +		first = last = 0;
> +		break;
> +	}
>   	if (!first
>   	    || first > modsym_name(gpl_syms, modsym, i))
>   		first = modsym_name(gpl_syms, modsym, i);
>   	if (modsym_name(gpl_syms, modsym, i) > last)
>   		last = modsym_name(gpl_syms, modsym, i);
>   }
> 
> With this check, the buffer won't be created unless all the symbols are
> in the contiguous region, so we don't need my added check from this
> patche.

Ah, got it.  I guess that usually the number of modules that their 
symbols are overwritten by ksplice is few in a system?  so I'm ok with 
this approach.

I was thinking about continuing here (not abort) if it's not 
IN_MODULE(name, lm) and using strbuf only for strings in the module. 
but maybe we don't need to do such effort if the number is few.  Also it 
will make store_module_symbols_6_4() a bit confusing, so it might be 
overkill.

> 
> I will send an updated patch if you like this approach.

Please go ahead, I think you can use IN_MODULE().

Thanks,
Kazu
--
Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux