Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'

* refs/remotes/tmux-openbsd/master:
  Tighten up TMUX_TMPDIR - do not allow relative paths or .. or if realpath fails. From Alexandre Fiori.
This commit is contained in:
tmux update bot
2026-09-25 23:37:17 +00:00
2 changed files with 55 additions and 10 deletions

7
tmux.1
View File

@@ -1,4 +1,4 @@
.\" $OpenBSD: tmux.1,v 1.1173 2026/09/23 12:37:50 nicm Exp $ .\" $OpenBSD: tmux.1,v 1.1174 2026/09/25 13:44:49 nicm Exp $
.\" .\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\" .\"
@@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: September 23 2026 $ .Dd $Mdocdate: September 25 2026 $
.Dt TMUX 1 .Dt TMUX 1
.Os .Os
.Sh NAME .Sh NAME
@@ -9192,6 +9192,9 @@ See the
option for details. option for details.
.It Ev TMUX_TMPDIR .It Ev TMUX_TMPDIR
The parent directory of the directory containing the server sockets. The parent directory of the directory containing the server sockets.
It must be an absolute path to an existing directory and must not contain
.Ql .. ;
if it is empty it is ignored.
See the See the
.Fl L .Fl L
option for details. option for details.

58
tmux.c
View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tmux.c,v 1.224 2026/09/25 09:11:18 nicm Exp $ */ /* $OpenBSD: tmux.c,v 1.225 2026/09/25 13:44:49 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -201,10 +201,33 @@ expand_paths(const char *s, char ***paths, u_int *n, int no_realpath)
free(copy); free(copy);
} }
static int
check_socket_path(const char *path, char **cause)
{
char *copy, *next, *tmp;
if (*path != '/') {
xasprintf(cause, "socket directory %s is not an absolute path",
path);
return (0);
}
copy = tmp = xstrdup(path);
while ((next = strsep(&tmp, "/")) != NULL) {
if (strcmp(next, "..") == 0) {
xasprintf(cause, "socket directory %s contains ..",
path);
free(copy);
return (0);
}
}
free(copy);
return (1);
}
static char * static char *
make_label(const char *label, char **cause) make_label(const char *label, char **cause)
{ {
char **paths, *path, *base; char **paths, *path = NULL, *base, resolved[PATH_MAX];
u_int i, n; u_int i, n;
struct stat sb; struct stat sb;
uid_t uid; uid_t uid;
@@ -214,15 +237,34 @@ make_label(const char *label, char **cause)
label = "default"; label = "default";
uid = getuid(); uid = getuid();
expand_paths(TMUX_SOCK, &paths, &n, 0); /*
if (n == 0) { * An unset variable has already been dropped and an empty one is
xasprintf(cause, "no suitable socket path"); * skipped, but anything else must be an existing absolute path with no
return (NULL); * ".." or it is an error.
*/
expand_paths(TMUX_SOCK, &paths, &n, 1);
for (i = 0; i < n; i++) {
if (*paths[i] == '\0')
continue;
if (!check_socket_path(paths[i], cause))
break;
if (realpath(paths[i], resolved) == NULL) {
xasprintf(cause,
"couldn't resolve socket directory %s (%s)",
paths[i], strerror(errno));
break;
}
path = xstrdup(resolved);
break;
} }
path = paths[0]; /* can only have one socket! */ for (i = 0; i < n; i++)
for (i = 1; i < n; i++)
free(paths[i]); free(paths[i]);
free(paths); free(paths);
if (path == NULL) {
if (*cause == NULL)
xasprintf(cause, "no suitable socket path");
return (NULL);
}
xasprintf(&base, "%s/tmux-%ld", path, (long)uid); xasprintf(&base, "%s/tmux-%ld", path, (long)uid);
free(path); free(path);