Skip to content

Guard evdi_open_attached_to() against a NULL parent device - #593

Open
scotttromley wants to merge 1 commit into
DisplayLink:mainfrom
scotttromley:fix-open-attached-to-null
Open

Guard evdi_open_attached_to() against a NULL parent device#593
scotttromley wants to merge 1 commit into
DisplayLink:mainfrom
scotttromley:fix-open-attached-to-null

Conversation

@scotttromley

Copy link
Copy Markdown

Problem

evdi_open_attached_to_fixed() documents NULL as a valid argument meaning "open a
generic device", and implements 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:

return evdi_open_attached_to_fixed(sysfs_parent_device, strlen(sysfs_parent_device));

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 master as of 21a6390.

How I hit it

Silicon Motion ships SMIUSBDisplayManager, the userspace driver for their SM768 USB
display adapters, on top of evdi. It calls evdi_open_attached_to(NULL) to claim one
of the generic devices created by initial_device_count, and dies immediately:

SIGSEGV si_code=SEGV_MAPERR si_addr=NULL
#1 evdi_open_attached_to (libevdi.so.1 + 0x4523)    thread: pnpThreadfunc

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 affected
users. 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 not
clang-format clean).

Testing

  • make -C library builds clean.
  • evdi_open_attached_to(NULL) now returns a valid handle instead of faulting, and
    evdi_close() on it succeeds. libevdi logs Opened /dev/dri/card3 as slave drm device / Marking /dev/dri/card3 as unused.
  • End to end: with this fix SMIUSBDisplayManager starts and stays up, and the
    attached 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.
  • No behaviour change for non-NULL callers: same pointer, same length.

🤖 Generated with Claude Code

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>
@scotttromley
scotttromley changed the base branch from master to main August 31, 2026 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant