> On 2022/Apr/26, at 01:01, Sergei Trofimovich <sly...@gmail.com> wrote:
> 
> On Tue, 26 Apr 2022 02:43:00 +0000
> Pedro Miguel Justo <pm...@texair.net> wrote:
> 
>>> On 2022/Apr/25, at 14:27, Pedro Miguel Justo <pm...@texair.net> wrote:
>>> 
>>> 
>>> 
>>>> On 2022/Apr/25, at 14:09, Sergei Trofimovich <sly...@gmail.com> wrote:
>>>> 
>>>> On Mon, 25 Apr 2022 15:07:58 +0000
>>>> Pedro Miguel Justo <pm...@texair.net> wrote:
>>>> 
>>>>>> On 2022/Apr/25, at 01:22, Pedro Miguel Justo <pm...@texair.net> wrote:
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>>> On 2022/Apr/25, at 01:14, Frank Scheiner <frank.schei...@web.de> wrote:
>>>>>>> 
>>>>>>> Hi guys,
>>>>>>> 
>>>>>>> On 25.04.22 10:09, John Paul Adrian Glaubitz wrote:    
>>>>>>>>> From what I can understand by the information in the bugcheck, this 
>>>>>>>>> is somewhat related to a violation
>>>>>>>>> in parameter copy from user to kernel during some boot-time, crypto, 
>>>>>>>>> self-test. Does that sound right?
>>>>>>>>> If that is the case, how would this be related to FW?    
>>>>>>>> 
>>>>>>>> I'm not claiming that it must be related to the firmware, I'm just 
>>>>>>>> saying that I don't see this problem
>>>>>>>> on my RX2660 at all and I have even reinstalled it recently with one 
>>>>>>>> of the latest firmware images
>>>>>>>> without having to pass any parameter to the command line.    
>>>>>>> 
>>>>>>> A difference between Adrian's rx2660 and Pedro's rx2660 is Montecito
>>>>>>> left and Montvale right.
>>>>>>> 
>>>>>>> But could still be multiple other reasons we haven't looked at yet in
>>>>>>> detail:
>>>>>>> 
>>>>>>> * amount of memory installed
>>>>>>> * SMT enabled or not
>>>>>>> * number of processor modules installed
>>>>>>> 
>>>>>>> It might be possible for me to check on my rx2660s (one with Montvale
>>>>>>> and one with Montecito(s)) tomorrow. I will then also look at my other
>>>>>>> Itanium gear and gather relevant information.
>>>>>>> 
>>>>>> 
>>>>>> Yes, this sounds mode likely to me too.
>>>>>> 
>>>>>> The crypto self-tests seem to be an innocent bystander here. I tried 
>>>>>> booting the most recent kernel with the option “cryptomgr.notests” and 
>>>>>> it went much farther. Alas it still failed with another buffer copy 
>>>>>> validation for a different caller altogether:
>>>>>> 
>>>>>> [    3.836466]  [<a000000101353690>] usercopy_abort+0x120/0x130
>>>>>> [    3.836466]                                 sp=e0000001000cfdf0 
>>>>>> bsp=e0000001000c9388
>>>>>> [    3.836466]  [<a0000001004c5660>] __check_object_size+0x3c0/0x420
>>>>>> [    3.836466]                                 sp=e0000001000cfe00 
>>>>>> bsp=e0000001000c9350
>>>>>> [    3.836466]  [<a000000100570030>] sys_getcwd+0x250/0x420
>>>>>> [    3.836466]                                 sp=e0000001000cfe00 
>>>>>> bsp=e0000001000c92c8
>>>>>> [    3.836466]  [<a00000010000c860>] ia64_ret_from_syscall+0x0/0x20
>>>>>> [    3.836466]                                 sp=e0000001000cfe30 
>>>>>> bsp=e0000001000c92c8
>>>>>> [    3.836466]  [<a000000000040720>] ia64_ivt+0xffffffff00040720/0x400
>>>>>> [    3.836466]                                 sp=e0000001000d0000 
>>>>>> bsp=e0000001000c92c8
>>>>>> 
>>>>>> This suggests the bug might be in the logic validating these buffers 
>>>>>> against the allocations (heap, span, etc).
>>>>>> 
>>>>>> I don’t know why hardened_usercopy=off is not being observed by the 
>>>>>> kernel. As a work-around I am copying myself a new kernel with 
>>>>>> CONFIG_HARDENED_USERCOPY disabled at the source.   
>> 
>> So, I finished compiling my kernel with CONFIG_HARDENED_USERCOPY disabled. 
>> Guess what:
>> 
>> pmsjt@debian:~$ uname -a
>> Linux debian 5.17.3-rt17 #2 SMP Mon Apr 25 16:55:00 PDT 2022 ia64 GNU/Linux
>> 
>> Yup, the system starts just fine with the most recent kernel. So, two things 
>> we can infer from this:
>> - Yes, usercopy validation appears to be broken. The contours of how broken 
>> it is are yet unknown but we’ll have to investigate to see what part of the 
>> validation is failing.
> 
> My vague memory tells me that the breakage mechanics is the following:
> 
> 1. [ok] mm/usercopy.c:check_kernel_text_object() gets called on various 
> kernel addresses
> 2. [ok] ia64 address space has at least two widely used kernel addresses:
>        - 0xe0000000_00000000-0xe000..ff-ffffffff - proper linear mapping, 
> 0xe0000000_00000000 + phys
>                                                    (so called, RGN_KERNEL = 7)
>        - 0xa0000001_00000000-0xa0000000_00ffffff - kernel ~linear mapping, 
> 0xa0000001_00000000 + phys
>                                                    (so called, RGN_GATE = 5)
> 
> Both are easy to translate to proper linear address, but the translations
> are not identical. Note that RGN_GATE has an offset.
> 
> ia64's stack for some reason lives in RGN_KERNEL space (probably due to
> historical reasons before kernel switched to vmapped stacks on other arches).
> You can see these addresses in backtraces as
>    sp=e0000001000cfdf0 bsp=e0000001000c9388
> 
> ia64's kernel code on the other hand lives in RGN_GATE.
> You can see these addresses in backtraces as
>    [<a000000101353690>] usercopy_abort+0x120/0x130
> 
> Now, check_kernel_text_object() compares passed kernel address for 2 ranges:
> - RGN_GATE:
>    unsigned long textlow = (unsigned long)_stext;
>    unsigned long texthigh = (unsigned long)_etext;
>    if (overlaps(ptr, n, textlow, texthigh))
>        usercopy_abort("kernel text", NULL, to_user, ptr - textlow, n);
> 
>    I think this check is correct. There is no address translation.
> 
> - RGN_KERNEL:
>    textlow_linear = (unsigned long)lm_alias(textlow);
>    texthigh_linear = (unsigned long)lm_alias(texthigh);
>    if (overlaps(ptr, n, textlow_linear, texthigh_linear))
>        usercopy_abort("linear kernel text", NULL, to_user,...
> 
>    I think this one is wrong. Looking at the definition of lm_alias()
>    it can ge used only on RGN_KERNEL addresses (which looks useless,
>    they are already in correct form) and literal symbol names:
> 
>      include/linux/mm.h:#define lm_alias(x)  __va(__pa_symbol(x))
>      include/linux/mm.h:#define __pa_symbol(x)  __pa(RELOC_HIDE((unsigned 
> long)(x), 0))
>      arch/ia64/include/asm/page.h:#define __pa(x)            ({ia64_va _v; 
> _v.l = (long) (x); _v.f.reg = 0; _v.l;})
>      #define __va(x)            ({ia64_va _v; _v.l = (long) (x); _v.f.reg = 
> -1; _v.p;})
> 
> I think that means __pa_symbol(x) against local variables like textlow
> is completely broken. 
> 
> If lm_alias() works at all on ia64 maybe that is enough to unbreak usercoy:
> 
> --- a/mm/usercopy.c
> +++ b/mm/usercopy.c
> @@ -133,13 +133,13 @@ static inline void check_kernel_text_object(const 
> unsigned long ptr,
>         * __pa() is not just the reverse of __va(). This can be detected
>         * and checked:
>         */
> -       textlow_linear = (unsigned long)lm_alias(textlow);
> +       textlow_linear = (unsigned long)lm_alias(_stext);
>        /* No different mapping: we're done. */
>        if (textlow_linear == textlow)
>                return;
> 
>        /* Check the secondary mapping... */
> -       texthigh_linear = (unsigned long)lm_alias(texthigh);
> +       texthigh_linear = (unsigned long)lm_alias(_etext);
>        if (overlaps(ptr, n, textlow_linear, texthigh_linear))
>                usercopy_abort("linear kernel text", NULL, to_user,
>                               ptr - textlow_linear, n);
> 
> If not here is an ia64-specific workaround:
> 
> --- a/mm/usercopy.c
> +++ b/mm/usercopy.c
> @@ -133,13 +133,13 @@ static inline void check_kernel_text_object(const 
> unsigned long ptr,
>         * __pa() is not just the reverse of __va(). This can be detected
>         * and checked:
>         */
> -       textlow_linear = (unsigned long)lm_alias(textlow);
> +       textlow_linear = (unsigned long)ia64_imva(textlow);
>        /* No different mapping: we're done. */
>        if (textlow_linear == textlow)
>                return;
> 
>        /* Check the secondary mapping... */
> -       texthigh_linear = (unsigned long)lm_alias(texthigh);
> +       texthigh_linear = (unsigned long)ia64_imva(texthigh);
>        if (overlaps(ptr, n, textlow_linear, texthigh_linear))
>                usercopy_abort("linear kernel text", NULL, to_user,
>                               ptr - textlow_linear, n);
> 
> CAVEAT: I did not compile- or run- test it. Might need a bit of pointer/long 
> casting around.
> 

I don’t mind at all giving this a try. Sounds quite plausible.

Do you think the stacks (and RSE) will eventually have to move from RGN_KERNEL 
to vmapped the same as other archs to avoid issues like this and other to come?

>> - hardened_usercopy=off seems to be ignored by current kernels. When passing 
>> this option the system was still failing just the same.
> 
> I wonder how you are passing that flag to the kernel. Just a grub parameter 
> to kernel?
> Worth specifying it first and last to make sure if does not get eaten by 
> intermediate
> flags (in case there is a parser bug).
> 
>>>>>> 
>>>>> 
>>>>> Even with kernel "Linux debian 4.19.0-5-mckinley #1 SMP Debian 4.19.37-5 
>>>>> (2019-06-19) ia64 GNU/Linux"
>>>>> 
>>>>> Things are still not 100%. After a few hours into building the kernel it 
>>>>> started crashing also with usercopy validations but, this time, the other 
>>>>> way around. And because it was the other way around, it led to process 
>>>>> termination instead of full-blown bugcheck. This could be related or not. 
>>>>> Coule very well be a different bug that happens to manifest itself round 
>>>>> the same validation.
>>>>> 
>>>>> CC [M]  drivers/net/wireless/realtek/rtw88/rtw8822be.o
>>>>> LD [M]  drivers/net/wireless/realtek/rtw88/rtw88_8822be.o
>>>>> CC [M]  drivers/net/wireless/realtek/rtw88/rtw8822c.o
>>>>> Segmentation fault
>>>>> make[5]: *** [scripts/Makefile.build:293: 
>>>>> drivers/net/wireless/realtek/rtw88/rtw8822c.o] Error 139
>>>>> make[5]: *** Deleting file 'drivers/net/wireless/realtek/rtw88/rtw8822c.o'
>>>>> make[4]: *** [scripts/Makefile.build:555: 
>>>>> drivers/net/wireless/realtek/rtw88] Error 2
>>>>> make[3]: *** [scripts/Makefile.build:555: drivers/net/wireless/realtek] 
>>>>> Error 2
>>>>> make[2]: *** [scripts/Makefile.build:555: drivers/net/wireless] Error 2
>>>>> make[1]: *** [scripts/Makefile.build:555: drivers/net] Error 2
>>>>> make: *** [Makefile:1855: drivers] Error 2
>>>>> pmsjt@debian:~/linux-source-5.17$ make
>>>>> 
>>>>> Message from syslogd@debian at Apr 25 07:58:08 ...
>>>>> kernel:[23420.984012] usercopy: Kernel memory overwrite attempt detected 
>>>>> to linear kernel text (offset 1916912, size 8)!
>>>>> 
>>>>> Message from syslogd@debian at Apr 25 07:58:08 ...
>>>>> kernel:[23421.268009] usercopy: Kernel memory overwrite attempt detected 
>>>>> to linear kernel text (offset 1818608, size 8)!
>>>>> HOSTCC  scripts/sign-file
>>>>> CALL    scripts/checksyscalls.sh
>>>>> <stdin>:1517:2: warning: #warning syscall clone3 not implemented [-Wcpp]
>>>>> CALL    scripts/atomic/check-atomics.sh
>>>>> CHK     include/generated/compile.h
>>>>> make[2]: *** [scripts/Makefile.build:294: arch/ia64/kernel/signal.o] 
>>>>> Segmentation fault
>>>>> 
>>>>> Message from syslogd@debian at Apr 25 07:58:11 ...
>>>>> kernel:[23423.626254] usercopy: Kernel memory overwrite attempt detected 
>>>>> to linear kernel text (offset 1933296, size 8)!
>>>>> make[1]: *** [scripts/Makefile.build:555: arch/ia64/kernel] Error 2
>>>>> make: *** [Makefile:1855: arch/ia64] Error 2  
>>>> 
>>> 
>>> Hi Sergei
>>> 
>>>> In my understanding hardened_usercopy=on is completely broken on ia64
>>>> today. It can't run any userspace. Even init process would not survive
>>>> machine boot. At least that's what I experienced on rx3600.
>>>> 
>>>> Thus I think if your system survives that much time I would guess
>>>> that you have hardened_usercopy=off in full effect at least at boot.
>>>> 
>>> 
>>> I want to make sure there is no confusion here. My system only ’survives’ 
>>> this much when I am using the 4.19 kernel (even when the 
>>> hardened_usercopy=off is not present). With kernels more recent than that 
>>> the system will bugcheck very early on boot even if hardened_usercopy=off 
>>> is present.
>>> 
>>>> I would speculate it's some kind of memory corruption around
>>>> 'bypass_usercopy_checks' key.
>>>> 
>>>> Worth adding a few printk()s to mm/usercopy.c into 'usercopy_abort()'
>>>> and into 'set_hardened_usercopy()' just to make sure 
>>>> 'bypass_usercopy_checks'
>>>> has expected 'true' setting at boot time and at crash time.  
>>> 
>>> Right - we definitively need more context about what is the root cause and 
>>> characteristics of the bug. When the failure happens, is the (pointer, 
>>> range) of the copy really out-of-whack, or is the validation code not 
>>> making sense of the boundaries and over-actively failing.
>>> 
>>>> 
>>>> -- 
>>>> 
>>>> Sergei  
>>> 
>> 
> 
> 
> -- 
> 
>  Sergei

Reply via email to