From 763c51780c0830983ee75d66d516d65911b0e96a Mon Sep 17 00:00:00 2001
From: Dan Fandrich <dan@coneharvesters.com>
Date: Sun, 13 Jul 2014 00:18:40 +0200
Subject: [PATCH] netrc: fixed thread safety problem by using getpwuid_r if
 available

The old way using getpwuid could cause problems in programs that enable
reading from netrc files simultaneously in multiple threads.

Reported-by: David Woodhouse
---
 RELEASE-NOTES |  1 +
 configure.ac  |  1 +
 lib/netrc.c   | 14 +++++++++++++-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 307568825f..5d7936b6ed 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -58,6 +58,7 @@ This release includes the following bugfixes:
  o build: Fixed overridden compiler PDB settings in VC7 to VC12
  o ntlm_wb: Fixed buffer size not being large enough for NTLMv2 sessions [11]
  o netrc: don't abort if home dir cannot be found
+ o netrc: fixed thread safety problem by using getpwuid_r if available
 
 This release includes the following known bugs:
 
diff --git a/configure.ac b/configure.ac
index a06f0fd1fb..e8d322a02a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3033,6 +3033,7 @@ AC_CHECK_FUNCS([fork \
   getppid \
   getprotobyname \
   getpwuid \
+  getpwuid_r \
   getrlimit \
   gettimeofday \
   if_nametoindex \
diff --git a/lib/netrc.c b/lib/netrc.c
index a7a7101595..7435d94c48 100644
--- a/lib/netrc.c
+++ b/lib/netrc.c
@@ -76,7 +76,19 @@ int Curl_parsenetrc(const char *host,
     char *home = curl_getenv("HOME"); /* portable environment reader */
     if(home) {
       home_alloc = TRUE;
-#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+    }
+    else {
+      struct passwd pw, *pw_res;
+      char pwbuf[1024];
+      if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
+         && pw_res) {
+        home = strdup(pw.pw_dir);
+        if(!home)
+          return CURLE_OUT_OF_MEMORY;
+        home_alloc = TRUE;
+      }
+#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
     }
     else {
       struct passwd *pw;
-- 
GitLab