From 9e5736ebbd8511e58f167f95bd6740db4a8a0553 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Tue, 5 Dec 2017 14:33:29 +0000
Subject: [PATCH] resolve_link: Stop resolving if out of space

If PATH_MAX bytes aren't enough for anyone, smashing the stack or heap
is a poor way to report it.

Signed-off-by: Simon McVittie <smcv@collabora.com>
---
 utils/utils.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/utils/utils.c b/utils/utils.c
index f6da457c9..7a5acc1db 100644
--- a/utils/utils.c
+++ b/utils/utils.c
@@ -214,6 +214,13 @@ int resolve_link(const char *prefix, char *path, char *dir)
 
     rv = readlinkat( dfd, path, rl, sizeof(rl) );
 
+    if( rv == sizeof(rl) )
+    {
+        // Either rl was truncated, or there is no longer space for '\0'
+        rv = -1;
+        goto out;
+    }
+
     if( rv >= 0 )
     {
         rl[ rv ] = '\0';
@@ -222,6 +229,12 @@ int resolve_link(const char *prefix, char *path, char *dir)
         {
             const int pl = strlen( prefix );
 
+            if( pl + rv > PATH_MAX )
+            {
+                rv = -1;
+                goto out;
+            }
+
             safe_strncpy( path, prefix, PATH_MAX );
             safe_strncpy( path + pl, rl, PATH_MAX - pl );
         }
@@ -229,12 +242,19 @@ int resolve_link(const char *prefix, char *path, char *dir)
         {
             const int pl = strlen( dir );
 
+            if( pl + rv + 1 > PATH_MAX )
+            {
+                rv = -1;
+                goto out;
+            }
+
             safe_strncpy( path, dir, PATH_MAX );
             path[ pl ] = '/';
             safe_strncpy( path + pl + 1, rl, PATH_MAX - pl - 1 );
         }
     }
 
+out:
     close( dfd );
 
     return rv != -1;
-- 
GitLab