Skip to content

Bound the Wayland info buffer writes and free the returned info strings - #62

Merged
xyproto merged 1 commit into
xyproto:mainfrom
OvOhao:fix-info-string-overflow-and-leaks
Oct 21, 2026
Merged

xyproto merged 1 commit into
xyproto:mainfrom
OvOhao:fix-info-string-overflow-and-leaks

Conversation

@OvOhao

@OvOhao OvOhao commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

What changed

include/wayinfo.h (#59): BUF now expands to buf + strlen(buf), sizeof(buf) - strlen(buf), and all 20 sprintf(BUF, ...) calls are now snprintf(BUF, ...). Every append is limited to the space left in buf; output that does not fit is truncated instead of being written past the end of the 10240 byte buffer. The output for anything that fits is unchanged.

xinfo.go (#60), wayinfo.go (#61): X11InfoString() / WaylandInfoString() return a calloc'ed copy of the info text and clear the static buffer, so the caller owns the returned pointer. XInfo() and WaylandInfo() now keep the pointer, copy it with C.GoString and C.free it (deferred). Both headers already include <stdlib.h>. C.free(NULL) and C.GoString(nil) are both safe, so a NULL return still produces an empty string as before.

Testing

Run in a golang:1.27 (Debian, arm64) container with libx11-dev libxcursor-dev libxmu-dev libwayland-dev libxpm-dev xbitmaps libxmu-headers libheif-dev (the CI package list), plus Xvfb :99 -noreset with two screens and weston --backend=headless:

  • make succeeds and go vet . passes, before and after.
  • go test -count=10 -mod=vendor -run 'TestXMonitors|TestWaylandMonitors' -v .: 10/10 passes for each test, before and after. Both return the same monitors as before.
  • A small C program built with -fsanitize=address that includes include/wayinfo.h and passes sprint_infos() 100 registry entries with 200 character interface names:
    • before: AddressSanitizer: global-buffer-overflow ... WRITE of size 237 in vsprintf
    • after: no error, strlen(buf) = 10239, sizeof(buf) = 10240
  • A local loop of 20,000 calls measuring the C heap in use (mallinfo2().uordblks):
Call before after
XInfo() (281 byte result) +304 bytes/call +0 bytes/call
WaylandInfo() (1339 byte result) +3619 bytes/call +2258 bytes/call

The remaining growth in WaylandInfo() comes from the per-call registry/output records in wayinfo.h. This PR does not change them.

Fixes #59
Fixes #60
Fixes #61

WaylandInfoString appended to the fixed 10240 byte buf with
sprintf(buf + strlen(buf), ...), so output longer than the buffer was
written past its end. Let BUF also pass the space left in buf, and use
snprintf for every append, so output that does not fit is truncated.

X11InfoString and WaylandInfoString return a calloc'ed copy of the
info text, which XInfo and WaylandInfo never freed. Free it after
copying it into a Go string.

Fixes xyproto#59
Fixes xyproto#60
Fixes xyproto#61
@xyproto

xyproto commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Thanks for the PR, merged.

@xyproto
xyproto merged commit 01ee3ea into xyproto:main Oct 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants