Merge branch 'backport-1176-1183-1188-1191-glib-2-62' into 'glib-2-62'

Backport !1176, !1183, !1188, !1191 to `glib-2-62`

See merge request GNOME/glib!1194
This commit is contained in:
Simon McVittie 2019-10-29 14:20:56 +00:00
commit 404b07183b
8 changed files with 160 additions and 23 deletions

View File

@ -12,6 +12,7 @@ c_link_args = []
c = 'x86_64-w64-mingw32-gcc'
cpp = 'x86_64-w64-mingw32-g++'
ar = 'x86_64-w64-mingw32-ar'
objcopy = 'x86_64-w64-mingw32-objcopy'
strip = 'x86_64-w64-mingw32-strip'
pkgconfig = 'x86_64-w64-mingw32-pkg-config'
windres = 'x86_64-w64-mingw32-windres'

View File

@ -59,6 +59,7 @@ c_link_args = []
c = 'x86_64-w64-mingw32-gcc'
cpp = 'x86_64-w64-mingw32-g++'
ar = 'x86_64-w64-mingw32-ar'
objcopy = 'x86_64-w64-mingw32-objcopy'
strip = 'x86_64-w64-mingw32-strip'
pkgconfig = 'x86_64-w64-mingw32-pkg-config'
windres = 'x86_64-w64-mingw32-windres'

View File

@ -265,6 +265,35 @@ g_credentials_to_string (GCredentials *credentials)
/* ---------------------------------------------------------------------------------------------------- */
#if G_CREDENTIALS_USE_LINUX_UCRED
/*
* Check whether @native contains invalid data. If getsockopt SO_PEERCRED
* is used on a TCP socket, it succeeds but yields a credentials structure
* with pid 0, uid -1 and gid -1. Similarly, if SO_PASSCRED is used on a
* receiving Unix socket when the sending socket did not also enable
* SO_PASSCRED, it can succeed but yield a credentials structure with
* pid 0, uid /proc/sys/kernel/overflowuid and gid
* /proc/sys/kernel/overflowgid.
*/
static gboolean
linux_ucred_check_valid (struct ucred *native,
GError **error)
{
if (native->pid == 0
|| native->uid == -1
|| native->gid == -1)
{
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_DATA,
"GCredentials contains invalid data");
return FALSE;
}
return TRUE;
}
#endif
/**
* g_credentials_is_same_user:
* @credentials: A #GCredentials.
@ -294,7 +323,8 @@ g_credentials_is_same_user (GCredentials *credentials,
ret = FALSE;
#if G_CREDENTIALS_USE_LINUX_UCRED
if (credentials->native.uid == other_credentials->native.uid)
if (linux_ucred_check_valid (&credentials->native, NULL)
&& credentials->native.uid == other_credentials->native.uid)
ret = TRUE;
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
@ -453,7 +483,10 @@ g_credentials_get_unix_user (GCredentials *credentials,
g_return_val_if_fail (error == NULL || *error == NULL, -1);
#if G_CREDENTIALS_USE_LINUX_UCRED
ret = credentials->native.uid;
if (linux_ucred_check_valid (&credentials->native, error))
ret = credentials->native.uid;
else
ret = -1;
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
ret = credentials->native.cmcred_euid;
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
@ -499,7 +532,10 @@ g_credentials_get_unix_pid (GCredentials *credentials,
g_return_val_if_fail (error == NULL || *error == NULL, -1);
#if G_CREDENTIALS_USE_LINUX_UCRED
ret = credentials->native.pid;
if (linux_ucred_check_valid (&credentials->native, error))
ret = credentials->native.pid;
else
ret = -1;
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
ret = credentials->native.cmcred_pid;
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID

View File

@ -22,6 +22,77 @@
#include "gio/gcredentials.h"
#include "gio/gnetworking.h"
/*
* G_CREDENTIALS_SUPPORTED:
*
* Defined to 1 if GCredentials works.
*/
#undef G_CREDENTIALS_SUPPORTED
/*
* G_CREDENTIALS_USE_LINUX_UCRED, etc.:
*
* Defined to 1 if GCredentials uses Linux `struct ucred`, etc.
*/
#undef G_CREDENTIALS_USE_LINUX_UCRED
#undef G_CREDENTIALS_USE_FREEBSD_CMSGCRED
#undef G_CREDENTIALS_USE_NETBSD_UNPCBID
#undef G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
#undef G_CREDENTIALS_USE_SOLARIS_UCRED
/*
* G_CREDENTIALS_NATIVE_TYPE:
*
* Defined to one of G_CREDENTIALS_TYPE_LINUX_UCRED, etc.
*/
#undef G_CREDENTIALS_NATIVE_TYPE
/*
* G_CREDENTIALS_NATIVE_SIZE:
*
* Defined to the size of the %G_CREDENTIALS_NATIVE_TYPE
*/
#undef G_CREDENTIALS_NATIVE_SIZE
/*
* G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED:
*
* Defined to 1 if we have a message-passing API in which credentials
* are attached to a particular message, such as `SCM_CREDENTIALS` on Linux
* or `SCM_CREDS` on FreeBSD.
*/
#undef G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
/*
* G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED:
*
* Defined to 1 if we have a `getsockopt()`-style API in which one end of
* a socket connection can directly query the credentials of the process
* that initiated the other end, such as `getsockopt SO_PEERCRED` on Linux
* or `getpeereid()` on multiple operating systems.
*/
#undef G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED
/*
* G_CREDENTIALS_SPOOFING_SUPPORTED:
*
* Defined to 1 if privileged processes can spoof their credentials when
* using the message-passing API.
*/
#undef G_CREDENTIALS_SPOOFING_SUPPORTED
/*
* G_CREDENTIALS_PREFER_MESSAGE_PASSING:
*
* Defined to 1 if the data structure transferred by the message-passing
* API is strictly more informative than the one transferred by the
* `getsockopt()`-style API, and hence should be preferred, even for
* protocols like D-Bus that are defined in terms of the credentials of
* the (process that opened the) socket, as opposed to the credentials
* of an individual message.
*/
#undef G_CREDENTIALS_PREFER_MESSAGE_PASSING
#ifdef __linux__
#define G_CREDENTIALS_SUPPORTED 1
#define G_CREDENTIALS_USE_LINUX_UCRED 1
@ -41,6 +112,12 @@
#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct cmsgcred))
#define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
#define G_CREDENTIALS_SPOOFING_SUPPORTED 1
/* GLib doesn't implement it yet, but FreeBSD's getsockopt()-style API
* is getpeereid(), which is not as informative as struct cmsgcred -
* it does not tell us the PID. As a result, libdbus prefers to use
* SCM_CREDS, and if we implement getpeereid() in future, we should
* do the same. */
#define G_CREDENTIALS_PREFER_MESSAGE_PASSING 1
#elif defined(__NetBSD__)
#define G_CREDENTIALS_SUPPORTED 1

