diff --git a/src/file.cc b/src/file.cc index 64061d09..0867fa60 100644 --- a/src/file.cc +++ b/src/file.cc @@ -334,7 +334,7 @@ String find_file(StringView filename, ConstArrayView paths) return ""; } -void make_directory(StringView dir) +void make_directory(StringView dir, mode_t mode) { auto it = dir.begin(), end = dir.end(); while(it != end) @@ -352,7 +352,7 @@ void make_directory(StringView dir) auto old_mask = umask(0); auto restore_mask = on_scope_end([old_mask]() { umask(old_mask); }); - if (mkdir(dirname.zstr(), S_IRWXU | S_IRWXG | S_IRWXO) != 0) + if (mkdir(dirname.zstr(), mode) != 0) throw runtime_error(format("mkdir failed for directory '{}' errno {}", dirname, errno)); } } diff --git a/src/file.hh b/src/file.hh index 89d4e45e..006d0cfd 100644 --- a/src/file.hh +++ b/src/file.hh @@ -56,7 +56,7 @@ bool file_exists(StringView filename); Vector list_files(StringView directory); -void make_directory(StringView dir); +void make_directory(StringView dir, mode_t mode); timespec get_fs_timestamp(StringView filename); diff --git a/src/remote.cc b/src/remote.cc index e402322e..138f56c6 100644 --- a/src/remote.cc +++ b/src/remote.cc @@ -480,14 +480,22 @@ void RemoteUI::set_ui_options(const Options& options) m_socket_watcher.events() |= FdEvents::Write; } +static const char* tmpdir() +{ + if (const char* tmpdir = getenv("TMPDIR")) + return tmpdir; + return "/tmp"; +} + static sockaddr_un session_addr(StringView session) { sockaddr_un addr; addr.sun_family = AF_UNIX; if (find(session, '/')!= session.end()) - format_to(addr.sun_path, "/tmp/kakoune/{}", session); + format_to(addr.sun_path, "{}/kakoune/{}", tmpdir(), session); else - format_to(addr.sun_path, "/tmp/kakoune/{}/{}", getpwuid(geteuid())->pw_name, session); + format_to(addr.sun_path, "{}/kakoune/{}/{}", tmpdir(), + getpwuid(geteuid())->pw_name, session); return addr; } @@ -704,7 +712,13 @@ Server::Server(String session_name) fcntl(listen_sock, F_SETFD, FD_CLOEXEC); sockaddr_un addr = session_addr(m_session); - make_directory(split_path(addr.sun_path).first); + // set sticky bit on the shared kakoune directory + make_directory(format("{}/kakoune", tmpdir()), 01777); + make_directory(split_path(addr.sun_path).first, 0711); + + // Do not give any access to the socket to other users by default + auto old_mask = umask(0077); + auto restore_mask = on_scope_end([old_mask]() { umask(old_mask); }); if (bind(listen_sock, (sockaddr*) &addr, sizeof(sockaddr_un)) == -1) throw runtime_error(format("unable to bind listen socket '{}'", addr.sun_path));