Hi,

For avoiding the deadlock, protect cdgroup_change_cgroup_uid_gid_flags()
by blocking SIGUSR2 signal.

A cgrulesengd daemon needs a lock of rl_lock in cgroup_change_cgroup_uid_
~gid_flags() for referring configuration buffer. On the other way, the
daemon reloads configuration file when receiving SIGUSR2 signal, and it
needs the same lock in cgroup_parse_rules(). So cgroup_change_cgroup_uid_
gid_flags() should be protected from SIGUSR2 signal for avoiding the
deadlock.


This patch is similar to the one([PATCH] Fix the deadlock of vsyslog() call),
but they fix the different problem. So I think both of them are necessary.

Reference:
 [PATCH] Fix the deadlock of vsyslog() call:
 
http://sourceforge.net/mailarchive/forum.php?thread_name=4A0D2820.6050706%40mxs.nes.nec.co.jp&forum_name=libcg-devel


Thanks
Ken'ichi Ohmichi

Signed-off-by: Ken'ichi Ohmichi <[email protected]>
---
 src/daemon/cgrulesengd.c |   33 ++++++++++++++++++++++++++-------
 1 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/src/daemon/cgrulesengd.c b/src/daemon/cgrulesengd.c
index 1a61476..fb757c1 100644
--- a/src/daemon/cgrulesengd.c
+++ b/src/daemon/cgrulesengd.c
@@ -271,6 +271,27 @@ static int cgre_was_parent_changed_when_forking(const 
struct proc_event *ev)
        return 0;
 }
 
+static int cgre_change_cgroup_uid_gid(const uid_t uid, const gid_t gid,
+                                       const pid_t pid)
+{
+       int ret;
+       sigset_t sigset;
+
+       /*
+        * For avoiding the deadlock, protect cdgroup_change_cgroup_
+        * ~uid_gid_flags() by blocking SIGUSR2 signal.
+        */
+       sigemptyset(&sigset);
+       sigaddset(&sigset, SIGUSR2);
+       sigprocmask(SIG_BLOCK, &sigset, NULL);
+
+       ret = cgroup_change_cgroup_uid_gid_flags(uid, gid, pid,
+                                                CGFLAG_USECACHE);
+       sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+
+       return ret;
+}
+
 /**
  * Process an event from the kernel, and determine the correct UID/GID/PID to
  * pass to libcgroup.  Then, libcgroup will decide the cgroup to move the PID
@@ -318,22 +339,20 @@ int cgre_process_event(const struct proc_event *ev, const 
int type)
        case PROC_EVENT_UID:
                log_uid = ev->event_data.id.e.euid;
                log_gid = egid;
-               ret = cgroup_change_cgroup_uid_gid_flags(
+               ret = cgre_change_cgroup_uid_gid(
                                        ev->event_data.id.e.euid,
-                                       egid, pid, CGFLAG_USECACHE);
+                                       egid, pid);
                break;
        case PROC_EVENT_GID:
                log_uid = euid;
                log_gid = ev->event_data.id.e.egid;
-               ret = cgroup_change_cgroup_uid_gid_flags(euid,
-                                       ev->event_data.id.e.egid,
-                                       pid, CGFLAG_USECACHE);
+               ret = cgre_change_cgroup_uid_gid(euid,
+                                       ev->event_data.id.e.egid, pid);
                break;
        case PROC_EVENT_FORK:
                log_uid = euid;
                log_gid = egid;
-               ret = cgroup_change_cgroup_uid_gid_flags(euid,
-                                       egid, pid, CGFLAG_USECACHE);
+               ret = cgre_change_cgroup_uid_gid(euid, egid, pid);
                break;
        default:
                break;


------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables 
unlimited royalty-free distribution of the report engine 
for externally facing server and web deployment. 
http://p.sf.net/sfu/businessobjects
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to