Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve wlEglMemoryIsReadable behavior #38

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Commits on Sep 19, 2021

  1. src/wayland-eglutils.c: check for EINTR and EAGAIN

    In 2eb4628 ("egl-wayland: check interface name in
    wlEglCheckInterfaceType", 2021-08-30, 1.1.8), the
    wlEglPointerIsDereferencable function was replaced with a new
    wlEglMemoryIsReadable function.
    
    The new wlEglMemoryIsReadable function relies on the write function
    returning EFAULT when passed a buffer that is "outside your accessible
    address space".
    
    However, there's nothing to prevent that write call from being
    interrupted and returning EINTR before it can complete validation
    of the input arguments.
    
    Add a loop to retry the call if it's interrupted with a signal.
    
    Additionally, there's no guarantee that a just-created pipe will
    always be able to immediately accept at least one byte without
    blocking in which case an EAGAIN error will be returned.
    
    Detect an EAGAIN error and treat that as success since the EAGAIN
    error indicates that the call can succeed if retried implying the
    arguments are otherwise valid.
    
    Signed-off-by: Kyle J. McKay <[email protected]>
    mackyle committed Sep 19, 2021
    Configuration menu
    Copy the full SHA
    8002e1a View commit details
    Browse the repository at this point in the history
  2. src/wayland-eglutils.c: refactor pipe write code

    In preparation for reusing the same attempt-to-write-on-a-dummy-pipe
    code, move the code that checks for EINTR and EAGAIN into its own
    separate static function.
    
    Signed-off-by: Kyle J. McKay <[email protected]>
    mackyle committed Sep 19, 2021
    Configuration menu
    Copy the full SHA
    8d59864 View commit details
    Browse the repository at this point in the history
  3. src/wayland-eglutils.c: check both ends for readability

    When using the write function call to check for whether or not the
    buffer being written is "outside your accessible address space,"
    it's important to consider any shortcuts the write function may be
    taking when validating the arguments.
    
    In particular, if the passed in length to write is zero it may not
    do any validation at all.  To that end, treat a length of 0 as 1.
    
    Furthermore, since the destination is a pipe that can only ever
    accept a small number of bytes without blocking, there's no need
    for the write function call to validate the entire memory range of
    the buffer being passed to be written, merely the initial portion.
    
    Work around this optimization by attempting to write a byte from
    the very end of the memory range to the pipe.  Be careful to avoid
    a PIPE_BUF size optimization by the write call by draining the
    single byte before attempting to write the entire range.
    
    (If a memory range of exactly PIPE_BUF bytes is passed, but there's
    only room in the pipe for PIPE_BUF-1 bytes because the write of a
    single byte from the end used up one byte, then the write call is
    expected to return EAGAIN in which case there's really no need for
    it to validate the buffer's memory address -- another optimization
    shortcut to avoid.)
    
    While this will not cause the entire memory range to be validated
    in the face of write function optimizations, it will force an extra
    check at the very end which provides a much more robust test than
    only checking the initial portion of the memory range.
    
    An alternative to provide even more checking would be to attempt
    to write at least one byte from every PAGE_SIZE block within the
    memory range being checked.  However, that would definitely incur
    a performance penalty for large memory ranges and even that could
    still potentially miss unwritable holes in the middle.
    
    Adding a check of the very end of the memory range provides a speedy
    compromise that will provide a more accurate answer in the face of
    write function optimizations without incurring a performance penalty.
    
    Signed-off-by: Kyle J. McKay <[email protected]>
    mackyle committed Sep 19, 2021
    Configuration menu
    Copy the full SHA
    4d4a421 View commit details
    Browse the repository at this point in the history
  4. src/wayland-eglutils.c: treat EINVAL like EFAULT

    If the write function thinks the pointer and/or length arguments
    are invalid, it may return EINVAL instead of EFAULT.
    
    In the context of wlEglMemoryIsReadable that will do just as well
    as an indication that the memory is most likely unreadable.
    
    Therefore allow an EINVAL error without causing an assertion failure.
    
    Signed-off-by: Kyle J. McKay <[email protected]>
    mackyle committed Sep 19, 2021
    Configuration menu
    Copy the full SHA
    9a4e08b View commit details
    Browse the repository at this point in the history