Package: fakeroot
Version: 1.20.2-1
Severity: normal
Tags: patch

Dear Maintainer,

I'm raising this as requested by Clint in:

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=855662#15

Fixing that bug (fakeroot: when msgrcv is interrupted by a signal, faked
accidentally reprocesses the previous message) stopped faked from overwriting
errno, which led me to realize that my intermittent failure problem while
building several packages at once might always be due to EIDRM.  (I only had
one failure with the patched version from that bug before contriving the patch
I submit here, so I don't have a big sample size.)  That led me to realize
that faked is, by default, inventing a random number on which to base its
message queue and semaphore ids.  When it then creates the message queues and
semaphore, it doesn't check for collisions.  Here I present a patch that I
hope detects that situation and retries.  I haven't seen a failure with this
patch, but I've only been running with it since last Friday.  I was previously
seeing as little as one failure per week.  I also haven't attempted the obvious
change to fail visibly in this case, which would have given me confidence that
the diagnosis was right.  I don't know why some of build machines seem more
vulnerable than others.  I don't know why I've only seen this since they were
upgraded to Jessie.  I based the patch supplied here on:

https://anonscm.debian.org/cgit/users/clint/fakeroot.git/

I wasn't sure whether Clint was asking me to base it instead on some upstream
branch.  That was at least due to the corporate email link mangler but I'm
quite new to git and Debian packaging.  This isn't the version I'm running,
which is instead based on the Jessie version.  I'm open to persuasion for
other experiments.


-- System Information:
Debian Release: 8.7
  APT prefers stable-updates
  APT policy: (990, 'stable-updates'), (990, 'stable'), (500, 
'testing-updates'), (500, 'oldstable-updates'), (500, 'oldoldstable'), (500, 
'testing'), (500, 'stable'), (500, 'oldstable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.16.0-4-amd64 (SMP w/8 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL 
set to en_US.UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages fakeroot depends on:
ii  libc6        2.19-18+deb8u7
ii  libfakeroot  1.20.2-1

fakeroot recommends no packages.

fakeroot suggests no packages.

-- no debconf information
diff --git a/faked.c b/faked.c
index a0f92ca..d280668 100644
--- a/faked.c
+++ b/faked.c
@@ -1305,6 +1305,7 @@ int main(int argc, char **argv){
 #ifndef FAKEROOT_FAKENET
   union semun sem_union;
   int justcleanup = 0;
+  int msgflag = IPC_CREAT|0600;
 #else /* FAKEROOT_FAKENET */
   int sd, val;
   unsigned int port = 0;
@@ -1375,29 +1376,42 @@ int main(int argc, char **argv){
 
 #ifndef FAKEROOT_FAKENET
 
-  if(!msg_key) {
-    srandom(time(NULL)+getpid()*33151);
-    while(!msg_key && (msg_key!=-1))  /* values 0 and -1 are treated
-					 specially by libfake */
-      msg_key=random();
-  }
+  do {
+    if(!msg_key) {
+      msgflag |= IPC_EXCL;
+      srandom(time(NULL)+getpid()*33151);
+      while(!msg_key && (msg_key!=-1))  /* values 0 and -1 are treated
+                                           specially by libfake */
+        msg_key=random();
+    }
 
-  if(debug)
-    fprintf(stderr,"using %li as msg key\n",(long)msg_key);
+    if(debug)
+      fprintf(stderr,"using %li as msg key\n",(long)msg_key);
+
+    msg_get=msgget(msg_key,msgflag);
+    if (msg_get != -1)
+      msg_snd=msgget(msg_key+1,msgflag);
+    if (msg_snd != -1)
+      sem_id=semget(msg_key+2,1,msgflag);
+
+    if((msg_get==-1)||(msg_snd==-1)||(sem_id==-1)){
+      if (errno == EEXIST) {
+        if(debug)
+          fprintf(stderr,"using %li as msg key caused a collision, trying again\n",(long)msg_key);
+        cleanup(-1);
+        msg_key = 0;
+        continue;
+      }
+      perror("fakeroot, while creating message channels");
+      fprintf(stderr, "This may be due to a lack of SYSV IPC support.\n");
+      cleanup(-1);
+      exit(1);
+    }
+  } while(msg_key == 0);
 
-  msg_get=msgget(msg_key,IPC_CREAT|0600);
-  msg_snd=msgget(msg_key+1,IPC_CREAT|0600);
-  sem_id=semget(msg_key+2,1,IPC_CREAT|0600);
   sem_union.val=1;
   semctl (sem_id,0,SETVAL,sem_union);
 
-  if((msg_get==-1)||(msg_snd==-1)||(sem_id==-1)){
-    perror("fakeroot, while creating message channels");
-    fprintf(stderr, "This may be due to a lack of SYSV IPC support.\n");
-    cleanup(-1);
-    exit(1);
-  }
-
   if(debug)
     fprintf(stderr,"msg_key=%li\n",(long)msg_key);
 

Reply via email to