View File

@ -31,6 +31,7 @@
#include "gdbusutils.h"
#include "gioenumtypes.h"
#include "gcredentials.h"
#include "gcredentialsprivate.h"
#include "gdbusprivate.h"
#include "giostream.h"
#include "gdatainputstream.h"
@ -969,9 +970,31 @@ _g_dbus_auth_run_server (GDBusAuth *auth,
g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
/* first read the NUL-byte */
/* read the NUL-byte, possibly with credentials attached */
#ifdef G_OS_UNIX
if (G_IS_UNIX_CONNECTION (auth->priv->stream))
#ifndef G_CREDENTIALS_PREFER_MESSAGE_PASSING
if (G_IS_SOCKET_CONNECTION (auth->priv->stream))
{
GSocket *sock = g_socket_connection_get_socket (G_SOCKET_CONNECTION (auth->priv->stream));
local_error = NULL;
credentials = g_socket_get_credentials (sock, &local_error);
if (credentials == NULL && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
{
g_propagate_error (error, local_error);
goto out;
}
else
{
/* Clear the error indicator, so we can retry with
* g_unix_connection_receive_credentials() if necessary */
g_clear_error (&local_error);
}
}
#endif
if (credentials == NULL && G_IS_UNIX_CONNECTION (auth->priv->stream))
{
local_error = NULL;
credentials = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (auth->priv->stream),

View File

@ -577,7 +577,9 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
# Support for --add-symbol was added to LLVM objcopy in 2019
# (https://reviews.llvm.org/D58234). FIXME: This test could be enabled for
# LLVM once that support is in a stable release.
if build_machine.system() == 'linux' and cc.get_id() == 'gcc'
objcopy = find_program('objcopy', required : false)
if build_machine.system() == 'linux' and cc.get_id() == 'gcc' and objcopy.found()
test_gresource_binary = custom_target('test5.gresource',
input : 'test5.gresource.xml',
output : 'test5.gresource',
@ -616,7 +618,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
test_resources_binary2 = custom_target('test_resources2.o',
input : test_resources_binary,
output : 'test_resources2.o',
command : ['objcopy',
command : [objcopy,
'--add-symbol','_g_binary_test1_resource_data=.data:0',
'@INPUT@',
'@OUTPUT@'])

View File

@ -372,7 +372,6 @@ g_spawn_sync (const gchar *working_directory,
gint outpipe = -1;
gint errpipe = -1;
GPid pid;
fd_set fds;
gint ret;
GString *outstr = NULL;
GString *errstr = NULL;
@ -435,18 +434,16 @@ g_spawn_sync (const gchar *working_directory,
(outpipe >= 0 ||
errpipe >= 0))
{
ret = 0;
FD_ZERO (&fds);
if (outpipe >= 0)
FD_SET (outpipe, &fds);
if (errpipe >= 0)
FD_SET (errpipe, &fds);
ret = select (MAX (outpipe, errpipe) + 1,
&fds,
NULL, NULL,
NULL /* no timeout */);
/* Any negative FD in the array is ignored, so we can use a fixed length.
* We can use UNIX FDs here without worrying about Windows HANDLEs because
* the Windows implementation is entirely in gspawn-win32.c. */
GPollFD fds[] =
{
{ outpipe, G_IO_IN | G_IO_HUP | G_IO_ERR, 0 },
{ errpipe, G_IO_IN | G_IO_HUP | G_IO_ERR, 0 },
};
ret = g_poll (fds, G_N_ELEMENTS (fds), -1 /* no timeout */);
if (ret < 0)
{
@ -466,7 +463,7 @@ g_spawn_sync (const gchar *working_directory,
break;
}
if (outpipe >= 0 && FD_ISSET (outpipe, &fds))
if (outpipe >= 0 && fds[0].revents != 0)
{
switch (read_data (outstr, outpipe, error))
{
@ -485,7 +482,7 @@ g_spawn_sync (const gchar *working_directory,
break;
}
if (errpipe >= 0 && FD_ISSET (errpipe, &fds))
if (errpipe >= 0 && fds[1].revents != 0)
{
switch (read_data (errstr, errpipe, error))
{

View File

@ -83,7 +83,7 @@ typedef void (*GTestFixtureFunc) (gpointer fixture,
g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
#l1 " (len(" #m1 ")) == " #l2 " (len(" #m2 "))", \
(long double) __l1, "==", (long double) __l2, 'i'); \
else if (__l1 != 0 && memcmp (__m1, __m2, __l1) != 0) \
else if (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
"assertion failed (" #m1 " == " #m2 ")"); \
} G_STMT_END