Discussion on scoping of idle detection #3
Replies: 11 comments 6 replies
-
I really like the way you go about it. Here's my thougts on the issues you raise
Unfortunately, I'm quite blind to the security issues that would be by doing a system-wide API for idle detection. I do realize that you are after maximum efficiency, minimum CPU usage. But a feature-set like the above could enable people to really minmax their mining/crunching rigs. |
Beta Was this translation helpful? Give feedback.
-
I have an idea of "staging" things to avoid complexity, in that term.. For a start, you should focus on "what actually works right now" for "well-known" and "most-used" environments, For that we know that many of who want to detect IDLE are DE users so we can start with that for both X11 & Wayland for the top DEs out there and stick to what already works. Then you can start thinking of TTY sessions, including SSH (Which I think already works now?) After that point, you can worry about cases like VNC and edge cases. After this journey, you could start worrying about customizing everything that you could go with to the sides of "what is IDLE" and, for example, have a configuration that considers the system IDLE when CPU usage (maybe other resources, too) is low or at a specific rate for some time. And another version that reports IDLE when there is no input activity from input devices. The last one should be complex enough to hate thinking of, and that's why I think you should focus on the first parts as it could be considered as "features" to have later which may include more details (exclude specific process from resources bla bla..) |
Beta Was this translation helpful? Give feedback.
-
I agree. This means a focus on what is visible from the "primary user" perspective is where we start... |
Beta Was this translation helpful? Give feedback.
-
Which is why I want this to work as a systemd user level service... |
Beta Was this translation helpful? Give feedback.
-
Allow me to whine about Wayland. I am looking at the Wayland side and because Wayland's philosophy is compositor-centric, there is NO common idle detection API unlike X. Each compositor must implement their own. This is really fundamentally retarded. I understand that Wayland wanted to git rid of X bloat and the security issue, but the idea of not providing an abstraction layer of common things like idle detection makes application level idle detection very difficult. I can imagine every social media app programming in away status pulling their hair out in frustration... :) |
Beta Was this translation helpful? Give feedback.
-
Perhaps the selection of distros could be narrowed down by trying to align with the OS's Boinc wants to support? I dont really see how idle detection can remain "unbroken" when each compositor can change their setup without any requirement to give notice. So perhaps flip the bucket, and make the first bit about creating a library that can be used by the Wayland compositors and x11 alike? Like give them a common place to send the idle statuses? |
Beta Was this translation helpful? Give feedback.
-
Switching to the other thread for Wayland... |
Beta Was this translation helpful? Give feedback.
-
Alright. I am at pre-release tag 0.3. At this point there is a pretty much finalized C++ application, event_detect, that runs wrapped by the dc_event_detection.service systemd service. This replaces the script version. The C++ application is a multithreaded application that monitors the /dev/input/eventX devices that are pointing devices for events and the dev/tty* and dev/pts/* devices for atime. This application then updates the last active time in unix epoch seconds in the file /run/last_active_time.dat The idle_detect.sh script, which is run by the user level systemd service wrapper dc_idle_detection.service, has been simplified to check the last_active_time in that file and/or check xprintidle, if available. The event_detect application is reliably detecting activity in all terminals including ssh sessions, and all pointer movements by physical pointing devices. Note that VNC sessions are not detected properly because the pointers are virtual and are injected at the window manager level for X (the XTEST pointer). The idle_detect.sh script will detect VNC access via xprintidle, and will also detect an idle inhibit issued by an application where someone is watching a movie. So X sessions are really well covered by the combination of these two. There is a remaining gap with Wayland, because as discussed before, while Wayland provides a common way for an application to exert idle inhibit, there is no common way for another application to query the idle state. Each compositor has a different implementation. The event_detect service monitoring the /dev/input devices provides low level activity detection in a Wayland session perfectly well, however. |
Beta Was this translation helpful? Give feedback.
-
I will start working on the C++ version to replace the idle_detect.sh script, and perhaps we can write support for the top two Wayland compositors to be able to achieve the equivalent of xprintidle in Wayland for KDE (kwin) and Gnome (mutter). |
Beta Was this translation helpful? Give feedback.
-
Note I do not believe this approach outlined above presents any security issues. The C++ event_detect application is a very small, tightly written C++ application using modern techniques. It is compiled with stack hardening and is also sandboxed in the dc_event_detection service wrapper, so while it runs with root privileges, there is minimal risk. The service writes to its own data directory in the /run (in memory tmpfs) folder. This folder is ready only by all other than root. |
Beta Was this translation helpful? Give feedback.
-
I am leaning towards implementing a named pipe in the /run/event_detect directory that will be writable from the user level idle_detect instances. The event_detect service will have the pipe open for listening. Each instance of the idle_detect will send an updated "last_active_time" to event_detect, causing event_detect to use that time if it is greater (more recent) than other events/ttys it is monitoring. This will allow any application to simply read the last_active_time.dat in the run/event_detect directory and apply its own idle logic. This includes, of course, the boinc-client. This represents a reversal from the way idle_detect is currently operating, but actually may be more realistic, given that each DC application probably wants to implement its own internal logic for processing "last_active_time". Right now idle_detect does that and sends control signals to BOINC. For folks that are curious, I had an interesting conversation with Gemini Advanced 2.0 Flash Thinking about this and various important considerations: User: Ok back on event_detect, I would like to implement an interface that will allow the idle_detect program to communicate with event_detect and register an event from the user space idle_detect. Gemini: Okay, let's design an interface for the idle_detect program to communicate with event_detect and register events from user space. Here's a breakdown of a common and effective approach using a named pipe (FIFO), along with considerations for other methods. User: How about dbus? Is it too complicated? Gemini: You're right to consider D-Bus! It's a powerful and well-established inter-process communication (IPC) mechanism, especially prevalent in Linux desktop environments. However, your question about whether it's "too complicated" depends on your specific needs and familiarity with the technology. User: I think the named pipe might be the best way to go. Let's talk about the need a little more. As you know from earlier sessions, the event_detect program's main job is to determine the "last active time" of any user on the machine. The event_detect program cannot do this completely comprehensively: The event_detect uses low level activity monitoring and does not detect a "idle inhibit" directive from an application such as a video program to show a movie, etc. So we need the idle_detect program to detect the situations such as when an idle inhibit has been issued and send an last_active_time to event_detect that is essentially the current time (i.e. the user is active). Note that we must consider the possibility that more than one idle_detect instance could be running on the machine (unlike event_detect, which uses pid control to enforce single instance), because there could be VNC remote graphical sessions in addition to the main console session. Gemini: Okay, this additional context clarifies the requirements significantly and reinforces the idea that the communication needs to be relatively straightforward but reliable, especially with the possibility of multiple idle_detect instances. User: Please use C++ since the other parts of idle_detect are in C++ Gemini: Okay, let's implement the communication using a named pipe in C++. User: Are there any security concerns with using named pipes for a malicious actor to send something unwanted to the event_detect program? Gemini: Yes, there are security concerns associated with using named pipes if the permissions are not properly restricted and if the receiving program does not thoroughly validate its input. By carefully managing permissions and implementing robust input validation, you can mitigate these risks to a significant extent. User: Take a look in the idle_detect repository. event_detect runs in a systemd service wrapper with root privileges, and must do so, because it is necessary to monitor the event devices. Note that the dc_event_detection.service is set to protect home directories, and the compile options for event_detect use stack hardening. Note that the idle_detect program must run as the same user as the GUI session to properly work. This means that the event detect code that receives the message must implement stringent validation. Gemini: You are absolutely correct. Given this context, the need for stringent validation in the event_detect code that reads from the named pipe is absolutely critical. User: I think we can remove the reason field. It is enough to simply register an updated last_active_time to be used by the rest of the event_detect code. Gemini: Okay, let's simplify the communication by removing the "reason" field. The goal is now simply for idle_detect to send a signal to event_detect that signifies user activity and includes a timestamp, which event_detect will use to update its last_active_time. User: Would a shared memory segment be better for security reasons or worse? Gemini: Given the security context, a named pipe is likely a better choice than shared memory for this communication. The ability to perform stringent validation on the data received through the named pipe provides a crucial layer of defense, especially when the receiving process (event_detect) is running with root privileges and the sending process (idle_detect) runs at user level. User: Yep. I agree. Gemini: Great. I'm glad we're on the same page regarding the security considerations. Continuing with the named pipe approach and focusing on robust validation in event_detect is definitely the more secure path forward given the privileges involved. Do you have any further questions about implementing the named pipe communication, or would you like to move on to a different aspect of the event_detect or idle_detect programs? User: On the while loop, does the call block if there is no data in the pipe or does it return bytesRead = 0 and then the loop is essentially polling every 100 milliseconds? Gemini: That's a very insightful question! You're right to think about the blocking behavior of the read() call. In the event_detect C++ code I provided, the named pipe is opened for reading using open(PIPE_PATH.c_str(), O_RDONLY). In this mode, the read() call will indeed block if there is no data available in the pipe. User: Yes, but the thread needs to be gracefully interruptible. Take a look at the signalling mechanism in the actual event_detect.cpp. In actuality, this is going to be implemented on a separate thread similar to the TtyMonitor. Gemini: You are absolutely correct. For a robust application like event_detect that needs to handle signals for graceful shutdown, running the named pipe reader in a separate thread and integrating it with the existing signalling mechanism is the right approach. User: While an idle_detect instance has the pipe open for writing, this is exclusive correct? Meaning no other idle_detect instance can have access. Gemini: That's a good question that highlights a key aspect of how named pipes work. The answer is no, opening a named pipe for writing (O_WRONLY) is not exclusive in the way you might be thinking. User: This is very good. You have no concern about interleaving actually interleaving in the middle of one of the messages, so the field order is confused? Gemini: For the small, well-defined messages we are using (e.g., timestamp:user_active followed by a newline), you should not have a concern about interleaving occurring in the middle of a message that would confuse the field order. The kernel's handling of writes to named pipes, especially for sizes within the atomic limit, should prevent this. The newline delimiter further helps in ensuring that event_detect reads complete messages. User: Excellent. Gemini: Great to hear that! I'm glad I could clarify that for you. Let me know if you have any more questions or if there's anything else I can help you with regarding this or any other aspect of your project. User: Can you produce a transcript of this conversation for my records? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
The scoping of the idle detection is a serious issue. Linux is designed to be multi-user. Theoretically, this means one can have many tty sessions and GUI sessions all belonging to different users. In practice, for workstation use, you have a GUI user (let's call this the "primary user"), and a whole bunch of "secondary users" which are services logged in and users logged in via tty sessions, either local or remote (via ssh).
We have to make some decisions as to what context we want to run idle detection. For example the early alpha script is intended to run initiated from the current user's GUI session (either directly as a session startup configured via the window manager autostart or systemd user level service unit). This allows the idle detection to detect GUI activity in the users GUI + any ttys that w can see (which is actually system-wide). I do not believe someone logged to a virtual GUI via system administration VNC, for example would be detected using this approach. Do we care? The security challenges involved in doing a truly global (system-wide) API for idle detection would seem to be very problematic.
Beta Was this translation helpful? Give feedback.
All reactions