On Thu, Dec 29, 2022 at 11:27:01AM -0800, John Reiser wrote:
On 12/21/22 13:49, Ben Cotton wrote:
>
https://fedoraproject.org/wiki/Changes/XServerProhibitsByteSwappedClients
> X server implementations (e.g. Xorg and Xwayland) allow clients with
> an endianess different to that of the server to connect. Protocol
> messages to and from these clients are byte-swapped by the X server.
> However, the code in the X server that does this is virtually
> untested, providing a large attack surface for malicious clients.
There is a technological solution which eradicates the byte-swapped
attack surface. All existing byte-swapping bugs (known and unknown)
are fixed, and all future byte-swapping bugs are prevented.
In C++, re-code each 'struct' by using a typedef for each
member that can suffer byte-swapping. Create a template for
each struct containing such members, where the typedefs for
members are template parameters for the templated struct.
Create a template for each function which uses such structs,
again with the typedefs as template parameters (possibly subsumed
inside other templated objects.)
When the X server accepts a connection from a client of different
endian-ness, then automatic template instantiation and matching
by the C++ compiler will invoke the correct top-level function(s),
which will invoke the correct lower-level functions.
An example is
https://github.com/upx/upx/blob/devel/src/p_mach.h
and p_mach.cpp, which handles both width (32 vs 64) and endian-ness
for processing any Mach-O executable by the UPX program compressor
running on any machine (same or different width and endian-ness).
A years-earlier "by-hand" example of related coding in plain-C is
scripts/recordmcount.c in the source code for Linux kernel.
Interesting approach, but the X server is written in C, introducing C++
is not going to happen in a project that's in maintenance mode. Even if
anyone could find the time to do it and figure out how to test all the
changes afterwards.
It's not all structs either (and there's *a lot* of thos, probably well
over 1000), sometimes it's something like this:
struct XSomething *foo;
uint32_t len = (uint32_t*)(foo + 1);
and other similar approaches. Which means not every 16/32 bit number is
part of a struct.
Cheers,
Peter