Commit Graph

706 Commits

Author SHA1 Message Date
Enrico Weigelt, metux IT consult
ad5393296f (1623) xkb: split XkbSendMap()
This function is a funny beast: it assembles and writes out an xkbGetMapReply,
called in two different cases, ProcXkbGetMap() as well as ProcXkbGetKbdByName().
In the latter case the whole reply is contained in another one. That's the reason
why it's payload size is computed separately - the caller must know that in order
to set up the container's reply size correctly.

As preparation for upcoming simplifications of the reply send path, splitting off
this function into pieces: XkbAssembleMap() just assembles the reply payload,
while it's callers now responsible for preparing the request header and writing
out both pieces.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
ae58654783 (1623) xkb: ProcXkbGetKbdByName(): static initialization of sub-reply structs
For easier reading, move th sub-reply structs down to where they're used
first and use static initialization for the common fields.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
a2db290097 (1623) xkb: ProcXkbGetKbdByName() simplify reply struct initialization
Move down the declaration of the reply struct, right before swapping and sending
and use static initialization.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
6a92902cf8 (1623) xkb: XkbSendGeometry(): pass in struct as value instead of pointer
The function doesn't need to pass anything back via this pointer, it's
the last consumer of this struct. Make understanding the code a bit easier
and clear the road for further simplifications by passing the struct as
value instead of pointer.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
c02eede856 (1623) xkb: XkbSendNames(): move common code into a helper macro
A little bit of simplification by putting repeated statements into macro.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
3481bba2a4 (1623) xkb: XkbSendNames(): pass in struct as value instead of pointer
The function doesn't need to pass anything back via this pointer, it's
the last consumer of this struct. Make understanding the code a bit easier
and clear the road for further simplifications by passing the struct as
value instead of pointer.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
5cef8683dc (1623) xkb: let SendDeviceLedFBs() fill buffer instead of writing directly
Make the code flow a bit easier to understand and allow further simplification
by now just having to write out one additional payload as one block.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
99229f5d39 (1623) xkb: ProcXkbGetDeviceInfo(): consolidate buffers to reduce writes
Putting both payload pieces into one buffer, so it can be written out
with only one call.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
527ccda60c (1623) xkb: CheckDeviceLedFBs(): untwist parameters
It's hard to see which fields of the xkbGetDeviceInfoReply struct it's
reading or writing, and that complicates further simplifications of the
caller. So instead let the caller pass in the relevant fields and do the
modifications on the reply structs on its own.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
b36cdfd3d5 (1623) xkb: XkbSendIndicatorMap(): little simplification
A bit simplification in code flow.
The extra length check (did we write as much as intended?) isn't necessary,
since the buffer size is computed by the very same data before this
function is called.

Hint: the size computation must be done before calling this one, because
the reply might be encapsulated in another one (xkbGetKbdByName).

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
202456de16 (1623) xkb: XkbSendIndicatorMap() pass in reply struct as value instead of pointer
It's not passing back any data via that pointer and actually the last
consumer of it. Changing it to value instead of pointer clears the
road for further simplifications by subsequent patches.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
c91e02d0a4 (1623) xkb: XkbSendCompatMap(): little cleanup and simplification
Make it a bit simpler and easier to read.

calloc() and WriteToClient() can handle zero lengths very well.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
1adbfbca93 (1623) xkb: XkbSendCompatMap(): pass xkbGetCompatMapReply as value instead of pointer
It's not passing back any data via that pointer and actually the last
consumer of it. Changing it to value instead of pointer clears the
road for further simplifications by subsequent patches.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
d33bcf38c4 (1623) xkb: XkbSendMap(): some little variable decl cleanups
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
980f3e9007 (1623) xkb: XkbSendMap() pass in reply struct as value instead of pointer
It's not passing back any data via that pointer and actually the last
consumer of it. Changing it to value instead of pointer clears the
road for further simplifications by subsequent patches.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
f44d5d1ab6 (1623) xkb: XkbWriteVirtualModMap(): only pass in the needed data
We don't need the whole struct here, especially do we not wanna change it.
Therefore only pass in what's really needed, so it gets easier to understand.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
4266913cc8 (1623) xkb: XkbWriteModifierMap(): only pass in the needed data
We don't need the whole struct here, especially do we not wanna change it.
Therefore only pass in what's really needed, so it gets easier to understand.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
fab58d65b0 (1623) xkb: XkbWriteExplicit(): only pass in the needed data
We don't need the whole struct here, especially do we not wanna change it.
Therefore only pass in what's really needed, so it gets easier to understand.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
25039132cf (1623) xkb: XkbWriteKeyBehaviors(): only pass in the needed data
We don't need the whole struct here, especially do we not wanna change it.
Therefore only pass in what's really needed, so it gets easier to understand.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
64bdd50790 (1623) xkb: XkbWriteKeyActions(): only pass in the needed data
We don't need the whole struct here, especially do we not wanna change it.
Therefore only pass in what's really needed, so it gets easier to understand.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
2edccfa8c8 (1623) xkb: XkbWriteKeyTypes(): only pass in the needed data
We don't need the whole struct here, especially do we not wanna change it.
Therefore only pass in what's really needed, so it gets easier to understand.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:13 +01:00
Enrico Weigelt, metux IT consult
05fcbe206d (1623) xkb: XkbWriteKeySyms(): only pass in the needed data
We don't need the whole struct here, especially do we not wanna change it.
Therefore only pass in what's really needed, so it gets easier to understand.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:12 +01:00
Enrico Weigelt, metux IT consult
dfdecf3ae9 (1623) xkb: SProcXkbSelectEvents(): simplify swapping
The swapping logic isn't entirely trivial to understand and can be
simplified.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:12 +01:00
Enrico Weigelt, metux IT consult
beb4e1601f (1623) xkb: simplify reply struct initialization
Use static initializaton as much as possible and drop unnecessary
or duplicate zero assignments.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:12 +01:00
Enrico Weigelt, metux IT consult
1c121e23b5 (1823) xkb: protect from memory allocation failure
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:12 +01:00
Enrico Weigelt, metux IT consult
34d56181b8 (1823) xkb: replace xallocarray() by calloc()
Only key difference that calloc(), in contrast to rellocarray(),
is zero-initializing. The overhead is hard to measure on today's
machines, and it's safer programming practise to always allocate
zero-initialized, so one can't forget to do it explicitly.

Cocci rule:

    @@
    expression COUNT;
    expression LEN;
    @@
    - xallocarray(COUNT,LEN)
    + calloc(COUNT,LEN)

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:35:12 +01:00
Enrico Weigelt, metux IT consult
868fb9720c (1889) xkb: fix printf conversion error on Windows
> ../xkb/xkb.c: In function ‘_XkbSetMapCheckLength’:
> ../xkb/xkb.c:2440:53: warning: unknown conversion type character ‘z’ in format [-Wformat=]
>  2440 |     ErrorF("[xkb] BOGUS LENGTH in SetMap: expected %zd got %zd\n", len, req_len);
>       |                                                     ^
> ../xkb/xkb.c:2440:61: warning: unknown conversion type character ‘z’ in format [-Wformat=]
>  2440 |     ErrorF("[xkb] BOGUS LENGTH in SetMap: expected %zd got %zd\n", len, req_len);
>       |                                                             ^
> ../xkb/xkb.c:2440:12: warning: too many arguments for format [-Wformat-extra-args]
>  2440 |     ErrorF("[xkb] BOGUS LENGTH in SetMap: expected %zd got %zd\n", len, req_len);
>       |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-02-02 17:33:34 +01:00
Enrico Weigelt, metux IT consult
a0c1eeea98 xkb: simplify loops in XkbRF_Free()
Make the code a bit easier to read by simplifying the loops.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
abfbc76824 xkb: drop obsolete parameter from XkbRF_Free()
The freeRules parameter is always set to TRUE, meaning always free the
XkbRF_RulesRec struct. Therefore also no need to clear out fields that
aren't going to be reused again, ever.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
a88b17565b xkb: maprules: use static struct init instead of memset()
Allow the compiler to figure out the most efficient way to do the
struct initialization, and a little improvement on code readability.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
ffd7ca8af2 xkb: maprules: put some loop counters into local scope
Prevent from being accidentially removed and making the code a
little bit easier to understand.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
60d37d0158 xkb: make XkbRF_Create() static inline
The function is nothing more than a calloc() call, so we can spare
an actual function call here by making it static inline.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
a82fa00835 xkb: unexport XkbRF_RuleRec struct
Not used outside xkb, so no need to keep it in public API header.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
83c8a90a61 xkb: unexport XkbRF_GroupRec struct
Not used outside xkb, so no need to keep it in public API header.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
043dc8041c xkb: unexport XkbRF_RulesRec struct
Not used by any drivers, so no need to keep it in public header.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
34372cb3da xkb: unexport XkbRF_Free()
Only used inside xkb/* - not used by any modules, so no need
to keep maintaining it in public headers.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
89475cbed4 xkb: unexport XkbRF_Create()
Only used inside xkb/* - not used by any modules, so no need
to keep maintaining it in public headers.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
c376cd2c3d xkb: unexport XkbRF_LoadRules()
Only used inside xkb/* - not used by any modules, so no need
to keep maintaining it in public headers.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
d3b328ba4a xkb: unexport XkbRF_GetComponents()
Only used inside xkb/* - not used by any modules, so no need
to keep maintaining it in public headers.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
b535fd7a4c xkb: move XkbRF_* defines into xkb/maprules.c
Only used there so no need to keep them in public API header.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
1a9592ea4b xkb: move _XKB_RF_NAMES_PROP_ATOM define into xkbInit.c
It's only used there, nowhere else, so no need to keep it in
a public API header.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Enrico Weigelt, metux IT consult
e38eeb4718 xkb: drop unused XkbRF_LoadRulesByName()
Not used anywhere, so no need to keep it around any longer.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1840>
2025-02-26 13:43:52 +00:00
Alan Coopersmith
42a1f25faf xkb: Add tbGetBufferString helper function
Handles common case of allocating & copying string to temporary buffer

(cherry picked from xorg/lib/libxkbfile@8a91517ca6ea77633476595b0eb5b213357c60e5)

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1821>
2025-02-26 13:15:34 +00:00
Martin Burggraf
7a23010232 xkb: correcting mathematical nonsense in XkbGeomFPText
Fixes formatting of negative numbers, so they don't show minus sign
after the decimal point.

(cherry picked from xorg/lib/libxkbfile@d2ec504fec2550f4fd046e801b34317ef4a4bab9)

Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1821>
2025-02-26 13:15:34 +00:00
Alan Coopersmith
60419d8e4a xkb: Convert more sprintf calls to snprintf in xkbtext.c
Based on xorg/lib/libxkbfile@390acfe5bb88cdab509b5eaae4041f265e969d2b

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1821>
2025-02-26 13:15:34 +00:00
José Expósito
6d33834186 xkb: Check that needed is > 0 in XkbResizeKeyActions
Passing a negative value in `needed` to the `XkbResizeKeyActions()`
function can create a `newActs` array of an unespected size.
Check the value and return if it is invalid.

This error has been found by a static analysis tool. This is the report:

    Error: OVERRUN (CWE-119):
    libX11-1.8.7/src/xkb/XKBMAlloc.c:811: cond_const:
      Checking "xkb->server->size_acts == 0" implies that
      "xkb->server->size_acts" is 0 on the true branch.
    libX11-1.8.7/src/xkb/XKBMAlloc.c:811: buffer_alloc:
      "calloc" allocates 8 bytes dictated by parameters
      "(size_t)((xkb->server->size_acts == 0) ? 1 : xkb->server->size_acts)"
      and "8UL".
    libX11-1.8.7/src/xkb/XKBMAlloc.c:811: var_assign:
      Assigning: "newActs" = "calloc((size_t)((xkb->server->size_acts == 0) ? 1 : xkb->server->size_acts), 8UL)".
    libX11-1.8.7/src/xkb/XKBMAlloc.c:815: assignment:
      Assigning: "nActs" = "1".
    libX11-1.8.7/src/xkb/XKBMAlloc.c:829: cond_at_least:
      Checking "nCopy > 0" implies that "nCopy" is at least 1 on the
      true branch.
    libX11-1.8.7/src/xkb/XKBMAlloc.c:830: overrun-buffer-arg:
      Overrunning buffer pointed to by "&newActs[nActs]" of 8 bytes by
      passing it to a function which accesses it at byte offset 15
      using argument "nCopy * 8UL" (which evaluates to 8).
    #  828|
    #  829|           if (nCopy > 0)
    #  830|->             memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i),
    #  831|                      nCopy * sizeof(XkbAction));
    #  832|           if (nCopy < nKeyActs)

(cherry picked from xorg/lib/libx11@af1312d2873d2ce49b18708a5029895aed477392)

Signed-off-by: José Expósito <jexposit@redhat.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1821>
2025-02-26 13:15:34 +00:00
Alan Coopersmith
09c6f09eb7 xkb: ensure XkbAllocNames sets num_rg to 0 on allocation failure
If there was a previous radio_groups array which we failed to realloc
and freed instead, clear the array size in the XkbNamesRec.

Taken from xorg/lib/libx11@258a8ced681dc1bc50396be7439fce23f9807e2a

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1821>
2025-02-26 13:15:34 +00:00
Olivier Fourdan
0e4ed94952 xkb: Fix buffer overflow in XkbChangeTypesOfKey()
If XkbChangeTypesOfKey() is called with nGroups == 0, it will resize the
key syms to 0 but leave the key actions unchanged.

If later, the same function is called with a non-zero value for nGroups,
this will cause a buffer overflow because the key actions are of the wrong
size.

To avoid the issue, make sure to resize both the key syms and key actions
when nGroups is 0.

CVE-2025-26597, ZDI-CAN-25683

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1828>
2025-02-25 11:43:01 +01:00
Olivier Fourdan
80d69f0142 xkb: Fix computation of XkbSizeKeySyms
The computation of the length in XkbSizeKeySyms() differs from what is
actually written in XkbWriteKeySyms(), leading to a heap overflow.

Fix the calculation in XkbSizeKeySyms() to match what kbWriteKeySyms()
does.

CVE-2025-26596, ZDI-CAN-25543

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1828>
2025-02-25 11:43:01 +01:00
Olivier Fourdan
11fcda8753 xkb: Fix buffer overflow in XkbVModMaskText()
The code in XkbVModMaskText() allocates a fixed sized buffer on the
stack and copies the virtual mod name.

There's actually two issues in the code that can lead to a buffer
overflow.

First, the bound check mixes pointers and integers using misplaced
parenthesis, defeating the bound check.

But even though, if the check fails, the data is still copied, so the
stack overflow will occur regardless.

Change the logic to skip the copy entirely if the bound check fails.

CVE-2025-26595, ZDI-CAN-25545

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1828>
2025-02-25 11:43:01 +01:00