Re: glib2.0 test gio/tests/socket fails, BUG in libc0.3?
On Fri, 2013-09-13 at 00:01 +0200, Svante Signell wrote:
> Hello,
>
> Running the test suite for glib2.0 one test: gio/tests/socket,
> sub-test: /socket/unix-connection-ancillary-data fails for unknown
> reasons The ancillary data sent is using SCM_RIGHTS (not SCM_CREDS). The
> latest libc-2.17-92, hurd-20130727 and glib2.0-2.36.4-1, are installed.
>
> The test errors out with err = EKERN_INVALID_ADDRESS after calling
> sendmsg.c:
> Is there any reason for this error message to fail that test? (setting
> err to zero and rebuilding libc.so makes this, and other, test pass)
>
> ./lt-socket
> /socket/unix-connection-ancillary-data: **
I've now built patched versions of dbus and glib2.0, see attachments:
the first for dbus and the other two for glib2.0.
(The write_credentials_byte() and _dbus_read_credentials_socket() code
are fixes to disable dbus to error out. The domain is not available in
these functions. Comments welcomed).
With them the test above fails with stock libc-2.17-92.
Additionally, the test before fails:
/socket/ipv6_sync: **
GLib-GIO:ERROR:/home/srs/DEBs/glib2.0/glib2.0-2.36.4/./gio/tests/socket.c:92:create_server: assertion failed (error == NULL): Unable to create socket: Address family not supported by protocol (g-io-error-quark, 0)
Aborted
This is strange, since the arguments to socket are (26,1,0), i.e.
socket(AF_INET6, SOCK_STREAM, 0). The test works om my locally modified
libc0.3 though?
> I'm attaching the built test program, not stripped, it's only 25k.
I had some problems running that program if copied to another computer,
since it was linked to the currently built glib2.0 libraries.
chrpath -r /usr/lib/i386-gnu ./lt-socket; ldd ./lt-socket
fixed that.
--- a/dbus/dbus-sysdeps-unix.c 2013-09-08 12:01:26.000000000 +0200
+++ b/dbus/dbus-sysdeps-unix.c 2013-09-12 14:04:27.000000000 +0200
@@ -139,7 +139,7 @@ _dbus_open_socket (int *fd_
cloexec_done = *fd_p >= 0;
/* Check if kernel seems to be too old to know SOCK_CLOEXEC */
- if (*fd_p < 0 && errno == EINVAL)
+ if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
#endif
{
*fd_p = socket (domain, type, protocol);
@@ -887,16 +887,21 @@ _dbus_connect_exec (const char *path
{
int fds[2];
pid_t pid;
+ int retval;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
_dbus_verbose ("connecting to process %s\n", path);
- if (socketpair (AF_UNIX, SOCK_STREAM
#ifdef SOCK_CLOEXEC
- |SOCK_CLOEXEC
+ retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
#endif
- , 0, fds) < 0)
+ if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
+ {
+ retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
+ }
+
+ if (retval < 0)
{
dbus_set_error (error,
_dbus_error_from_errno (errno),
@@ -1617,6 +1622,12 @@ write_credentials_byte (int
if (bytes_written < 0 && errno == EINTR)
goto again;
+ /* sendmsg() only accepts domain == PF_UNIX*/
+#if defined(HAVE_CMSGCRED)
+ if (bytes_written < 0 && errno == EINVAL)
+ bytes_written = send (server_fd, buf, 1, 0);
+#endif
+
if (bytes_written < 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
@@ -1753,8 +1764,12 @@ _dbus_read_credentials_socket (int
}
#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
- if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
- || cmsg.hdr.cmsg_type != SCM_CREDS)
+ /* Special case for a zero credentials byte written */
+ if (bytes_read == 1 && buf == '\0')
+ {
+ }
+ else if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
+ || cmsg.hdr.cmsg_type != SCM_CREDS)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Message from recvmsg() was not SCM_CREDS");
@@ -3055,7 +3070,7 @@ _dbus_full_duplex_pipe (int *fd1,
retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
cloexec_done = retval >= 0;
- if (retval < 0 && errno == EINVAL)
+ if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
#endif
{
retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
--- a/gio/gcredentials.c
+++ b/gio/gcredentials.c
@@ -79,7 +79,7 @@
#ifdef __linux__
struct ucred native;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
struct cmsgcred native;
#elif defined(__OpenBSD__)
struct sockpeercred native;
@@ -131,7 +131,7 @@
credentials->native.pid = getpid ();
credentials->native.uid = geteuid ();
credentials->native.gid = getegid ();
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
memset (&credentials->native, 0, sizeof (struct cmsgcred));
credentials->native.cmcred_pid = getpid ();
credentials->native.cmcred_euid = geteuid ();
@@ -193,7 +193,7 @@
g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
if (ret->str[ret->len - 1] == ',')
ret->str[ret->len - 1] = '\0';
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
g_string_append (ret, "freebsd-cmsgcred:");
if (credentials->native.cmcred_pid != -1)
g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_pid);
@@ -251,7 +251,7 @@
#ifdef __linux__
if (credentials->native.uid == other_credentials->native.uid)
ret = TRUE;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
ret = TRUE;
#elif defined(__OpenBSD__)
@@ -307,7 +307,7 @@
{
ret = &credentials->native;
}
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
if (native_type != G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED)
{
g_warning ("g_credentials_get_native: Trying to get credentials of type %d but only "
@@ -368,7 +368,7 @@
{
memcpy (&credentials->native, native, sizeof (struct ucred));
}
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
if (native_type != G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED)
{
g_warning ("g_credentials_set_native: Trying to set credentials of type %d "
@@ -426,7 +426,7 @@
#ifdef __linux__
ret = credentials->native.uid;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
ret = credentials->native.cmcred_euid;
#elif defined(__OpenBSD__)
ret = credentials->native.uid;
@@ -468,7 +468,7 @@
#ifdef __linux__
ret = credentials->native.pid;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
ret = credentials->native.cmcred_pid;
#elif defined(__OpenBSD__)
ret = credentials->native.pid;
@@ -515,7 +515,7 @@
#ifdef __linux__
credentials->native.uid = uid;
ret = TRUE;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
credentials->native.cmcred_euid = uid;
ret = TRUE;
#elif defined(__OpenBSD__)
--- a/gio/gunixcredentialsmessage.c
+++ b/gio/gunixcredentialsmessage.c
@@ -38,7 +38,7 @@
/* ---------------------------------------------------------------------------------------------------- */
#ifdef __linux__
#define G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
#define G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
#else
/* TODO: please add support for your UNIX flavor */
@@ -75,7 +75,7 @@
{
#ifdef __linux__
return sizeof (struct ucred);
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
return sizeof (struct cmsgcred);
#else
return 0;
@@ -87,7 +87,7 @@
{
#ifdef __linux__
return SOL_SOCKET;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
return SOL_SOCKET;
#else
return 0;
@@ -99,7 +99,7 @@
{
#ifdef __linux__
return SCM_CREDENTIALS;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
return SCM_CREDS;
#else
return 0;
@@ -149,7 +149,7 @@
out:
;
}
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
{
GCredentials *credentials;
struct cmsgcred *cred;
@@ -191,7 +191,7 @@
g_credentials_get_native (message->priv->credentials,
G_CREDENTIALS_TYPE_LINUX_UCRED),
sizeof (struct ucred));
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
memcpy (data,
g_credentials_get_native (message->priv->credentials,
G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED),
--- a/gio/tests/credentials.c
+++ b/gio/tests/credentials.c
@@ -30,6 +30,7 @@
# if (defined(__linux__) || \
defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || \
+ defined(__GNU__) || \
defined(__OpenBSD__))
# define SHOULD_HAVE_CREDENTIALS
# endif
@@ -91,7 +92,7 @@
g_assert_cmpuint (native->uid, ==, geteuid ());
g_assert_cmpuint (native->pid, ==, getpid ());
}
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)|| defined(__GNU__)
{
struct cmsgcred *native = g_credentials_get_native (creds,
G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED);
--- a/gio/tests/gdbus-peer.c
+++ b/gio/tests/gdbus-peer.c
@@ -47,6 +47,7 @@
#if (defined(__linux__) || \
defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || \
+ defined(__GNU__) || \
defined(__OpenBSD__))
#define SHOULD_HAVE_CREDENTIALS_PASSING
#endif
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -499,7 +499,7 @@
return fd;
/* It's possible that libc has SOCK_CLOEXEC but the kernel does not */
- if (fd < 0 && errno == EINVAL)
+ if (fd < 0 && (errno == EINVAL || errno == EPROTOTYPE))
#endif
fd = socket (domain, type, protocol);
Reply to: