lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <884d131bbc28ebfa0b729176e6415269@ispras.ru>
Date:   Mon, 22 May 2023 13:35:07 +0300
From:   Alexey Izbyshev <izbyshev@...ras.ru>
To:     David Hildenbrand <david@...hat.com>
Cc:     Florent Revest <revest@...omium.org>, linux-kernel@...r.kernel.org,
        linux-mm@...ck.org, akpm@...ux-foundation.org,
        catalin.marinas@....com, anshuman.khandual@....com,
        joey.gouly@....com, mhocko@...e.com, keescook@...omium.org,
        peterx@...hat.com, broonie@...nel.org, szabolcs.nagy@....com,
        kpsingh@...nel.org, gthelen@...gle.com, toiwoton@...il.com
Subject: Re: [PATCH v2 3/5] mm: Make PR_MDWE_REFUSE_EXEC_GAIN an unsigned long

On 2023-05-22 11:55, David Hildenbrand wrote:
> On 17.05.23 17:03, Florent Revest wrote:
>> Alexey pointed out that defining a prctl flag as an int is a footgun
>> because, under some circumstances, when used as a flag to prctl, it 
>> can
>> be casted to long with garbage upper bits which would result in
>> unexpected behaviors.
>> 
>> This patch changes the constant to a UL to eliminate these
>> possibilities.
>> 
>> Signed-off-by: Florent Revest <revest@...omium.org>
>> Suggested-by: Alexey Izbyshev <izbyshev@...ras.ru>
>> ---
>>   include/uapi/linux/prctl.h       | 2 +-
>>   tools/include/uapi/linux/prctl.h | 2 +-
>>   2 files changed, 2 insertions(+), 2 deletions(-)
>> 
>> diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
>> index f23d9a16507f..6e9af6cbc950 100644
>> --- a/include/uapi/linux/prctl.h
>> +++ b/include/uapi/linux/prctl.h
>> @@ -283,7 +283,7 @@ struct prctl_mm_map {
>>     /* Memory deny write / execute */
>>   #define PR_SET_MDWE			65
>> -# define PR_MDWE_REFUSE_EXEC_GAIN	1
>> +# define PR_MDWE_REFUSE_EXEC_GAIN	(1UL << 0)
>>     #define PR_GET_MDWE			66
>>   diff --git a/tools/include/uapi/linux/prctl.h 
>> b/tools/include/uapi/linux/prctl.h
>> index 759b3f53e53f..6e6563e97fef 100644
>> --- a/tools/include/uapi/linux/prctl.h
>> +++ b/tools/include/uapi/linux/prctl.h
>> @@ -283,7 +283,7 @@ struct prctl_mm_map {
>>     /* Memory deny write / execute */
>>   #define PR_SET_MDWE			65
>> -# define PR_MDWE_REFUSE_EXEC_GAIN	1
>> +# define PR_MDWE_REFUSE_EXEC_GAIN	(1UL << 0)
>>     #define PR_GET_MDWE			66
>> 
> 
> Both are changing existing uapi, so you'll already have existing user
> space using the old values, that your kernel code has to deal with no?

I'm the one who suggested this change, so I feel the need to clarify.

For any existing 64-bit user space code using the kernel and the uapi 
headers before this patch and doing the wrong prctl(PR_SET_MDWE, 
PR_MDWE_REFUSE_EXEC_GAIN) call instead of the correct prctl(PR_SET_MDWE, 
(unsigned long)PR_MDWE_REFUSE_EXEC_GAIN), there are two possibilities 
when prctl() implementation extracts the second argument via va_arg(op, 
unsigned long):

* It gets lucky, and the upper 32 bits of the argument are zero. The 
call does what is expected by the user.

* The upper 32 bits are non-zero junk. The flags argument is rejected by 
the kernel, and the call fails with EINVAL (unexpectedly for the user).

This change is intended to affect only the second case, and only after 
the program is recompiled with the new uapi headers. The currently 
wrong, but naturally-looking prctl(PR_SET_MDWE, 
PR_MDWE_REFUSE_EXEC_GAIN) call becomes correct.

The kernel ABI is unaffected by this change, since it has been defined 
in terms of unsigned long from the start.

Thanks,
Alexey

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