mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Alexey Izbyshev <izbyshev@ispras.ru>
To: Catalin Marinas <catalin.marinas@arm.com>
Cc: David Hildenbrand <david@redhat.com>,
	Florent Revest <revest@chromium.org>,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	akpm@linux-foundation.org, anshuman.khandual@arm.com,
	joey.gouly@arm.com, mhocko@suse.com, keescook@chromium.org,
	peterx@redhat.com, broonie@kernel.org, szabolcs.nagy@arm.com,
	kpsingh@kernel.org, gthelen@google.com, toiwoton@gmail.com
Subject: Re: [PATCH v2 3/5] mm: Make PR_MDWE_REFUSE_EXEC_GAIN an unsigned long
Date: Tue, 23 May 2023 17:46:52 +0300	[thread overview]
Message-ID: <a91012e9cde9046d98713835476cab4b@ispras.ru> (raw)
In-Reply-To: <ZGzJNvKu8h5nDXsa@arm.com>

On 2023-05-23 17:09, Catalin Marinas wrote:
> On Tue, May 23, 2023 at 04:25:45PM +0300, Alexey Izbyshev wrote:
>> On 2023-05-23 16:07, Catalin Marinas wrote:
>> > On Tue, May 23, 2023 at 11:12:37AM +0200, David Hildenbrand wrote:
>> > > Also, how is passing "0"s to e.g., PR_GET_THP_DISABLE reliable? We
>> > > need arg2
>> > > -> arg5 to be 0. But wouldn't the following also just pass a 0 "int" ?
>> > >
>> > > prctl(PR_GET_THP_DISABLE, 0, 0, 0, 0)
>> > >
>> > > I'm easily confused by such (va_args) things, so sorry for the dummy
>> > > questions.
>> >
>> > Isn't the prctl() prototype in the user headers defined with the first
>> > argument as int while the rest as unsigned long? At least from the man
>> > page:
>> >
>> > int prctl(int option, unsigned long arg2, unsigned long arg3,
>> > 	  unsigned long arg4, unsigned long arg5);
>> >
>> > So there are no va_args tricks (which confuse me as well).
>> >
>> I have explicitly mentioned the problem with man pages in my response 
>> to
>> David[1]. Quoting myself:
>> 
>> > This stuff *is* confusing, and note that Linux man pages don't even tell
>> that prctl() is actually declared as a variadic function (and for
>> ptrace() this is mentioned only in the notes, but not in its 
>> signature).
> 
> Ah, thanks for the clarification (I somehow missed your reply).
> 
>> The reality:
>> 
>> * glibc: 
>> https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sys/prctl.h;h=821aeefc1339b35210e8918ecfe9833ed2792626;hb=glibc-2.37#l42
>> 
>> * musl:
>> https://git.musl-libc.org/cgit/musl/tree/include/sys/prctl.h?h=v1.2.4#n180
>> 
>> Though there is a test in the kernel that does define its own 
>> prototype,
>> avoiding the issue: 
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/testing/selftests/sched/cs_prctl_test.c?h=v6.3#n77
> 
> At least for glibc, it seems that there is a conversion to unsigned
> long:
> 
> https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/prctl.c#l28
> 
> unsigned long int arg2 = va_arg (arg, unsigned long int);
> 
> (does va_arg expand to an actual cast?)
> 
No, this not a conversion or a cast in the sense that I think you mean 
it. What happens in the situation discussed in this thread is the 
following (assuming the argument is passed via a register, which is 
typical for initial variadic arguments on 64-bit targets):

* User calls prctl(op, 0) on a 64-bit target.
* The second argument is an int.
* The compiler generates code to pass an int (32 bits) via a 64-bit 
register. The compiler is NOT required to clear the upper 32 bits of the 
register, so they might contain arbitrary junk in a general case.
* The prctl() implementation calls va_arg(arg, unsigned long) (as in 
your quote).
* The compiler extracts the full 64-bit value of the same register 
(which in our case might contain junk in the upper 32 bits).
* This extracted 64-bit value is then passed to the system call.

So...

> If the libc passes a 32-bit to a kernel ABI that expects 64-bit, I 
> think
> it's a user-space bug and not a kernel ABI issue.

... the problem happens not at the user/kernel boundary, but in prctl() 
call/implementation in user space. But yes, it's still a user-space bug 
and not a kernel ABI issue. The David's question, as I understand it, 
was whether we want to keep such buggy code that happens to pass junk 
failing with EINVAL in future kernels or not. If we do want to keep it 
failing, we can never assign any meaning to the upper 32 bits of the 
second prctl() argument for PR_SET_MDWE op.

Thanks,
Alexey

  reply	other threads:[~2023-05-23 14:46 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-17 15:03 [PATCH v2 0/5] MDWE without inheritance Florent Revest
2023-05-17 15:03 ` [PATCH v2 1/5] kselftest: vm: Fix tabs/spaces inconsistency in the mdwe test Florent Revest
2023-05-22  8:52   ` David Hildenbrand
2023-05-17 15:03 ` [PATCH v2 2/5] kselftest: vm: Fix mdwe's mmap_FIXED test case Florent Revest
2023-05-22  8:53   ` David Hildenbrand
2023-05-17 15:03 ` [PATCH v2 3/5] mm: Make PR_MDWE_REFUSE_EXEC_GAIN an unsigned long Florent Revest
2023-05-22  8:55   ` David Hildenbrand
2023-05-22 10:35     ` Alexey Izbyshev
2023-05-22 16:22       ` David Hildenbrand
2023-05-22 18:58         ` Alexey Izbyshev
2023-05-23  9:12           ` David Hildenbrand
2023-05-23 10:53             ` Alexey Izbyshev
2023-05-23 14:10               ` David Hildenbrand
2023-05-26 19:04                 ` Florent Revest
2023-05-23 13:07             ` Catalin Marinas
2023-05-23 13:25               ` Alexey Izbyshev
2023-05-23 14:09                 ` Catalin Marinas
2023-05-23 14:46                   ` Alexey Izbyshev [this message]
2023-05-23 15:01                   ` Szabolcs Nagy
2023-05-26 19:02           ` Florent Revest
2023-05-23 14:11   ` Catalin Marinas
2023-05-17 15:03 ` [PATCH v2 4/5] mm: Add a NO_INHERIT flag to the PR_SET_MDWE prctl Florent Revest
2023-05-22  9:01   ` David Hildenbrand
2023-05-22 16:11     ` Florent Revest
2023-05-23 16:36   ` Catalin Marinas
2023-05-26 19:05     ` Florent Revest
2023-05-17 15:03 ` [PATCH v2 5/5] kselftest: vm: Add tests for no-inherit memory-deny-write-execute Florent Revest

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=a91012e9cde9046d98713835476cab4b@ispras.ru \
    --to=izbyshev@ispras.ru \
    --cc=akpm@linux-foundation.org \
    --cc=anshuman.khandual@arm.com \
    --cc=broonie@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=david@redhat.com \
    --cc=gthelen@google.com \
    --cc=joey.gouly@arm.com \
    --cc=keescook@chromium.org \
    --cc=kpsingh@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mhocko@suse.com \
    --cc=peterx@redhat.com \
    --cc=revest@chromium.org \
    --cc=szabolcs.nagy@arm.com \
    --cc=toiwoton@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®