Package:  halevt                                                                
Version:  0.1.6.2-1
Severity: normal                                                              
Tags:     patch 

It appears that halevt does not setup supplemental groups (i.e., doesn't
call initgroups) when changing ids to a non-root user.  This means that the
halevt daemon does not have permission to access files/devices owned by a
group for which user "halevt" is a member, but are not owned by user
"halevt" or group "plugdev" themselves.

As a motivating example, I have a halevt rule that toggles my sound mixer's
mute setting on a "mute button" hotkey keypress.  Access to
/dev/snd/controlC0 via amixer requires that the user be a member of group
"audio", which on my system user "halevt" is.  In this case, it wouldn't
make sense to change ownership of the mixer device to either halevt or
plugdev, as other applications (used with group audio membership) access
the mixer device.  Running halevt under group audio would work, but is a
heavy-handed approach that might not be appropriate in all situations.

As it turns out this bug is a regression.  Although halevt itself never
called initgroups, the Debian halevt init.d script in version 0.1.5-4 and
below ran halevt as a non-root user via start-stop-daemon's -c and -g
options, and thus the "change id" code in halevt itself was always
bypassed.

It's unclear from the changelog why the "change id" responsibility was
shifted from start-stop-daemon to halevt.  Personally I find the former to
be strategic from a security perspective--that is, leave the privileged
operations solely to a well trusted program (start-stop-daemon) since
halevt itself does not need root privileges except to change users.

In any event, if the change to have halevt switch users itself is intended,
then attached is a patch which adds the appropriate initgroups call to
halevt.  I've tested it, and it works well to fix the problem.

Thanks!
diff --git a/src/manager.c b/src/manager.c
--- a/src/manager.c
+++ b/src/manager.c
@@ -331,6 +331,11 @@
             DEBUG(_("Error setting gid to %u: %s"), gid, strerror(errno));
             exit(1);
         }
+        if (initgroups(user, gid) != 0)
+        {
+            DEBUG(_("Error setting initgroups for %s, %u: %s"), user, gid, strerror(errno));
+            exit(1);
+        }
         if (setuid(uid) != 0)
         {
             DEBUG(_("Error setting uid to %u: %s"), uid, strerror(errno));

Reply via email to