Disallow byte-swapped clients on Fedora 38 and above

Resolves: #2159489
This commit is contained in:
Olivier Fourdan 2023-01-17 13:35:52 +01:00
parent ed1c5b0be5
commit 764fdb6d82
4 changed files with 249 additions and 1 deletions

View File

@ -0,0 +1,69 @@
From 5f0f99c817cdcf0c258962f3039afc6483698388 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Mon, 19 Dec 2022 10:34:29 +1000
Subject: [PATCH xserver 1/3] Fix some indentation issues
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 73d6e888c6058b28a0e87ab65aa4172b17d8327d)
---
dix/dispatch.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 460296197..4fc99b170 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -492,10 +492,10 @@ Dispatch(void)
if (!WaitForSomething(clients_are_ready()))
continue;
- /*****************
- * Handle events in round robin fashion, doing input between
- * each round
- *****************/
+ /*****************
+ * Handle events in round robin fashion, doing input between
+ * each round
+ *****************/
if (!dispatchException && clients_are_ready()) {
client = SmartScheduleClient();
@@ -3657,11 +3657,11 @@ ProcInitialConnection(ClientPtr client)
prefix = (xConnClientPrefix *) ((char *)stuff + sz_xReq);
order = prefix->byteOrder;
if (order != 'l' && order != 'B' && order != 'r' && order != 'R')
- return client->noClientException = -1;
+ return client->noClientException = -1;
if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
- (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) {
- client->swapped = TRUE;
- SwapConnClientPrefix(prefix);
+ (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) {
+ client->swapped = TRUE;
+ SwapConnClientPrefix(prefix);
}
stuff->reqType = 2;
stuff->length += bytes_to_int32(prefix->nbytesAuthProto) +
@@ -3670,7 +3670,7 @@ ProcInitialConnection(ClientPtr client)
swaps(&stuff->length);
}
if (order == 'r' || order == 'R') {
- client->local = FALSE;
+ client->local = FALSE;
}
ResetCurrentRequest(client);
return Success;
@@ -3781,8 +3781,8 @@ ProcEstablishConnection(ClientPtr client)
auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
- pad_to_int32(prefix->nbytesAuthProto) +
- pad_to_int32(prefix->nbytesAuthString))
+ pad_to_int32(prefix->nbytesAuthProto) +
+ pad_to_int32(prefix->nbytesAuthString))
reason = "Bad length";
else if ((prefix->majorVersion != X_PROTOCOL) ||
(prefix->minorVersion != X_PROTOCOL_REVISION))
--
2.39.0

View File

@ -0,0 +1,50 @@
From da6398e4e13aa2866232df6f896c75751cc7cb46 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Tue, 20 Dec 2022 11:40:16 +1000
Subject: [PATCH xserver 2/3] dix: localize two variables
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit f69280ddcdd3115ee4717f22e85e0f43569b60dd)
---
dix/dispatch.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 4fc99b170..2efa2dcf1 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3771,14 +3771,11 @@ int
ProcEstablishConnection(ClientPtr client)
{
const char *reason;
- char *auth_proto, *auth_string;
xConnClientPrefix *prefix;
REQUEST(xReq);
prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq);
- auth_proto = (char *) prefix + sz_xConnClientPrefix;
- auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
pad_to_int32(prefix->nbytesAuthProto) +
@@ -3787,12 +3784,15 @@ ProcEstablishConnection(ClientPtr client)
else if ((prefix->majorVersion != X_PROTOCOL) ||
(prefix->minorVersion != X_PROTOCOL_REVISION))
reason = "Protocol version mismatch";
- else
+ else {
+ char *auth_proto = (char *) prefix + sz_xConnClientPrefix;
+ char *auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
reason = ClientAuthorized(client,
(unsigned short) prefix->nbytesAuthProto,
auth_proto,
(unsigned short) prefix->nbytesAuthString,
auth_string);
+ }
return (SendConnSetup(client, reason));
}
--
2.39.0

View File

