-
-
Notifications
You must be signed in to change notification settings - Fork 69
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 clipboard robustness #337
Conversation
If a client/receiving Wayland clipboard client causes us to write() to a closed pipe/socket, we'll get SIGPIPE which the default action is to terminate the process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
How did you test this?
A misbehaving client can cause us to block when writing to the send fd, such as if they create a pipe, read only a few bytes, then block themselves, but we called write() with megabytes of data. As for the receive fd, the Linux man page for select(2) says there may be "circumstances in which a file descriptor is spuriously reported as ready". This is probably never going to be a problem and we'd use epoll on Linux anyway, but setting it doesn't hurt. (O_NONBLOCK helps if the misbehaving client uses a pipe, but writing to a disk would still "block" (more accurately, put us in non-interruptible sleep). The protocol doesn't specify a limitation on what kinds of files can be used, so there are probably various ways a client can freeze the selection owner.)
This prevents sending incomplete data if the system or receiving Wayland client causes partial writes to occur (especially now that we set O_NONBLOCK). This needs to be asynchronous (not a while loop) to protect us from misbehaving clients. We only need to perform asynchronous sending if a partial write occurs on the initial synchronous write. Otherwise, don't bother. That means we should keep O_NONBLOCK for the initial synchronous write.
I used a small test client that sends a closed pipe (before patch, wayvnc gets SIGPIPE soon after the write call, but I guess has enough time to print that "write from clipboard incomplete" message), or does single a read() with a small buffer (before patch, wayvnc blocks on the write() call if its selection data is large) client
For testing the patch I generated a large random text file and copied it on the client (to test the async send code):
|
986fd24
to
bcbfe79
Compare
This was only necessary in the initial version of the file where offer handling was synchronous.
bcbfe79
to
1ed5c5f
Compare
Excellent. Thanks! |
Some changes which improve our robustness with weird files or misbehaving clients.
I have read and understood CONTRIBUTING.md.