Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
/* Test whether a file has a nontrivial ACL. -*- coding: utf-8 -*-
|
|
|
|
|
2025-01-01 07:39:17 +00:00
|
|
|
Copyright (C) 2002-2003, 2005-2025 Free Software Foundation, Inc.
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2022-02-23 11:11:52 -08:00
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible. */
|
|
|
|
|
2024-09-05 08:41:11 +08:00
|
|
|
#include <config.h>
|
|
|
|
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
/* Without this pragma, gcc 4.7.0 20120126 may suggest that the
|
|
|
|
file_has_acl function might be candidate for attribute 'const' */
|
2024-09-05 08:41:11 +08:00
|
|
|
#if _GL_GNUC_PREREQ (4, 6)
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
# pragma GCC diagnostic ignored "-Wsuggest-attribute=const"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "acl.h"
|
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
#include <dirent.h>
|
|
|
|
#include <limits.h>
|
|
|
|
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
#include "acl-internal.h"
|
2023-06-07 12:00:15 -07:00
|
|
|
#include "attribute.h"
|
2023-05-15 22:09:04 -07:00
|
|
|
#include "minmax.h"
|
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
/* Check the assumption that UCHAR_MAX < INT_MAX. */
|
|
|
|
static_assert (ACL_SYMLINK_FOLLOW & ~ (unsigned char) -1);
|
|
|
|
|
|
|
|
static char const UNKNOWN_SECURITY_CONTEXT[] = "?";
|
|
|
|
|
|
|
|
#if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
|
|
|
|
# define USE_LINUX_XATTR true
|
|
|
|
#else
|
|
|
|
# define USE_LINUX_XATTR false
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if USE_LINUX_XATTR
|
|
|
|
# if USE_SELINUX_SELINUX_H
|
|
|
|
# include <selinux/selinux.h>
|
|
|
|
# endif
|
2023-05-15 22:09:04 -07:00
|
|
|
# include <stdckdint.h>
|
2024-12-17 14:02:41 -08:00
|
|
|
# include <stdint.h>
|
2022-12-23 23:15:52 -08:00
|
|
|
# include <string.h>
|
|
|
|
# include <arpa/inet.h>
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
# include <sys/xattr.h>
|
|
|
|
# include <linux/xattr.h>
|
2025-01-01 15:18:19 -08:00
|
|
|
# ifndef XATTR_NAME_SMACK
|
|
|
|
# define XATTR_NAME_SMACK "security.SMACK64"
|
|
|
|
# endif
|
|
|
|
# ifndef XATTR_NAME_SELINUX
|
|
|
|
# define XATTR_NAME_SELINUX "security.selinux"
|
|
|
|
# endif
|
2022-12-23 23:15:52 -08:00
|
|
|
# ifndef XATTR_NAME_NFSV4_ACL
|
|
|
|
# define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
|
|
|
|
# endif
|
2023-06-07 12:00:15 -07:00
|
|
|
# ifndef XATTR_NAME_POSIX_ACL_ACCESS
|
|
|
|
# define XATTR_NAME_POSIX_ACL_ACCESS "system.posix_acl_access"
|
|
|
|
# endif
|
|
|
|
# ifndef XATTR_NAME_POSIX_ACL_DEFAULT
|
|
|
|
# define XATTR_NAME_POSIX_ACL_DEFAULT "system.posix_acl_default"
|
|
|
|
# endif
|
2022-12-23 23:15:52 -08:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# ifdef HAVE_SMACK
|
|
|
|
# include <sys/smack.h>
|
|
|
|
# else
|
|
|
|
static char const *
|
|
|
|
smack_smackfs_path (void)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
static ssize_t
|
|
|
|
smack_new_label_from_path (MAYBE_UNUSED const char *path,
|
|
|
|
MAYBE_UNUSED const char *xattr,
|
|
|
|
MAYBE_UNUSED int follow, MAYBE_UNUSED char **label)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
static bool
|
|
|
|
is_smack_enabled (void)
|
|
|
|
{
|
|
|
|
return !!smack_smackfs_path ();
|
|
|
|
}
|
|
|
|
|
2022-12-23 23:15:52 -08:00
|
|
|
enum {
|
|
|
|
/* ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000, */
|
|
|
|
ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001,
|
|
|
|
ACE4_IDENTIFIER_GROUP = 0x00000040
|
|
|
|
};
|
|
|
|
|
2025-01-15 19:31:07 -08:00
|
|
|
/* AI indicates XATTR may be present but wasn't accessible.
|
|
|
|
This is the case when [l]listxattr failed with E2BIG,
|
|
|
|
or failed with EACCES which in Linux kernel 6.12 NFS can mean merely
|
|
|
|
that we lack read access.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static bool
|
|
|
|
aclinfo_may_indicate_xattr (struct aclinfo const *ai)
|
|
|
|
{
|
|
|
|
return ai->size < 0 && (ai->u.err == EACCES || ai->u.err == E2BIG);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Does NAME have XATTR? */
|
|
|
|
|
|
|
|
static bool
|
|
|
|
has_xattr (char const *xattr, struct aclinfo const *ai,
|
|
|
|
MAYBE_UNUSED char const *restrict name, MAYBE_UNUSED int flags)
|
|
|
|
{
|
|
|
|
if (ai && aclinfo_has_xattr (ai, xattr))
|
|
|
|
return true;
|
|
|
|
else if (!ai || aclinfo_may_indicate_xattr (ai))
|
|
|
|
{
|
|
|
|
int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr)
|
|
|
|
(name, xattr, NULL, 0));
|
|
|
|
if (0 <= ret || (errno == ERANGE || errno == E2BIG))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
/* Does AI's xattr set contain XATTR? */
|
2023-05-14 18:51:22 -07:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
bool
|
|
|
|
aclinfo_has_xattr (struct aclinfo const *ai, char const *xattr)
|
2023-05-14 18:51:22 -07:00
|
|
|
{
|
2024-12-17 14:02:41 -08:00
|
|
|
if (0 < ai->size)
|
|
|
|
{
|
|
|
|
char const *blim = ai->buf + ai->size;
|
|
|
|
for (char const *b = ai->buf; b < blim; b += strlen (b) + 1)
|
|
|
|
for (char const *a = xattr; *a == *b; a++, b++)
|
|
|
|
if (!*a)
|
|
|
|
return true;
|
|
|
|
}
|
2023-05-14 18:51:22 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
/* Get attributes of the file NAME into AI, if USE_ACL.
|
|
|
|
If FLAGS & ACL_GET_SCONTEXT, also get security context.
|
|
|
|
If FLAGS & ACL_SYMLINK_FOLLOW, follow symbolic links. */
|
|
|
|
static void
|
|
|
|
get_aclinfo (char const *name, struct aclinfo *ai, int flags)
|
|
|
|
{
|
|
|
|
int scontext_err = ENOTSUP;
|
|
|
|
ai->buf = ai->u.__gl_acl_ch;
|
|
|
|
ssize_t acl_alloc = sizeof ai->u.__gl_acl_ch;
|
|
|
|
|
|
|
|
if (! (USE_ACL || flags & ACL_GET_SCONTEXT))
|
|
|
|
ai->size = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ssize_t (*lsxattr) (char const *, char *, size_t)
|
|
|
|
= (flags & ACL_SYMLINK_FOLLOW ? listxattr : llistxattr);
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
ai->size = lsxattr (name, ai->buf, acl_alloc);
|
|
|
|
if (0 < ai->size)
|
|
|
|
break;
|
|
|
|
ai->u.err = ai->size < 0 ? errno : 0;
|
|
|
|
if (! (ai->size < 0 && ai->u.err == ERANGE && acl_alloc < SSIZE_MAX))
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* The buffer was too small. Find how large it should have been. */
|
|
|
|
ssize_t size = lsxattr (name, NULL, 0);
|
|
|
|
if (size <= 0)
|
|
|
|
{
|
|
|
|
ai->size = size;
|
|
|
|
ai->u.err = size < 0 ? errno : 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Grow allocation to at least 'size'. Grow it by a nontrivial
|
|
|
|
amount, to defend against denial of service by an adversary
|
|
|
|
that fiddles with ACLs. */
|
|
|
|
if (ai->buf != ai->u.__gl_acl_ch)
|
|
|
|
{
|
|
|
|
free (ai->buf);
|
|
|
|
ai->buf = ai->u.__gl_acl_ch;
|
|
|
|
}
|
|
|
|
if (ckd_add (&acl_alloc, acl_alloc, acl_alloc >> 1))
|
|
|
|
acl_alloc = SSIZE_MAX;
|
|
|
|
if (acl_alloc < size)
|
|
|
|
acl_alloc = size;
|
|
|
|
if (SIZE_MAX < acl_alloc)
|
|
|
|
{
|
|
|
|
ai->u.err = ENOMEM;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
char *newbuf = malloc (acl_alloc);
|
|
|
|
if (!newbuf)
|
|
|
|
{
|
|
|
|
ai->u.err = errno;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ai->buf = newbuf;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-15 19:31:07 -08:00
|
|
|
/* A security context can exist only if extended attributes do. */
|
|
|
|
if (flags & ACL_GET_SCONTEXT
|
|
|
|
&& (0 < ai->size || aclinfo_may_indicate_xattr (ai)))
|
2024-12-17 14:02:41 -08:00
|
|
|
{
|
|
|
|
if (is_smack_enabled ())
|
|
|
|
{
|
2025-01-15 19:31:07 -08:00
|
|
|
if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SMACK))
|
2024-12-17 14:02:41 -08:00
|
|
|
{
|
|
|
|
ssize_t r = smack_new_label_from_path (name, "security.SMACK64",
|
|
|
|
flags & ACL_SYMLINK_FOLLOW,
|
|
|
|
&ai->scontext);
|
|
|
|
scontext_err = r < 0 ? errno : 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
# if USE_SELINUX_SELINUX_H
|
2025-01-15 19:31:07 -08:00
|
|
|
if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SELINUX))
|
2024-12-17 14:02:41 -08:00
|
|
|
{
|
|
|
|
ssize_t r =
|
|
|
|
((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon)
|
|
|
|
(name, &ai->scontext));
|
|
|
|
scontext_err = r < 0 ? errno : 0;
|
|
|
|
# ifndef SE_SELINUX_INLINE
|
|
|
|
/* Gnulib's selinux-h module is not in use, so getfilecon and
|
|
|
|
lgetfilecon can misbehave, be it via an old version of
|
|
|
|
libselinux where these would return 0 and set the result
|
|
|
|
context to NULL, or via a modern kernel+lib operating on a
|
|
|
|
file from a disk whose attributes were set by a kernel from
|
|
|
|
around 2006. In that latter case, the functions return a
|
|
|
|
length of 10 for the "unlabeled" context. Map both failures
|
|
|
|
to a return value of -1, and set errno to ENOTSUP in the
|
|
|
|
first case, and ENODATA in the latter. */
|
|
|
|
if (r == 0)
|
|
|
|
scontext_err = ENOTSUP;
|
|
|
|
if (r == 10 && memcmp (ai->scontext, "unlabeled", 10) == 0)
|
|
|
|
{
|
|
|
|
freecon (ai->scontext);
|
|
|
|
scontext_err = ENODATA;
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ai->scontext_err = scontext_err;
|
|
|
|
if (scontext_err)
|
|
|
|
ai->scontext = (char *) UNKNOWN_SECURITY_CONTEXT;
|
|
|
|
}
|
|
|
|
|
|
|
|
# ifndef aclinfo_scontext_free
|
|
|
|
/* Free the pointer that file_has_aclinfo put into scontext.
|
|
|
|
However, do nothing if the argument is a null pointer;
|
|
|
|
This lets the caller replace the scontext member with a null pointer if it
|
|
|
|
is willing to own the member and call this function later. */
|
|
|
|
void
|
|
|
|
aclinfo_scontext_free (char *scontext)
|
|
|
|
{
|
|
|
|
if (scontext != UNKNOWN_SECURITY_CONTEXT)
|
|
|
|
{
|
|
|
|
if (is_smack_enabled ())
|
|
|
|
free (scontext);
|
|
|
|
else if (scontext)
|
|
|
|
freecon (scontext);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
|
|
|
/* Free AI's heap storage. */
|
|
|
|
void
|
|
|
|
aclinfo_free (struct aclinfo *ai)
|
|
|
|
{
|
|
|
|
if (ai->buf != ai->u.__gl_acl_ch)
|
|
|
|
free (ai->buf);
|
|
|
|
aclinfo_scontext_free (ai->scontext);
|
|
|
|
}
|
|
|
|
|
2022-12-23 23:15:52 -08:00
|
|
|
/* Return 1 if given ACL in XDR format is non-trivial, 0 if it is trivial.
|
|
|
|
-1 upon failure to determine it. Possibly change errno. Assume that
|
|
|
|
the ACL is valid, except avoid undefined behavior even if invalid.
|
|
|
|
|
|
|
|
See <https://linux.die.net/man/5/nfs4_acl>. The NFSv4 acls are
|
|
|
|
defined in Internet RFC 7530 and as such, every NFSv4 server
|
|
|
|
supporting ACLs should support NFSv4 ACLs (they differ from from
|
|
|
|
POSIX draft ACLs). The ACLs can be obtained via the
|
|
|
|
nfsv4-acl-tools, e.g., the nfs4_getfacl command. Gnulib provides
|
|
|
|
only basic support of NFSv4 ACLs, i.e., recognize trivial vs
|
|
|
|
nontrivial ACLs. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes)
|
|
|
|
{
|
|
|
|
enum { BYTES_PER_NETWORK_UINT = 4};
|
|
|
|
|
|
|
|
/* Grab the number of aces in the acl. */
|
|
|
|
nbytes -= BYTES_PER_NETWORK_UINT;
|
|
|
|
if (nbytes < 0)
|
|
|
|
return -1;
|
|
|
|
uint32_t num_aces = ntohl (*xattr++);
|
|
|
|
if (6 < num_aces)
|
|
|
|
return 1;
|
|
|
|
int ace_found = 0;
|
|
|
|
|
|
|
|
for (int ace_n = 0; ace_n < num_aces; ace_n++)
|
|
|
|
{
|
|
|
|
/* Get the acl type and flag. Skip the mask; it's too risky to
|
|
|
|
test it and it does not seem to be needed. Get the wholen. */
|
|
|
|
nbytes -= 4 * BYTES_PER_NETWORK_UINT;
|
|
|
|
if (nbytes < 0)
|
|
|
|
return -1;
|
|
|
|
uint32_t type = ntohl (xattr[0]);
|
|
|
|
uint32_t flag = ntohl (xattr[1]);
|
|
|
|
uint32_t wholen = ntohl (xattr[3]);
|
|
|
|
xattr += 4;
|
2023-01-06 17:53:54 -08:00
|
|
|
int whowords = (wholen / BYTES_PER_NETWORK_UINT
|
|
|
|
+ (wholen % BYTES_PER_NETWORK_UINT != 0));
|
|
|
|
int64_t wholen4 = whowords;
|
|
|
|
wholen4 *= BYTES_PER_NETWORK_UINT;
|
2022-12-23 23:15:52 -08:00
|
|
|
|
|
|
|
/* Trivial ACLs have only ACE4_ACCESS_ALLOWED_ACE_TYPE or
|
|
|
|
ACE4_ACCESS_DENIED_ACE_TYPE. */
|
|
|
|
if (ACE4_ACCESS_DENIED_ACE_TYPE < type)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
/* RFC 7530 says FLAG should be 0, but be generous to NetApp and
|
|
|
|
also accept the group flag. */
|
|
|
|
if (flag & ~ACE4_IDENTIFIER_GROUP)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
/* Get the who string. Check NBYTES - WHOLEN4 before storing
|
|
|
|
into NBYTES, to avoid truncation on conversion. */
|
|
|
|
if (nbytes - wholen4 < 0)
|
|
|
|
return -1;
|
|
|
|
nbytes -= wholen4;
|
|
|
|
|
|
|
|
/* For a trivial ACL, max 6 (typically 3) ACEs, 3 allow, 3 deny.
|
|
|
|
Check that there is at most one ACE of each TYPE and WHO. */
|
|
|
|
int who2
|
|
|
|
= (wholen == 6 && memcmp (xattr, "OWNER@", 6) == 0 ? 0
|
|
|
|
: wholen == 6 && memcmp (xattr, "GROUP@", 6) == 0 ? 2
|
|
|
|
: wholen == 9 && memcmp (xattr, "EVERYONE@", 9) == 0 ? 4
|
|
|
|
: -1);
|
|
|
|
if (who2 < 0)
|
|
|
|
return 1;
|
|
|
|
int ace_found_bit = 1 << (who2 | type);
|
|
|
|
if (ace_found & ace_found_bit)
|
|
|
|
return 1;
|
|
|
|
ace_found |= ace_found_bit;
|
|
|
|
|
2023-01-06 17:53:54 -08:00
|
|
|
xattr += whowords;
|
2022-12-23 23:15:52 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Return 1 if NAME has a nontrivial access control list,
|
|
|
|
0 if ACLs are not supported, or if NAME has no or only a base ACL,
|
|
|
|
and -1 (setting errno) on error. Note callers can determine
|
|
|
|
if ACLs are not supported as errno is set in that case also.
|
2024-12-17 14:02:41 -08:00
|
|
|
Set *AI to ACL info regardless of return value.
|
|
|
|
FLAGS should be a <dirent.h> d_type value, optionally ORed with
|
|
|
|
- _GL_DT_NOTDIR if it is known that NAME is not a directory,
|
|
|
|
- ACL_GET_SCONTEXT to retrieve security context and return 1 if present,
|
|
|
|
- ACL_SYMLINK_FOLLOW to follow the link if NAME is a symbolic link;
|
|
|
|
otherwise do not follow them if possible.
|
|
|
|
If the d_type value is not known, use DT_UNKNOWN though this may be less
|
|
|
|
efficient. */
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
int
|
2024-12-17 14:02:41 -08:00
|
|
|
file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
|
|
|
|
struct aclinfo *restrict ai, int flags)
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
{
|
2024-12-17 14:02:41 -08:00
|
|
|
MAYBE_UNUSED unsigned char d_type = flags & UCHAR_MAX;
|
|
|
|
|
|
|
|
#if USE_LINUX_XATTR
|
|
|
|
int initial_errno = errno;
|
|
|
|
get_aclinfo (name, ai, flags);
|
|
|
|
|
2025-01-15 19:31:07 -08:00
|
|
|
if (!aclinfo_may_indicate_xattr (ai) && ai->size <= 0)
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
{
|
2024-12-17 14:02:41 -08:00
|
|
|
errno = ai->size < 0 ? ai->u.err : initial_errno;
|
|
|
|
return ai->size;
|
|
|
|
}
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
/* In Fedora 39, a file can have both NFSv4 and POSIX ACLs,
|
|
|
|
but if it has an NFSv4 ACL that's the one that matters.
|
|
|
|
In earlier Fedora the two types of ACLs were mutually exclusive.
|
|
|
|
Attempt to work correctly on both kinds of systems. */
|
|
|
|
|
2025-01-15 19:31:07 -08:00
|
|
|
if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, name, flags))
|
2024-12-17 14:02:41 -08:00
|
|
|
return
|
2025-01-15 19:31:07 -08:00
|
|
|
(has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, name, flags)
|
2024-12-17 14:02:41 -08:00
|
|
|
|| ((d_type == DT_DIR || d_type == DT_UNKNOWN)
|
2025-01-15 19:31:07 -08:00
|
|
|
&& has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, name, flags)));
|
2024-12-17 14:02:41 -08:00
|
|
|
|
|
|
|
/* A buffer large enough to hold any trivial NFSv4 ACL.
|
|
|
|
The max length of a trivial NFSv4 ACL is 6 words for owner,
|
|
|
|
6 for group, 7 for everyone, all times 2 because there are both
|
|
|
|
allow and deny ACEs. There are 6 words for owner because of
|
|
|
|
type, flag, mask, wholen, "OWNER@"+pad and similarly for group;
|
|
|
|
everyone is another word to hold "EVERYONE@". */
|
|
|
|
uint32_t buf[2 * (6 + 6 + 7)];
|
|
|
|
|
|
|
|
int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr)
|
|
|
|
(name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf));
|
|
|
|
if (ret < 0)
|
|
|
|
switch (errno)
|
|
|
|
{
|
|
|
|
case ENODATA: return 0;
|
|
|
|
case ERANGE : return 1; /* ACL must be nontrivial. */
|
|
|
|
default: return - acl_errno_valid (errno);
|
|
|
|
}
|
2023-05-15 22:09:04 -07:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
/* It looks like a trivial ACL, but investigate further. */
|
|
|
|
ret = acl_nfs4_nontrivial (buf, ret);
|
|
|
|
errno = ret < 0 ? EINVAL : initial_errno;
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
#else /* !USE_LINUX_XATTR */
|
|
|
|
|
|
|
|
ai->buf = ai->u.__gl_acl_ch;
|
|
|
|
ai->size = -1;
|
|
|
|
ai->u.err = ENOTSUP;
|
|
|
|
ai->scontext = (char *) UNKNOWN_SECURITY_CONTEXT;
|
|
|
|
ai->scontext_err = ENOTSUP;
|
|
|
|
|
|
|
|
# if USE_ACL
|
|
|
|
# if HAVE_ACL_GET_FILE
|
|
|
|
|
|
|
|
{
|
|
|
|
/* POSIX 1003.1e (draft 17 -- abandoned) specific version. */
|
|
|
|
/* Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
# if HAVE_ACL_EXTENDED_FILE /* Linux */
|
|
|
|
/* On Linux, acl_extended_file is an optimized function: It only
|
|
|
|
makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for
|
|
|
|
ACL_TYPE_DEFAULT. */
|
|
|
|
ret = ((flags & ACL_SYMLINK_FOLLOW
|
|
|
|
? acl_extended_file
|
|
|
|
: acl_extended_file_nofollow)
|
|
|
|
(name));
|
|
|
|
# elif HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
|
|
|
|
/* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS)
|
|
|
|
and acl_get_file (name, ACL_TYPE_DEFAULT)
|
|
|
|
always return NULL / EINVAL. There is no point in making
|
|
|
|
these two useless calls. The real ACL is retrieved through
|
|
|
|
acl_get_file (name, ACL_TYPE_EXTENDED). */
|
|
|
|
acl_t acl = ((flags & ACL_SYMLINK_FOLLOW
|
|
|
|
? acl_get_file
|
|
|
|
: acl_get_link_np)
|
|
|
|
(name, ACL_TYPE_EXTENDED));
|
|
|
|
if (acl)
|
|
|
|
{
|
|
|
|
ret = acl_extended_nontrivial (acl);
|
|
|
|
acl_free (acl);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = -1;
|
|
|
|
# else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */
|
|
|
|
acl_t (*acl_get_file_or_link) (char const *, acl_type_t) = acl_get_file;
|
|
|
|
# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10 */
|
|
|
|
if (! (flags & ACL_SYMLINK_FOLLOW))
|
|
|
|
acl_get_file_or_link = acl_get_link_np;
|
|
|
|
# endif
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
acl_t acl = acl_get_file_or_link (name, ACL_TYPE_ACCESS);
|
|
|
|
if (acl)
|
|
|
|
{
|
|
|
|
ret = acl_access_nontrivial (acl);
|
|
|
|
int saved_errno = errno;
|
|
|
|
acl_free (acl);
|
|
|
|
errno = saved_errno;
|
|
|
|
# if HAVE_ACL_FREE_TEXT /* Tru64 */
|
|
|
|
/* On OSF/1, acl_get_file (name, ACL_TYPE_DEFAULT) always
|
|
|
|
returns NULL with errno not set. There is no point in
|
|
|
|
making this call. */
|
|
|
|
# else /* FreeBSD, NetBSD >= 10, IRIX, Cygwin >= 2.5 */
|
|
|
|
/* On Linux, FreeBSD, NetBSD, IRIX,
|
|
|
|
acl_get_file (name, ACL_TYPE_ACCESS)
|
|
|
|
and acl_get_file (name, ACL_TYPE_DEFAULT) on a directory
|
|
|
|
either both succeed or both fail; it depends on the
|
|
|
|
file system. Therefore there is no point in making the second
|
|
|
|
call if the first one already failed. */
|
|
|
|
if (ret == 0
|
|
|
|
&& (d_type == DT_DIR
|
|
|
|
|| (d_type == DT_UNKNOWN && !(flags & _GL_DT_NOTDIR))))
|
|
|
|
{
|
|
|
|
acl = acl_get_file_or_link (name, ACL_TYPE_DEFAULT);
|
|
|
|
if (acl)
|
2022-12-23 23:15:52 -08:00
|
|
|
{
|
2024-12-17 14:02:41 -08:00
|
|
|
# ifdef __CYGWIN__ /* Cygwin >= 2.5 */
|
|
|
|
ret = acl_access_nontrivial (acl);
|
|
|
|
saved_errno = errno;
|
|
|
|
acl_free (acl);
|
|
|
|
errno = saved_errno;
|
|
|
|
# else
|
|
|
|
ret = (0 < acl_entries (acl));
|
|
|
|
acl_free (acl);
|
|
|
|
# endif
|
2022-12-23 23:15:52 -08:00
|
|
|
}
|
2024-12-17 14:02:41 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = -1;
|
|
|
|
# ifdef __CYGWIN__ /* Cygwin >= 2.5 */
|
|
|
|
if (d_type == DT_UNKNOWN)
|
|
|
|
ret = 0;
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = -1;
|
|
|
|
# endif
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
return ret < 0 ? - acl_errno_valid (errno) : ret;
|
|
|
|
}
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# else /* !HAVE_ACL_GET_FILE */
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
/* The remaining APIs always follow symlinks and operate on
|
|
|
|
platforms where symlinks do not have ACLs, so skip the APIs if
|
|
|
|
NAME is known to be a symlink. */
|
|
|
|
if (d_type != DT_LNK)
|
|
|
|
{
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# if HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# ifdef ACL_NO_TRIVIAL
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
|
|
|
/* Solaris 10 (newer version), which has additional API declared in
|
|
|
|
<sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial,
|
|
|
|
acl_fromtext, ...). */
|
|
|
|
return acl_trivial (name);
|
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# else /* Solaris, Cygwin, general case */
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
|
|
|
/* Solaris 2.5 through Solaris 10, Cygwin, and contemporaneous versions
|
|
|
|
of Unixware. The acl() call returns the access and default ACL both
|
|
|
|
at once. */
|
|
|
|
{
|
|
|
|
/* Initially, try to read the entries into a stack-allocated buffer.
|
|
|
|
Use malloc if it does not fit. */
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
alloc_init = 4000 / sizeof (aclent_t), /* >= 3 */
|
|
|
|
alloc_max = MIN (INT_MAX, SIZE_MAX / sizeof (aclent_t))
|
|
|
|
};
|
|
|
|
aclent_t buf[alloc_init];
|
|
|
|
size_t alloc = alloc_init;
|
|
|
|
aclent_t *entries = buf;
|
|
|
|
aclent_t *malloced = NULL;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
count = acl (name, GETACL, alloc, entries);
|
|
|
|
if (count < 0 && errno == ENOSPC)
|
|
|
|
{
|
|
|
|
/* Increase the size of the buffer. */
|
|
|
|
free (malloced);
|
|
|
|
if (alloc > alloc_max / 2)
|
|
|
|
{
|
|
|
|
errno = ENOMEM;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
alloc = 2 * alloc; /* <= alloc_max */
|
|
|
|
entries = malloced =
|
|
|
|
(aclent_t *) malloc (alloc * sizeof (aclent_t));
|
|
|
|
if (entries == NULL)
|
2024-12-17 14:02:41 -08:00
|
|
|
return -1;
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (count < 0)
|
|
|
|
{
|
|
|
|
if (errno == ENOSYS || errno == ENOTSUP)
|
|
|
|
;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
free (malloced);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (count == 0)
|
|
|
|
;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Don't use MIN_ACL_ENTRIES: It's set to 4 on Cygwin, but Cygwin
|
|
|
|
returns only 3 entries for files with no ACL. But this is safe:
|
|
|
|
If there are more than 4 entries, there cannot be only the
|
|
|
|
"user::", "group::", "other:", and "mask:" entries. */
|
|
|
|
if (count > 4)
|
|
|
|
{
|
|
|
|
free (malloced);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (acl_nontrivial (count, entries))
|
|
|
|
{
|
|
|
|
free (malloced);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free (malloced);
|
|
|
|
}
|
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# ifdef ACE_GETACL
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
/* Solaris also has a different variant of ACLs, used in ZFS and NFSv4
|
|
|
|
file systems (whereas the other ones are used in UFS file systems). */
|
|
|
|
{
|
|
|
|
/* Initially, try to read the entries into a stack-allocated buffer.
|
|
|
|
Use malloc if it does not fit. */
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
alloc_init = 4000 / sizeof (ace_t), /* >= 3 */
|
|
|
|
alloc_max = MIN (INT_MAX, SIZE_MAX / sizeof (ace_t))
|
|
|
|
};
|
|
|
|
ace_t buf[alloc_init];
|
|
|
|
size_t alloc = alloc_init;
|
|
|
|
ace_t *entries = buf;
|
|
|
|
ace_t *malloced = NULL;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
count = acl (name, ACE_GETACL, alloc, entries);
|
|
|
|
if (count < 0 && errno == ENOSPC)
|
|
|
|
{
|
|
|
|
/* Increase the size of the buffer. */
|
|
|
|
free (malloced);
|
|
|
|
if (alloc > alloc_max / 2)
|
|
|
|
{
|
|
|
|
errno = ENOMEM;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
alloc = 2 * alloc; /* <= alloc_max */
|
|
|
|
entries = malloced = (ace_t *) malloc (alloc * sizeof (ace_t));
|
|
|
|
if (entries == NULL)
|
2024-12-17 14:02:41 -08:00
|
|
|
return -1;
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (count < 0)
|
|
|
|
{
|
|
|
|
if (errno == ENOSYS || errno == EINVAL)
|
|
|
|
;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
free (malloced);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (count == 0)
|
|
|
|
;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* In the old (original Solaris 10) convention:
|
|
|
|
If there are more than 3 entries, there cannot be only the
|
|
|
|
ACE_OWNER, ACE_GROUP, ACE_OTHER entries.
|
|
|
|
In the newer Solaris 10 and Solaris 11 convention:
|
|
|
|
If there are more than 6 entries, there cannot be only the
|
|
|
|
ACE_OWNER, ACE_GROUP, ACE_EVERYONE entries, each once with
|
|
|
|
NEW_ACE_ACCESS_ALLOWED_ACE_TYPE and once with
|
|
|
|
NEW_ACE_ACCESS_DENIED_ACE_TYPE. */
|
|
|
|
if (count > 6)
|
|
|
|
{
|
|
|
|
free (malloced);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (acl_ace_nontrivial (count, entries))
|
|
|
|
{
|
|
|
|
free (malloced);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free (malloced);
|
|
|
|
}
|
2024-12-17 14:02:41 -08:00
|
|
|
# endif
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
|
|
|
return 0;
|
2024-12-17 14:02:41 -08:00
|
|
|
# endif
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# elif HAVE_GETACL /* HP-UX */
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
struct acl_entry entries[NACLENTRIES];
|
|
|
|
int count;
|
|
|
|
|
|
|
|
count = getacl (name, NACLENTRIES, entries);
|
|
|
|
|
|
|
|
if (count < 0)
|
|
|
|
{
|
|
|
|
/* ENOSYS is seen on newer HP-UX versions.
|
|
|
|
EOPNOTSUPP is typically seen on NFS mounts.
|
|
|
|
ENOTSUP was seen on Quantum StorNext file systems (cvfs). */
|
|
|
|
if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
|
|
|
|
;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else if (count == 0)
|
|
|
|
return 0;
|
|
|
|
else /* count > 0 */
|
|
|
|
{
|
|
|
|
if (count > NACLENTRIES)
|
|
|
|
/* If NACLENTRIES cannot be trusted, use dynamic memory
|
|
|
|
allocation. */
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
/* If there are more than 3 entries, there cannot be only the
|
|
|
|
(uid,%), (%,gid), (%,%) entries. */
|
|
|
|
if (count > 3)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
{
|
|
|
|
struct stat statbuf;
|
|
|
|
|
Update from Gnulib
Make the following changes by hand, and run 'admin/merge-gnulib'.
* .gitignore: Add lib/malloc/*.gl.h.
* admin/merge-gnulib: Copy lib/af_alg.h and lib/save-cwd.h
directly from Gnulib, without worrying about Gnulib modules,
as these files are special cases.
(AVOIDED_MODULES): Remove malloc-posix.
* lib/malloc.c, lib/realloc.c, m4/malloc.m4, m4/realloc.m4:
* m4/year2038.m4: New files, copied from Gnulib.
* lib/malloca.c, lib/malloca.h:
* m4/close-stream.m4, m4/glibc21.m4, m4/malloca.m4:
Remove. These are either no longer present in Gnulib, or are no
longer needed by modules that Emacs uses.
* oldXMenu/AddPane.c, oldXmenu/Addsel.c: Include XmenuInt.h first;
needed for new Gnulib.
* src/xmenu.c: Call emacs_abort, not abort.
2021-10-04 12:11:39 -07:00
|
|
|
if (stat (name, &statbuf) == -1 && errno != EOVERFLOW)
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
return acl_nontrivial (count, entries);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# if HAVE_ACLV_H /* HP-UX >= 11.11 */
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
struct acl entries[NACLVENTRIES];
|
|
|
|
int count;
|
|
|
|
|
|
|
|
count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries);
|
|
|
|
|
|
|
|
if (count < 0)
|
|
|
|
{
|
|
|
|
/* EOPNOTSUPP is seen on NFS in HP-UX 11.11, 11.23.
|
|
|
|
EINVAL is seen on NFS in HP-UX 11.31. */
|
|
|
|
if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
|
|
|
|
;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else if (count == 0)
|
|
|
|
return 0;
|
|
|
|
else /* count > 0 */
|
|
|
|
{
|
|
|
|
if (count > NACLVENTRIES)
|
|
|
|
/* If NACLVENTRIES cannot be trusted, use dynamic memory
|
|
|
|
allocation. */
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
/* If there are more than 4 entries, there cannot be only the
|
|
|
|
four base ACL entries. */
|
|
|
|
if (count > 4)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return aclv_nontrivial (count, entries);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# endif
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# elif HAVE_ACLX_GET && defined ACL_AIX_WIP /* AIX */
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
|
|
|
acl_type_t type;
|
|
|
|
char aclbuf[1024];
|
|
|
|
void *acl = aclbuf;
|
|
|
|
size_t aclsize = sizeof (aclbuf);
|
|
|
|
mode_t mode;
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
/* The docs say that type being 0 is equivalent to ACL_ANY, but it
|
|
|
|
is not true, in AIX 5.3. */
|
|
|
|
type.u64 = ACL_ANY;
|
|
|
|
if (aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) >= 0)
|
|
|
|
break;
|
|
|
|
if (errno == ENOSYS)
|
|
|
|
return 0;
|
|
|
|
if (errno != ENOSPC)
|
|
|
|
{
|
|
|
|
if (acl != aclbuf)
|
Update from Gnulib
Make the following changes by hand, and run 'admin/merge-gnulib'.
* .gitignore: Add lib/malloc/*.gl.h.
* admin/merge-gnulib: Copy lib/af_alg.h and lib/save-cwd.h
directly from Gnulib, without worrying about Gnulib modules,
as these files are special cases.
(AVOIDED_MODULES): Remove malloc-posix.
* lib/malloc.c, lib/realloc.c, m4/malloc.m4, m4/realloc.m4:
* m4/year2038.m4: New files, copied from Gnulib.
* lib/malloca.c, lib/malloca.h:
* m4/close-stream.m4, m4/glibc21.m4, m4/malloca.m4:
Remove. These are either no longer present in Gnulib, or are no
longer needed by modules that Emacs uses.
* oldXMenu/AddPane.c, oldXmenu/Addsel.c: Include XmenuInt.h first;
needed for new Gnulib.
* src/xmenu.c: Call emacs_abort, not abort.
2021-10-04 12:11:39 -07:00
|
|
|
free (acl);
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
aclsize = 2 * aclsize;
|
|
|
|
if (acl != aclbuf)
|
|
|
|
free (acl);
|
|
|
|
acl = malloc (aclsize);
|
|
|
|
if (acl == NULL)
|
2024-12-17 14:02:41 -08:00
|
|
|
return -1;
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (type.u64 == ACL_AIXC)
|
|
|
|
{
|
|
|
|
int result = acl_nontrivial ((struct acl *) acl);
|
|
|
|
if (acl != aclbuf)
|
|
|
|
free (acl);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
else if (type.u64 == ACL_NFS4)
|
|
|
|
{
|
|
|
|
int result = acl_nfs4_nontrivial ((nfs4_acl_int_t *) acl);
|
|
|
|
if (acl != aclbuf)
|
|
|
|
free (acl);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* A newer type of ACL has been introduced in the system.
|
|
|
|
We should better support it. */
|
|
|
|
if (acl != aclbuf)
|
|
|
|
free (acl);
|
|
|
|
errno = EINVAL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# elif HAVE_STATACL /* older AIX */
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
|
|
|
union { struct acl a; char room[4096]; } u;
|
|
|
|
|
|
|
|
if (statacl ((char *) name, STX_NORMAL, &u.a, sizeof (u)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return acl_nontrivial (&u.a);
|
|
|
|
|
2024-12-17 14:02:41 -08:00
|
|
|
# elif HAVE_ACLSORT /* NonStop Kernel */
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
struct acl entries[NACLENTRIES];
|
|
|
|
int count;
|
|
|
|
|
|
|
|
count = acl ((char *) name, ACL_GET, NACLENTRIES, entries);
|
|
|
|
|
|
|
|
if (count < 0)
|
|
|
|
{
|
|
|
|
if (errno == ENOSYS || errno == ENOTSUP)
|
|
|
|
;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else if (count == 0)
|
|
|
|
return 0;
|
|
|
|
else /* count > 0 */
|
|
|
|
{
|
|
|
|
if (count > NACLENTRIES)
|
|
|
|
/* If NACLENTRIES cannot be trusted, use dynamic memory
|
|
|
|
allocation. */
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
/* If there are more than 4 entries, there cannot be only the
|
|
|
|
four base ACL entries. */
|
|
|
|
if (count > 4)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return acl_nontrivial (count, entries);
|
|
|
|
}
|
|
|
|
}
|
2024-12-17 14:02:41 -08:00
|
|
|
# endif
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
}
|
2024-12-17 14:02:41 -08:00
|
|
|
# endif
|
|
|
|
# endif
|
Redo emacsclient socket symlink-attack checking
* admin/merge-gnulib (GNULIB_MODULES): Add file-has-acl.
* lib/file-has-acl.c: New file, copied from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib-src/emacsclient.c: Include acl.h, for file_has_acl.
(O_PATH): Default to O_SEARCH, which is good enough here.
(union local_sockaddr): New type.
(socket_status): Remove, replacing with ...
(connect_socket): New function. All callers changed.
This function checks for ownership and permissions issues with the
parent directory of the socket file, instead of checking the
owner of the socket (which does not help security).
(socknamesize): Move to file scope.
(local_sockname): New arg S. No need to pass socknamesize.
UID arg is now uid_t. All callers changed. Get file descriptor
of parent directory of socket, to foil some symlink attacks.
Do not follow symlinks to that directory.
(set_local_socket): Create the socket here instead of on
each attempt to connect it. Fall back from XDG_RUNTIME_DIR
to /tmp only if the former fails due to ENOENT. Adjust
permission-failure diagnostic to match changed behavior.
This addresses Bug#33847, which complained about emacsclient in a
safer XDG environment not connecting to an Emacs server running in
a less-safe enviroment outside XDG. The patch fixes a
longstanding issue with emacsclient permission checking.
It’s ineffective to look at the permission of the socket file
itself; on some platforms, these permissions are ignored anyway.
What matters are the permissions on the parent directory of the
socket file, as these are what make symlink attacks possible.
Change the permissions check accordingly, and also refuse to
follow symlinks to that parent directory. These changes make it
OK for emacsclient to fall back from XDG_RUNTIME_DIR to the
traditionally less-safe /tmp/emacsNNNN directories, since /tmp is
universally sticky nowadays.
2021-07-23 13:33:21 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2024-12-17 14:02:41 -08:00
|
|
|
|
|
|
|
/* Return 1 if NAME has a nontrivial access control list,
|
|
|
|
0 if ACLs are not supported, or if NAME has no or only a base ACL,
|
|
|
|
and -1 (setting errno) on error. Note callers can determine
|
|
|
|
if ACLs are not supported as errno is set in that case also.
|
|
|
|
SB must be set to the stat buffer of NAME,
|
|
|
|
obtained through stat() or lstat(). */
|
|
|
|
int
|
|
|
|
file_has_acl (char const *name, struct stat const *sb)
|
|
|
|
{
|
|
|
|
int flags = IFTODT (sb->st_mode);
|
|
|
|
if (!S_ISDIR (sb->st_mode))
|
|
|
|
flags |= _GL_DT_NOTDIR;
|
|
|
|
struct aclinfo ai;
|
|
|
|
int r = file_has_aclinfo (name, &ai, flags);
|
|
|
|
aclinfo_free (&ai);
|
|
|
|
return r;
|
|
|
|
}
|