mirror of
https://github.com/troglobit/finit.git
synced 2026-11-01 13:10:32 +00:00
keventd: skip futile fork for missing /lib/udev/<helper>
When a rule references an absolute helper path (e.g. /lib/udev/fido_id, /lib/udev/scsi_id) that the system does not ship and we have no matching builtin either, return 1 from try_builtin_fallback() so the caller does not fork /bin/sh on a binary that's known to be missing. Previously each such uevent left a zombie 127 child for keventd's sigchld_cb to reap -- harmless but noisy and wasteful at coldplug. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 file changed
+34
-15
+34
-15
@@ -1132,19 +1132,28 @@ static gid_t resolve_gid(const char *s)
|
|||||||
*
|
*
|
||||||
* Stock udev rules invoke /lib/udev/<helper> (path_id, usb_id, blkid, ...)
|
* Stock udev rules invoke /lib/udev/<helper> (path_id, usb_id, blkid, ...)
|
||||||
* via IMPORT{program}=. keventd ships compatible builtins for many of
|
* via IMPORT{program}=. keventd ships compatible builtins for many of
|
||||||
* those. If the helper is absent on this system, fall back to the
|
* those. Dispatch order:
|
||||||
* matching builtin so the rule still works. If the helper exists, run
|
|
||||||
* it as-is -- this lets users override our builtins by dropping a
|
|
||||||
* custom helper into /lib/udev/.
|
|
||||||
*
|
*
|
||||||
* Returns 1 if the builtin handled the command, 0 if the caller should
|
* 1. Absolute helper path that exists -> let caller fork+exec it
|
||||||
* proceed with the normal fork+exec path.
|
* (lets users override builtins by dropping a custom helper)
|
||||||
|
* 2. Basename matches a known builtin -> run the builtin in-process
|
||||||
|
* 3. Absolute helper path that does NOT exist and has no matching
|
||||||
|
* builtin -> skip silently with a debug
|
||||||
|
* log; forking /bin/sh on a missing binary just yields a 127
|
||||||
|
* child for every event (e.g. /lib/udev/fido_id, /lib/udev/scsi_id
|
||||||
|
* on systems that don't ship them).
|
||||||
|
* 4. Anything else (relative command, shell snippet, ...) -> caller
|
||||||
|
* forks /bin/sh -c which resolves via PATH.
|
||||||
|
*
|
||||||
|
* Returns 1 if the case has been handled here (caller skips fork),
|
||||||
|
* 0 if the caller should proceed with the normal fork+exec path.
|
||||||
*/
|
*/
|
||||||
static int try_builtin_fallback(const char *cmd, struct uevent *ev)
|
static int try_builtin_fallback(const char *cmd, struct uevent *ev)
|
||||||
{
|
{
|
||||||
char first[PATH_MAX], rebuilt[PATH_MAX];
|
char first[PATH_MAX], rebuilt[PATH_MAX];
|
||||||
const char *space, *base;
|
const char *space, *base;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
int helper_missing;
|
||||||
|
|
||||||
space = strchr(cmd, ' ');
|
space = strchr(cmd, ' ');
|
||||||
len = space ? (size_t)(space - cmd) : strlen(cmd);
|
len = space ? (size_t)(space - cmd) : strlen(cmd);
|
||||||
@@ -1157,20 +1166,30 @@ static int try_builtin_fallback(const char *cmd, struct uevent *ev)
|
|||||||
if (access(first, X_OK) == 0)
|
if (access(first, X_OK) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
helper_missing = (first[0] == '/'); /* absolute path that's not there */
|
||||||
|
|
||||||
base = strrchr(first, '/');
|
base = strrchr(first, '/');
|
||||||
base = base ? base + 1 : first;
|
base = base ? base + 1 : first;
|
||||||
|
|
||||||
if (!builtin_has(base))
|
if (builtin_has(base)) {
|
||||||
return 0;
|
if (space)
|
||||||
|
snprintf(rebuilt, sizeof(rebuilt), "%s%s", base, space);
|
||||||
|
else
|
||||||
|
snprintf(rebuilt, sizeof(rebuilt), "%s", base);
|
||||||
|
|
||||||
if (space)
|
logit(LOG_DEBUG, "rules: %s not found, falling back to builtin %s",
|
||||||
snprintf(rebuilt, sizeof(rebuilt), "%s%s", base, space);
|
first, base);
|
||||||
else
|
builtin_run(ev, rebuilt);
|
||||||
snprintf(rebuilt, sizeof(rebuilt), "%s", base);
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
logit(LOG_DEBUG, "rules: %s not found, falling back to builtin %s", first, base);
|
if (helper_missing) {
|
||||||
builtin_run(ev, rebuilt);
|
logit(LOG_DEBUG, "rules: %s not found and no matching builtin, skipping",
|
||||||
return 1;
|
first);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void import_from_program(const char *cmd, struct uevent *ev)
|
static void import_from_program(const char *cmd, struct uevent *ev)
|
||||||
|
|||||||
Reference in new issue
Block a user