When the server socket is given by the user with -S, create it with

umask 177 instead of 117 because it may not be in a safe directory like
the default directory in /tmp. The user can chmod it more open after it
is created if they want.
This commit is contained in:
nicm 2020-03-12 09:26:34 +00:00
parent 4eba98313c
commit 2a5702a936
4 changed files with 33 additions and 24 deletions

View File

@ -97,7 +97,7 @@ client_get_lock(char *lockfile)
/* Connect client to server. */ /* Connect client to server. */
static int static int
client_connect(struct event_base *base, const char *path, int start_server) client_connect(struct event_base *base, const char *path, int flags)
{ {
struct sockaddr_un sa; struct sockaddr_un sa;
size_t size; size_t size;
@ -122,7 +122,7 @@ retry:
log_debug("connect failed: %s", strerror(errno)); log_debug("connect failed: %s", strerror(errno));
if (errno != ECONNREFUSED && errno != ENOENT) if (errno != ECONNREFUSED && errno != ENOENT)
goto failed; goto failed;
if (!start_server) if (~flags & CLIENT_STARTSERVER)
goto failed; goto failed;
close(fd); close(fd);
@ -154,7 +154,7 @@ retry:
close(lockfd); close(lockfd);
return (-1); return (-1);
} }
fd = server_start(client_proc, base, lockfd, lockfile); fd = server_start(client_proc, flags, base, lockfd, lockfile);
} }
if (locked && lockfd >= 0) { if (locked && lockfd >= 0) {
@ -238,7 +238,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
struct cmd_parse_result *pr; struct cmd_parse_result *pr;
struct cmd *cmd; struct cmd *cmd;
struct msg_command *data; struct msg_command *data;
int cmdflags, fd, i; int fd, i;
const char *ttynam, *cwd; const char *ttynam, *cwd;
pid_t ppid; pid_t ppid;
enum msgtype msg; enum msgtype msg;
@ -248,17 +248,13 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
/* Ignore SIGCHLD now or daemon() in the server will leave a zombie. */ /* Ignore SIGCHLD now or daemon() in the server will leave a zombie. */
signal(SIGCHLD, SIG_IGN); signal(SIGCHLD, SIG_IGN);
/* Save the flags. */
client_flags = flags;
/* Set up the initial command. */ /* Set up the initial command. */
cmdflags = 0;
if (shell_command != NULL) { if (shell_command != NULL) {
msg = MSG_SHELL; msg = MSG_SHELL;
cmdflags = CMD_STARTSERVER; flags = CLIENT_STARTSERVER;
} else if (argc == 0) { } else if (argc == 0) {
msg = MSG_COMMAND; msg = MSG_COMMAND;
cmdflags = CMD_STARTSERVER; flags |= CLIENT_STARTSERVER;
} else { } else {
msg = MSG_COMMAND; msg = MSG_COMMAND;
@ -271,19 +267,22 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
if (pr->status == CMD_PARSE_SUCCESS) { if (pr->status == CMD_PARSE_SUCCESS) {
TAILQ_FOREACH(cmd, &pr->cmdlist->list, qentry) { TAILQ_FOREACH(cmd, &pr->cmdlist->list, qentry) {
if (cmd->entry->flags & CMD_STARTSERVER) if (cmd->entry->flags & CMD_STARTSERVER)
cmdflags |= CMD_STARTSERVER; flags |= CLIENT_STARTSERVER;
} }
cmd_list_free(pr->cmdlist); cmd_list_free(pr->cmdlist);
} else } else
free(pr->error); free(pr->error);
} }
/* Save the flags. */
client_flags = flags;
/* Create client process structure (starts logging). */ /* Create client process structure (starts logging). */
client_proc = proc_start("client"); client_proc = proc_start("client");
proc_set_signals(client_proc, client_signal); proc_set_signals(client_proc, client_signal);
/* Initialize the client socket and start the server. */ /* Initialize the client socket and start the server. */
fd = client_connect(base, socket_path, cmdflags & CMD_STARTSERVER); fd = client_connect(base, socket_path, client_flags);
if (fd == -1) { if (fd == -1) {
if (errno == ECONNREFUSED) { if (errno == ECONNREFUSED) {
fprintf(stderr, "no server running on %s\n", fprintf(stderr, "no server running on %s\n",

View File

@ -45,6 +45,7 @@ struct clients clients;
struct tmuxproc *server_proc; struct tmuxproc *server_proc;
static int server_fd = -1; static int server_fd = -1;
static int server_client_flags;
static int server_exit; static int server_exit;
static struct event server_ev_accept; static struct event server_ev_accept;
@ -98,7 +99,7 @@ server_check_marked(void)
/* Create server socket. */ /* Create server socket. */
static int static int
server_create_socket(char **cause) server_create_socket(int flags, char **cause)
{ {
struct sockaddr_un sa; struct sockaddr_un sa;
size_t size; size_t size;
@ -117,7 +118,10 @@ server_create_socket(char **cause)
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
goto fail; goto fail;
mask = umask(S_IXUSR|S_IXGRP|S_IRWXO); if (flags & CLIENT_DEFAULTSOCKET)
mask = umask(S_IXUSR|S_IXGRP|S_IRWXO);
else
mask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
if (bind(fd, (struct sockaddr *)&sa, sizeof sa) == -1) { if (bind(fd, (struct sockaddr *)&sa, sizeof sa) == -1) {
saved_errno = errno; saved_errno = errno;
close(fd); close(fd);
@ -146,8 +150,8 @@ fail:
/* Fork new server. */ /* Fork new server. */
int int
server_start(struct tmuxproc *client, struct event_base *base, int lockfd, server_start(struct tmuxproc *client, int flags, struct event_base *base,
char *lockfile) int lockfd, char *lockfile)
{ {
int pair[2]; int pair[2];
sigset_t set, oldset; sigset_t set, oldset;
@ -156,6 +160,7 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd,
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0) if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
fatal("socketpair failed"); fatal("socketpair failed");
server_client_flags = flags;
sigfillset(&set); sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, &oldset); sigprocmask(SIG_BLOCK, &set, &oldset);
@ -193,7 +198,7 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd,
gettimeofday(&start_time, NULL); gettimeofday(&start_time, NULL);
server_fd = server_create_socket(&cause); server_fd = server_create_socket(flags, &cause);
if (server_fd != -1) if (server_fd != -1)
server_update_socket(); server_update_socket();
c = server_client_create(pair[1]); c = server_client_create(pair[1]);
@ -396,7 +401,7 @@ server_signal(int sig)
break; break;
case SIGUSR1: case SIGUSR1:
event_del(&server_ev_accept); event_del(&server_ev_accept);
fd = server_create_socket(NULL); fd = server_create_socket(server_client_flags, NULL);
if (fd != -1) { if (fd != -1) {
close(server_fd); close(server_fd);
server_fd = fd; server_fd = fd;

13
tmux.c
View File

@ -379,12 +379,15 @@ main(int argc, char **argv)
path[strcspn(path, ",")] = '\0'; path[strcspn(path, ",")] = '\0';
} }
} }
if (path == NULL && (path = make_label(label, &cause)) == NULL) { if (path == NULL) {
if (cause != NULL) { if ((path = make_label(label, &cause)) == NULL) {
fprintf(stderr, "%s\n", cause); if (cause != NULL) {
free(cause); fprintf(stderr, "%s\n", cause);
free(cause);
}
exit(1);
} }
exit(1); flags |= CLIENT_DEFAULTSOCKET;
} }
socket_path = path; socket_path = path;
free(label); free(label);

4
tmux.h
View File

@ -1577,6 +1577,8 @@ struct client {
#define CLIENT_REDRAWSTATUSALWAYS 0x1000000 #define CLIENT_REDRAWSTATUSALWAYS 0x1000000
#define CLIENT_REDRAWOVERLAY 0x2000000 #define CLIENT_REDRAWOVERLAY 0x2000000
#define CLIENT_CONTROL_NOOUTPUT 0x4000000 #define CLIENT_CONTROL_NOOUTPUT 0x4000000
#define CLIENT_DEFAULTSOCKET 0x8000000
#define CLIENT_STARTSERVER 0x10000000
#define CLIENT_ALLREDRAWFLAGS \ #define CLIENT_ALLREDRAWFLAGS \
(CLIENT_REDRAWWINDOW| \ (CLIENT_REDRAWWINDOW| \
CLIENT_REDRAWSTATUS| \ CLIENT_REDRAWSTATUS| \
@ -2200,7 +2202,7 @@ void server_clear_marked(void);
int server_is_marked(struct session *, struct winlink *, int server_is_marked(struct session *, struct winlink *,
struct window_pane *); struct window_pane *);
int server_check_marked(void); int server_check_marked(void);
int server_start(struct tmuxproc *, struct event_base *, int, char *); int server_start(struct tmuxproc *, int, struct event_base *, int, char *);
void server_update_socket(void); void server_update_socket(void);
void server_add_accept(int); void server_add_accept(int);