@ -0,0 +1,117 @@
From 068862767ef95ebc54977e1df49ab700c20ae347 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Tue, 20 Dec 2022 10:42:03 +1000
Subject: [PATCH xserver 3/3] Disallow byte-swapped clients by default
The X server swapping code is a huge attack surface, much of this code
is untested and prone to security issues. The use-case of byte-swapped
clients is very niche, so let's disable this by default and allow it
only when the respective config option or commandline flag is given.
For Xorg, this adds the ServerFlag "AllowByteSwappedClients" "on".
For all DDX, this adds the commandline options +byteswappedclients and
-byteswappedclients to enable or disable, respectively.
Fixes #1201
https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1029
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 412777664a20dd3561b936c02c96571a756fe9b2)
---
dix/dispatch.c | 4 +++-
hw/xwayland/xwayland.pc.in | 1 +
include/opaque.h | 2 ++
man/Xserver.man | 6 ++++++
os/utils.c | 9 +++++++++
5 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 2efa2dcf1..0570ec07c 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3777,7 +3777,9 @@ ProcEstablishConnection(ClientPtr client)
prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq);
- if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
+ if (client->swapped && !AllowByteSwappedClients) {
+ reason = "Prohibited client endianess, see the Xserver man page ";
+ } else if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
pad_to_int32(prefix->nbytesAuthProto) +
pad_to_int32(prefix->nbytesAuthString))
reason = "Bad length";
diff --git a/hw/xwayland/xwayland.pc.in b/hw/xwayland/xwayland.pc.in
index 9d727b002..e920d7608 100644
--- a/hw/xwayland/xwayland.pc.in
+++ b/hw/xwayland/xwayland.pc.in
@@ -12,3 +12,4 @@ have_listenfd=true
have_verbose=true
have_terminate_delay=true
have_no_touch_pointer_emulation=true
+have_byteswappedclients=true
diff --git a/include/opaque.h b/include/opaque.h
index 256261c2a..398d4b4e5 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -74,4 +74,6 @@ extern _X_EXPORT Bool bgNoneRoot;
extern _X_EXPORT Bool CoreDump;
extern _X_EXPORT Bool NoListenAll;
+extern _X_EXPORT Bool AllowByteSwappedClients;
+
#endif /* OPAQUE_H */
diff --git a/man/Xserver.man b/man/Xserver.man
index 764bd1d90..e7adf9eb3 100644
--- a/man/Xserver.man
+++ b/man/Xserver.man
@@ -114,6 +114,12 @@ pattern. This is the default unless -retro or -wr is specified.
.B \-bs
disables backing store support on all screens.
.TP 8
+.B \+byteswappedclients
+Allow connections from clients with an endianess different to that of the server.
+.TP 8
+.B \-byteswappedclients
+Prohibit connections from clients with an endianess different to that of the server.
+.TP 8
.B \-c
turns off key-click.
.TP 8
diff --git a/os/utils.c b/os/utils.c
index c9a8e7367..6f5e64cee 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -189,6 +189,8 @@ Bool CoreDump;
Bool enableIndirectGLX = FALSE;
+Bool AllowByteSwappedClients = FALSE;
+
#ifdef PANORAMIX
Bool PanoramiXExtensionDisabledHack = FALSE;
#endif
@@ -523,6 +525,8 @@ UseMsg(void)
ErrorF("-br create root window with black background\n");
ErrorF("+bs enable any backing store support\n");
ErrorF("-bs disable any backing store support\n");
+ ErrorF("+byteswappedclients Allow clients with endianess different to that of the server\n");
+ ErrorF("-byteswappedclients Prohibit clients with endianess different to that of the server\n");
ErrorF("-c turns off key-click\n");
ErrorF("c # key-click volume (0-100)\n");
ErrorF("-cc int default color visual class\n");
@@ -720,6 +724,11 @@ ProcessCommandLine(int argc, char *argv[])
else
UseMsg();
}
+ else if (strcmp(argv[i], "-byteswappedclients") == 0) {
+ AllowByteSwappedClients = FALSE;
+ } else if (strcmp(argv[i], "+byteswappedclients") == 0) {
+ AllowByteSwappedClients = TRUE;
+ }
else if (strcmp(argv[i], "-br") == 0); /* default */
else if (strcmp(argv[i], "+bs") == 0)
enableBackingStore = TRUE;
--
2.39.0

View File

@ -9,7 +9,7 @@
Summary: Xwayland
Name: xorg-x11-server-Xwayland
Version: 22.1.7
Release: 1%{?gitdate:.%{gitdate}git%{shortcommit}}%{?dist}
Release: 2%{?gitdate:.%{gitdate}git%{shortcommit}}%{?dist}
URL: http://www.x.org
%if 0%{?gitdate}
@ -18,6 +18,15 @@ Source0: https://gitlab.freedesktop.org/xorg/%{pkgname}/-/archive/%{commit}/%{
Source0: https://www.x.org/pub/individual/xserver/%{pkgname}-%{version}.tar.xz
%endif
# Only on F38 and later
%if 0%{fedora} >= 38
# Disallow byte-swapped clients by default
# https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1029
Patch1: 0001-Fix-some-indentation-issues.patch
Patch2: 0002-dix-localize-two-variables.patch
Patch3: 0003-Disallow-byte-swapped-clients-by-default.patch
%endif
License: MIT
Requires: xorg-x11-server-common
@ -124,6 +133,9 @@ rm -Rf $RPM_BUILD_ROOT%{_localstatedir}/lib/xkb
%{_libdir}/pkgconfig/xwayland.pc
%changelog
* Tue Jan 17 2023 Olivier Fourdan <ofourdan@redhat.com> - 22.1.7-2
- Disallow byte-swapped clients on Fedora 38 and above (#2159489)
* Mon Dec 19 2022 Olivier Fourdan <ofourdan@redhat.com> - 22.1.7-1
- xwayland 22.1.7