Merge branch 'jg/credential-cache-chdir-to-sockdir'
authorJunio C Hamano <gitster@pobox.com>
Fri, 26 Feb 2016 21:37:20 +0000 (13:37 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 26 Feb 2016 21:37:20 +0000 (13:37 -0800)
The "credential-cache" daemon process used to run in whatever
directory it happened to start in, but this made umount(2)ing the
filesystem that houses the repository harder; now the process
chdir()s to the directory that house its own socket on startup.

* jg/credential-cache-chdir-to-sockdir:
credential-cache--daemon: change to the socket dir on startup
credential-cache--daemon: disallow relative socket path
credential-cache--daemon: refactor check_socket_directory

1  2 
credential-cache--daemon.c
index cc65a9c0d342aa51d4b307fe10c626d940e2f211,6b00ee0ee61536a9f3c63980d251d4f4e8d797ca..caef21e4fc91898f209709f723de1df5afc66a66
@@@ -96,12 -96,12 +96,12 @@@ static int read_request(FILE *fh, struc
        static struct strbuf item = STRBUF_INIT;
        const char *p;
  
 -      strbuf_getline(&item, fh, '\n');
 +      strbuf_getline_lf(&item, fh);
        if (!skip_prefix(item.buf, "action=", &p))
                return error("client sent bogus action line: %s", item.buf);
        strbuf_addstr(action, p);
  
 -      strbuf_getline(&item, fh, '\n');
 +      strbuf_getline_lf(&item, fh);
        if (!skip_prefix(item.buf, "timeout=", &p))
                return error("client sent bogus timeout line: %s", item.buf);
        *timeout = atoi(p);
@@@ -215,7 -215,7 +215,7 @@@ static const char permissions_advice[] 
  "users may be able to read your cached credentials. Consider running:\n"
  "\n"
  "     chmod 0700 %s";
- static void check_socket_directory(const char *path)
+ static void init_socket_directory(const char *path)
  {
        struct stat st;
        char *path_copy = xstrdup(path);
        if (!stat(dir, &st)) {
                if (st.st_mode & 077)
                        die(permissions_advice, dir);
-               free(path_copy);
-               return;
+       } else {
+               /*
+                * We must be sure to create the directory with the correct mode,
+                * not just chmod it after the fact; otherwise, there is a race
+                * condition in which somebody can chdir to it, sleep, then try to open
+                * our protected socket.
+                */
+               if (safe_create_leading_directories_const(dir) < 0)
+                       die_errno("unable to create directories for '%s'", dir);
+               if (mkdir(dir, 0700) < 0)
+                       die_errno("unable to mkdir '%s'", dir);
        }
  
-       /*
-        * We must be sure to create the directory with the correct mode,
-        * not just chmod it after the fact; otherwise, there is a race
-        * condition in which somebody can chdir to it, sleep, then try to open
-        * our protected socket.
-        */
-       if (safe_create_leading_directories_const(dir) < 0)
-               die_errno("unable to create directories for '%s'", dir);
-       if (mkdir(dir, 0700) < 0)
-               die_errno("unable to mkdir '%s'", dir);
+       if (chdir(dir))
+               /*
+                * We don't actually care what our cwd is; we chdir here just to
+                * be a friendly daemon and avoid tying up our original cwd.
+                * If this fails, it's OK to just continue without that benefit.
+                */
+               ;
        free(path_copy);
  }
  
@@@ -264,7 -271,10 +271,10 @@@ int main(int argc, const char **argv
        if (!socket_path)
                usage_with_options(usage, options);
  
-       check_socket_directory(socket_path);
+       if (!is_absolute_path(socket_path))
+               die("socket directory must be an absolute path");
+       init_socket_directory(socket_path);
        register_tempfile(&socket_file, socket_path);
  
        if (ignore_sighup)