This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
readlink() result buffer is not zero-terminated.
authorJarkko Hietaniemi <jhi@iki.fi>
Sat, 26 Jul 2014 13:42:30 +0000 (09:42 -0400)
committerJarkko Hietaniemi <jhi@iki.fi>
Mon, 28 Jul 2014 00:38:06 +0000 (20:38 -0400)
Therefore, as an extra paranoia step, zero-terminate
the readlink result buffer even before the result SV is created.

Also, readlink returns SSize_t, not int.

caretx.c
pp_sys.c

index bf5ba85..dffa445 100644 (file)
--- a/caretx.c
+++ b/caretx.c
@@ -99,7 +99,13 @@ Perl_set_caret_X(pTHX) {
         }
 #  elif defined(HAS_PROCSELFEXE)
         char buf[MAXPATHLEN];
-        int len = readlink(PROCSELFEXE_PATH, buf, sizeof(buf) - 1);
+        Ssize_t len = readlink(PROCSELFEXE_PATH, buf, sizeof(buf) - 1);
+        /* NOTE: if the length returned by readlink() is sizeof(buf) - 1,
+         * it is impossible to know whether the result was truncated. */
+
+        if (len != -1) {
+            buf[len] = '\0';
+        }
 
         /* On Playstation2 Linux V1.0 (kernel 2.2.1) readlink(/proc/self/exe)
            includes a spurious NUL which will cause $^X to fail in system
index 501146e..e01cf48 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -3671,13 +3671,17 @@ PP(pp_readlink)
     dTARGET;
     const char *tmps;
     char buf[MAXPATHLEN];
-    int len;
+    SSize_t len;
 
     TAINT;
     tmps = POPpconstx;
+    /* NOTE: if the length returned by readlink() is sizeof(buf) - 1,
+     * it is impossible to know whether the result was truncated. */
     len = readlink(tmps, buf, sizeof(buf) - 1);
     if (len < 0)
        RETPUSHUNDEF;
+    if (len != -1)
+        buf[len] = '\0';
     PUSHp(buf, len);
     RETURN;
 #else