This patch lets the daemon drop the root privileges and routes the kill
requests to the helper.
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
src/helper.c | 7 +++++-
src/helper.h | 4 ++-
src/main.c | 63 ++++++++++++++++++++++++++++++++++++++++++---------------
3 files changed, 55 insertions(+), 19 deletions(-)
diff --git a/src/helper.c b/src/helper.c
index 4084e87..4e3fb9a 100644
--- a/src/helper.c
+++ b/src/helper.c
@@ -192,7 +192,10 @@ int run_helper(int in_fd, int out_fd, int log_stderr)
if (pollfd.revents & POLLIN) {
rv = read_hm(in_fd, &hm);
- if (!rv && (hm.type == HELPER_MSG_RUNPATH)) {
+ if (rv)
+ continue;
+
+ if (hm.type == HELPER_MSG_RUNPATH) {
pid = fork();
if (!pid) {
run_path(&hm);
@@ -206,6 +209,8 @@ int run_helper(int in_fd, int out_fd, int log_stderr)
pid, fork_count, wait_count,
hm.path, hm.args);
*/
+ } else if (hm.type == HELPER_MSG_KILLPID) {
+ kill(hm.pid, hm.sig);
}
}
diff --git a/src/helper.h b/src/helper.h
index f55b051..b87bc61 100644
--- a/src/helper.h
+++ b/src/helper.h
@@ -18,6 +18,7 @@
#define SANLK_HELPER_MSG_LEN 512
#define HELPER_MSG_RUNPATH 1
+#define HELPER_MSG_KILLPID 2
struct helper_msg {
uint8_t type;
@@ -25,9 +26,10 @@ struct helper_msg {
uint16_t pad2;
uint32_t flags;
int pid;
+ int sig;
char path[SANLK_HELPER_PATH_LEN]; /* 128 */
char args[SANLK_HELPER_ARGS_LEN]; /* 128 */
- char pad[244];
+ char pad[240];
};
#define HELPER_STATUS_INTERVAL 30
diff --git a/src/main.c b/src/main.c
index 34d92f1..af39987 100644
--- a/src/main.c
+++ b/src/main.c
@@ -53,6 +53,8 @@
#define RELEASE_VERSION "2.3"
+#define SIGHELPER 100 /* anything that's not SIGTERM/SIGKILL */
+
struct thread_pool {
int num_workers;
int max_workers;
@@ -111,7 +113,7 @@ static void close_helper(void)
* msgs before getting EAGAIN.
*/
-static void send_helper_kill(struct client *cl)
+static void send_helper_kill(struct client *cl, int sig)
{
struct helper_msg hm;
int rv;
@@ -129,12 +131,17 @@ static void send_helper_kill(struct client *cl)
return;
memset(&hm, 0, sizeof(hm));
- hm.type = HELPER_MSG_RUNPATH;
- memcpy(hm.path, cl->killpath, SANLK_HELPER_PATH_LEN);
- memcpy(hm.args, cl->killargs, SANLK_HELPER_ARGS_LEN);
- if (cl->flags & CL_KILLPATH_PID)
- hm.pid = cl->pid;
+ if (sig == SIGHELPER) {
+ hm.type = HELPER_MSG_RUNPATH;
+ memcpy(hm.path, cl->killpath, SANLK_HELPER_PATH_LEN);
+ memcpy(hm.args, cl->killargs, SANLK_HELPER_ARGS_LEN);
+ } else {
+ hm.type = HELPER_MSG_KILLPID;
+ hm.sig = sig;
+ }
+
+ hm.pid = cl->pid;
retry:
rv = write(helper_kill_fd, &hm, sizeof(hm));
@@ -514,8 +521,6 @@ static int client_using_space(struct client *cl, struct space *sp)
return rv;
}
-#define SIG_HELPER 100 /* anything that's not SIGTERM/SIGKILL */
-
static void kill_pids(struct space *sp)
{
struct client *cl;
@@ -578,7 +583,7 @@ static void kill_pids(struct space *sp)
(helper_kill_fd != -1) &&
(cl->kill_count <= main_task.kill_count_term) &&
(now - helper_last_status < (HELPER_STATUS_INTERVAL * 2)))
- sig = SIG_HELPER;
+ sig = SIGHELPER;
else if (cl->restrict & SANLK_RESTRICT_SIGKILL)
sig = SIGTERM;
else if (cl->restrict & SANLK_RESTRICT_SIGTERM)
@@ -603,10 +608,7 @@ static void kill_pids(struct space *sp)
ci, fd, pid, sig, cl->kill_count);
}
- if (sig == SIG_HELPER)
- send_helper_kill(cl);
- else
- kill(pid, sig);
+ send_helper_kill(cl, sig);
}
}
@@ -1295,10 +1297,27 @@ static void setup_groups(void)
int rv, i, j, h;
int pngroups, sngroups, ngroups_max;
gid_t *pgroup, *sgroup;
+ struct rlimit rlim;
if (!com.uname || !com.gname)
return;
+ /* before switching to a different user/group we must configure
+ the limits form memlock and rtprio */
+ rlim.rlim_cur = rlim.rlim_max= -1;
+
+ rv = setrlimit(RLIMIT_MEMLOCK, &rlim);
+ if (rv < 0) {
+ log_error("cannot set the limits for memlock %i", errno);
+ exit(EXIT_FAILURE);
+ }
+
+ rv = setrlimit(RLIMIT_RTPRIO, &rlim);
+ if (rv < 0) {
+ log_error("cannot set the limits for rtprio %i", errno);
+ exit(EXIT_FAILURE);
+ }
+
ngroups_max = sysconf(_SC_NGROUPS_MAX);
if (ngroups_max < 0) {
log_error("cannot get the max number of groups %i", errno);
@@ -1352,6 +1371,16 @@ static void setup_groups(void)
goto out;
}
+ rv = setgid(com.gid);
+ if (rv < 0) {
+ log_error("cannot set group id to %i errno %i", com.gid, errno);
+ }
+
+ rv = setuid(com.uid);
+ if (rv < 0) {
+ log_error("cannot set user id to %i errno %i", com.uid, errno);
+ }
+
out:
free(pgroup);
}
@@ -1519,16 +1548,16 @@ static int do_daemon(void)
if (rv < 0)
return rv;
- fd = lockfile(SANLK_RUN_DIR, SANLK_LOCKFILE_NAME);
- if (fd < 0)
- return fd;
-
setup_logging();
setup_host_name();
setup_groups();
+ fd = lockfile(SANLK_RUN_DIR, SANLK_LOCKFILE_NAME);
+ if (fd < 0)
+ return fd;
+
log_error("sanlock daemon started %s aio %d %d renew %d %d host %s time
%llu",
RELEASE_VERSION,
main_task.use_aio, main_task.io_timeout_seconds,
--
1.7.1