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

Serial port should be opened with O_CLOEXEC #477

Closed
mhitchens opened this issue Oct 6, 2019 · 0 comments
Closed

Serial port should be opened with O_CLOEXEC #477

mhitchens opened this issue Oct 6, 2019 · 0 comments

Comments

@mhitchens
Copy link
Contributor

There is an issue when the library opens the serial port.

m_socket = open(m_strName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);

After the port is opened, libcec obtains an exclusive (single process only) lock on the device.

if (flock(m_socket, LOCK_EX | LOCK_NB) != 0)

An application might initialize a client, then fork/execve a child process, then exit. This would leave the serial port open and locked by the child process, which would prevent another process from initializing a client. This is because of the behavior documented in flock(2).

Locks created by flock() are preserved across an execve(2).

This can be mitigated. If the O_CLOEXEC option were added to the above open call, the child will close the serial port after execve, which will release the lock, per the following behavior also in flock(2).

Locks created by flock() are associated with an open file description (see open(2)). This means that duplicate file descriptors (created by, for example, fork(2) or dup(2)) refer to the same lock, and this lock may be modified or released using any of these file descriptors. Furthermore, the lock is released either by an explicit LOCK_UN operation on any of these duplicate file descriptors, or when all such file descriptors have been closed.

I discovered this behavior using Plex Media Player. It launches, then initializes a CEC client, then forks an unrelated pmphelper process. This process stays alive if the parent process exits, but does not use the CEC serial port. As a result, if the player launches again after the helper spawns, the helper will have the lock on the port and it will never be released.

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

No branches or pull requests

2 participants