Package: eatmydata
Version: 26-2
Severity: normal
Tags: patch

Hi,

first, thank you very much for eatmydata! I'm using it on the powerpcspe
buildds, running builds in schroots (with "command-prefix").

However, I encountered some mysterious errors with eatmydata. For example,
when installing gnunet-server (as a build dependency of some source package),
the following error happens:

Fatal: can't open /dev/urandom: Bad address

In fact, you can easily reproduce this (also on other arches like amd64) with:

# eatmydata gnunet-arm
Fatal: can't open /dev/urandom: Bad address
Aborted
#

This is due to the assumption that normally, eatmydata_init() is called as a
constructor before main():

void __attribute__ ((constructor)) eatmydata_init(void)

However, some programs like gnunet-arm for some reason don't run ctors of our
SO's ctor eatmydata_init(). While it might be a good idea to fix this in gnunet
also, I propose a workaround in eatmydata to even run programs like gnunet-arm
with this issue more transparently (as run without eatmydata).

Consider the attached patch: It fixes the issue by detecting directly if we
are just in the process of eatmydata_init() already. This is already done by
checking for !libc_open but this also happens in the above case:
eatmydata_init() not been called previously, leading to the assumption in
open() that we are catching the case of just initing and coming back from
dlsym() to open(). But here, this branch catches the wrong state, because
in gnunet-arm, eatmydata_init() wasn't called at all.

So the patch issues EFAULT only in case of actually just eatmydata_init()ing.
Otherwise, eatmydata_is_hungry() and therefore eatmydata_init() can be called
just as usual.

FWIW, the case of eatmydata_init() not being run as a ctor is already handled
by running it in eatmydata_is_hungry() but this doesn't work in case of open()
being called before one of the other triggering functions.

Note that gnunet-server is just an example. I encountered the same issue in
some other occasions also.

Thanks in advance,

Roland


-- System Information:
Debian Release: 7.0
  APT prefers unreleased
  APT policy: (500, 'unreleased'), (500, 'unstable')
Architecture: powerpcspe (ppc)

Kernel: Linux 3.8.0 (SMP w/2 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8) (ignored: LC_ALL 
set to en_GB.UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages eatmydata depends on:
ii  libc6  2.13-37+powerpcspe1

eatmydata recommends no packages.

eatmydata suggests no packages.

-- no debconf information
--- libeatmydata-26.orig/eatmydata.c
+++ libeatmydata-26/eatmydata.c
@@ -44,13 +44,17 @@ static int (*libc_msync)(void*, size_t,
         if (!libc_##name || dlerror())				\
                 _exit(1);
 
+static int initing = 0;
+
 void __attribute__ ((constructor)) eatmydata_init(void)
 {
+	initing = 1;
 	ASSIGN_DLSYM_OR_DIE(open);
 	ASSIGN_DLSYM_OR_DIE(fsync);
 	ASSIGN_DLSYM_OR_DIE(sync);
 	ASSIGN_DLSYM_OR_DIE(fdatasync);
 	ASSIGN_DLSYM_OR_DIE(msync);
+	initing = 0;
 }
 
 int eatmydata_is_hungry(void)
@@ -109,7 +113,7 @@ int open(const char* pathname, int flags
 
 	/* In pthread environments the dlsym() may call our open(). */
 	/* We simply ignore it because libc is already loaded       */
-	if (!libc_open) {
+	if (initing) {
 		errno = EFAULT;
 		return -1;
 	}

Reply via email to