]> git.proxmox.com Git - pve-cluster.git/blobdiff - data/src/pmxcfs.c
fix some format security issues
[pve-cluster.git] / data / src / pmxcfs.c
index 5547d5d31c927755197972455365b421f242df86..2fe7c59d80af958abc8b76b30b2d8ad6b16da28e 100644 (file)
@@ -58,6 +58,7 @@
 
 #define DBFILENAME VARLIBDIR "/config.db"
 #define LOCKFILE VARLIBDIR "/.pmxcfs.lockfile"
+#define RESTART_FLAG_FILE RUNDIR "/cfs-restart-flag"
 
 #define CFSDIR "/etc/pve"
 
@@ -80,7 +81,7 @@ static void glib_log_handler(const gchar *log_domain,
                             gpointer user_data)
 {
 
-       cfs_log(log_domain, log_level, NULL, 0, NULL, message);
+       cfs_log(log_domain, log_level, NULL, 0, NULL, "%s", message);
 }
 
 static gboolean write_pidfile(pid_t pid)
@@ -774,6 +775,7 @@ int main(int argc, char *argv[])
 {
        int ret = -1;
        int lockfd = -1;
+       int pipefd[2];
 
        gboolean foreground = FALSE;
        gboolean force_local_mode = FALSE;
@@ -860,6 +862,7 @@ int main(int argc, char *argv[])
        umask(027);
 
        mkdir(VARLIBDIR, 0755);
+       mkdir(RUNDIR, 0755);
 
        if ((lockfd = open(LOCKFILE, O_RDWR|O_CREAT|O_APPEND, 0600)) == -1) {
                cfs_critical("unable to create lock '%s': %s", LOCKFILE, strerror (errno));
@@ -869,11 +872,11 @@ int main(int argc, char *argv[])
        for (int i = 10; i >= 0; i--) {
                if (flock(lockfd, LOCK_EX|LOCK_NB) != 0) {
                        if (!i) {
-                               cfs_critical("unable to aquire pmxcfs lock: %s", strerror (errno));
+                               cfs_critical("unable to acquire pmxcfs lock: %s", strerror (errno));
                                goto err;
                        }
                        if (i == 10)
-                               cfs_message("unable to aquire pmxcfs lock - trying again");
+                               cfs_message("unable to acquire pmxcfs lock - trying again");
 
                        sleep(1);
                }
@@ -952,17 +955,39 @@ int main(int argc, char *argv[])
        fuse_set_signal_handlers(fuse_get_session(fuse));
 
        if (!foreground) {
+               if (pipe(pipefd) == -1) {
+                       cfs_critical("pipe error: %s", strerror(errno));
+                       goto err;
+               }
+
                pid_t cpid = fork();
 
                if (cpid == -1) {
                        cfs_critical("failed to daemonize program - %s", strerror (errno));
                        goto err;
                } else if (cpid) {
+                       int readbytes, errno_tmp;
+                       char readbuffer;
+                       close(pipefd[1]);
+                       readbytes = read(pipefd[0], &readbuffer, sizeof(readbuffer));
+                       errno_tmp = errno;
+                       close(pipefd[0]);
+                       if (readbytes == -1) {
+                               cfs_critical("read error: %s", strerror(errno_tmp));
+                               kill(cpid, SIGKILL);
+                               goto err;
+                       } else if (readbytes != 1 || readbuffer != '1') {
+                               cfs_critical("child failed to send '1'");
+                               kill(cpid, SIGKILL);
+                               goto err;
+                       }
+                       /* child finished starting up */
                        write_pidfile(cpid);
                        qb_log_fini();
                        _exit (0);
                } else {
                        int nullfd;
+                       close(pipefd[0]);
 
                        chroot("/");
 
@@ -1018,8 +1043,18 @@ int main(int argc, char *argv[])
 
        server_start(memdb);
 
+       unlink(RESTART_FLAG_FILE);
+
+       if (!foreground) {
+               /* finished starting up, signaling parent */
+               write(pipefd[1], "1", 1);
+               close(pipefd[1]);
+       }
+
        ret = fuse_loop_mt(fuse);
 
+       open(RESTART_FLAG_FILE, O_CREAT|O_NOCTTY|O_NONBLOCK);
+
        cfs_message("teardown filesystem");
 
        server_stop();
@@ -1048,7 +1083,6 @@ int main(int argc, char *argv[])
        if (service_status)
                service_dfsm_destroy(service_status);
 
-       sleep(1); /* do not restart too fast */
  ret:
 
        if (status_fsm)