Guard evdi_open_attached_to() against a NULL parent device - #593
scotttromley wants to merge 1 commit into
Conversation
evdi_open_attached_to_fixed() documents NULL as a valid argument meaning
"open a generic device", and handles it:
if (sysfs_parent_device == NULL)
device_index = get_generic_device();
but the deprecated evdi_open_attached_to() wrapper calls strlen() on the
pointer unconditionally, so passing NULL faults before that check can
ever run:
SIGSEGV si_code=SEGV_MAPERR si_addr=NULL
DisplayLink#1 evdi_open_attached_to (libevdi.so.1 + 0x4523)
Pass a length of 0 when the pointer is NULL, so the documented behaviour
is reachable through the old entry point as well as the new one.
This was reported in DisplayLink#582 and closed without the wrapper being changed,
so the fault is still present.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Confirming this on different hardware: Dell XPS 13 Plus 9320 (Alder Lake, i915), Arch kernel 7.2.3, evdi 1.15.0, with a Satechi USB-C Multiport MX adapter (SM768, One detail that explains why this only started with 1.15.0. Disassembling if (v.major == 1 && v.minor > 13 && v.patch > 3)
h = evdi_open_attached_to_fixed(NULL, 0);
else
h = evdi_open_attached_to(NULL);So on 1.14.16, which SMI bundles, it uses the safe |
Problem
evdi_open_attached_to_fixed()documents NULL as a valid argument meaning "open ageneric device", and implements it:
But the deprecated
evdi_open_attached_to()wrapper callsstrlen()on the pointerunconditionally:
so passing NULL faults before that check can ever run.
This was reported in #582, which was closed as completed with no comments, but the
wrapper was never changed — the fault is still present on
masteras of 21a6390.How I hit it
Silicon Motion ships
SMIUSBDisplayManager, the userspace driver for their SM768 USBdisplay adapters, on top of evdi. It calls
evdi_open_attached_to(NULL)to claim oneof the generic devices created by
initial_device_count, and dies immediately:strace shows the fault landing straight after a successful 64 MB framebuffer mmap
with all four firmware blobs already open, so the caller is otherwise healthy — it is
purely the wrapper.
Because that daemon is a closed-source binary, the workaround suggested in #582
(calling
evdi_open_attached_to_fixed(NULL, 0)instead) is not available to affectedusers. The wrapper itself has to accept NULL.
Fix
Pass a length of 0 when the pointer is NULL, so the documented behaviour is reachable
through the old entry point as well as the new one. Formatted per the repo's
.clang-format(note the original single-line call was 90 columns and notclang-format clean).
Testing
make -C librarybuilds clean.evdi_open_attached_to(NULL)now returns a valid handle instead of faulting, andevdi_close()on it succeeds. libevdi logsOpened /dev/dri/card3 as slave drm device/Marking /dev/dri/card3 as unused.SMIUSBDisplayManagerstarts and stays up, and theattached panel comes up as a working fourth display at 2560x1440@60. Tested on
kernel 7.2.2 (clang + ThinLTO), evdi 1.15.0, Hyprland 0.56.2 / aquamarine 0.14.0.
🤖 Generated with Claude Code