Warning: mysqli::__construct(): (HY000/1203): User howardkn already has more than 'max_user_connections' active connections in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\includes\artfuncs.php on line 21
Failed to connect to MySQL: (1203) User howardkn already has more than 'max_user_connections' active connectionsPath: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: James Kuyper 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: References: <20240320114218.151@kylheku.com> <20240321211306.779b21d126e122556c34a346@gmail.moc> <20240324185353.00002395@yahoo.com> 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: Content-Language: en-US Bytes: 3636 On 24/03/2024 19:58, bart wrote: > On 24/03/2024 15:53, Michael S wrote: >> #include >> #include >> >> 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.