Deutsch   English   Français   Italiano  
<uu3fu0$3gmba$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: James Kuyper <jameskuyper@alumni.caltech.edu>
Newsgroups: comp.lang.c
Subject: Re: A Famous Security Bug
Date: Thu, 28 Mar 2024 06:14:24 -0400
Organization: A noiseless patient Spider
Lines: 59
Message-ID: <uu3fu0$3gmba$1@dont-email.me>
References: <bug-20240320191736@ram.dialup.fu-berlin.de>
 <20240320114218.151@kylheku.com>
 <20240321211306.779b21d126e122556c34a346@gmail.moc>
 <utkea9$31sr2$1@dont-email.me> <utktul$35ng8$1@dont-email.me>
 <utm06k$3glqc$1@dont-email.me> <utme8b$3jtip$1@dont-email.me>
 <utn1a0$3ogob$1@dont-email.me> <utnh5m$3sdhk$1@dont-email.me>
 <20240324185353.00002395@yahoo.com> <utpt4f$ha61$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 28 Mar 2024 10:14:24 +0100 (CET)
Injection-Info: dont-email.me; posting-host="2ceea09d85f2c48031948d5e55584ec0";
	logging-data="3692906"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX19VmawCkPK/Bb2uGkPn0L1ZB0qpHpW/wnQ="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:V7PqRm4v9Xw8OcCyiiIvkGLaCv4=
In-Reply-To: <utpt4f$ha61$1@dont-email.me>
Content-Language: en-US
Bytes: 3636

On 24/03/2024 19:58, bart wrote:
> On 24/03/2024 15:53, Michael S wrote:

>> #include <stdio.h>
>> #include <stddef.h>
>>
>> int main(void)
>> {
>>    char* p0 = (char*)((size_t)main & -(size_t)0x10000);
>>    printf("%c%c\n", p0[0], p0[1]);
>>    return 0;
>> }
>>
>>
>> That would work for small programs. Not necessarily for bigger
>> programs.
>>
> 
> I'm not sure how that works. Are EXE images always loaded at multiple of 
> 64KB? I suppose on larger programs it could search backwards 64KB at a 
> time (although it could also hit on a rogue 'MZ' in program data).
> 
> My point however was whether C considered that p0[0] access UB because 
> it doesn't point into any C data object.

Here's what the standard says about (size_t)main:
"... the result is implementation-defined. If the result cannot be
represented in the integer type, the behavior is undefined. The result
need not be in the range of values of any integer type."

Here's what the standard says about the conversion to char*:
"the result is implementation-defined, might not be correctly aligned,
might not point to an entity of the referenced type, and might produce
an indeterminate representation when stored into an object."

Alignment cannot be an issue with char*, but the other two problems
remain. In particular, I think you're assuming that, when converted back
to a pointer, the resulting pointer will point 0x10000 bytes further on
in memory. There's no such guarantee.

p0[0] is defined as *(p0+0). As a result, the relevant wording occurs in
the description of the unary * operator.

"If the operand points to a function, the result is a function
designator; if it points to an object, the result is an lvalue
designating the object."

Here's the most fundamental problem: there's no guarantee that p0[0]
points at a C object. There's a very good chance, if the code does what
you're hoping it will do, that it points inside a function. As a result,
the following applies:

"If an invalid value has been assigned to the pointer, the behavior of
the unary * operator is undefined."

So, an implementation is free to define the behavior of such code so
that it does what you want - but the C standard doesn't even come close
to mandating that it do so.