Source: ocamlnet
Version: 4.1.2-1
Severity: important
Tags: upstream patch
User: debian-h...@lists.debian.org
Usertags: hurd

Hello,

ocamlnet currently FTBFS on hurd-i386 due to an inconditional usage of
PATH_MAX, which is not defined there since there is no such arbitrary
limit. The attached patch avoids using by by just reading the symlink
length, and adjusting the size in case the symlink length increased in
between through really bad concurrency luck.

I'm afraid I couldn't easily find the upstream URL for posting such
report, both the sourceforge tracker and the ocamlnet3 tracker seemed
outdated, and there is no link to a ocamlnet4 tracker.

Samuel

-- System Information:
Debian Release: stretch/sid
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable-debug'), (500, 
'testing-debug'), (500, 'buildd-unstable'), (500, 'unstable'), (500, 'stable'), 
(500, 'oldstable'), (1, 'experimental-debug'), (1, 'buildd-experimental'), (1, 
'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

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

-- 
Samuel
  bien sûr que ça convient mieux à tout le monde
  enfin, dans la mesure où tout le monde c'est comme moi
 -+- le consensus, c'est facile -+-
--- ./src/netsys/netsys_c.c.original    2016-11-11 23:14:29.000000000 +0000
+++ ./src/netsys/netsys_c.c     2016-11-11 23:25:42.000000000 +0000
@@ -607,12 +607,32 @@
 CAMLprim value netsys_readlinkat(value dirfd, value path)
 {
 #ifdef HAVE_AT
-  char buffer[PATH_MAX];
-  int len;
-  len = readlinkat(Int_val(dirfd), String_val(path), buffer, sizeof(buffer)-1);
-  if (len == -1) uerror("readlinkat", path);
+  char *buffer;
+  int buflen, len;
+  struct stat sb;
+  value ret;
+  if (lstat(String_val(path), &sb) == -1) {
+    buflen = sb.st_size + 1;
+  }
+  else {
+    buflen = 64;
+  }
+  while (1) {
+    buffer = malloc(buflen);
+    len = readlinkat(Int_val(dirfd), String_val(path), buffer, buflen-1);
+    if (len == -1) {
+      free(buffer);
+      uerror("readlinkat", path);
+    }
+    if (len < buflen-1)
+      break;
+    free(buffer);
+    buflen *= 2;
+  }
   buffer[len] = '\0';
-  return copy_string(buffer);
+  ret = copy_string(buffer);
+  free(buffer);
+  return ret;
 #else
     invalid_argument("Netsys_posix.readlinkat not available");
 #endif

Reply via email to