]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curl: improve the existing file check with -J
authorDaniel Stenberg <daniel@haxx.se>
Mon, 27 Jul 2020 10:44:19 +0000 (12:44 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 28 Jul 2020 21:28:40 +0000 (23:28 +0200)
Previously a file that isn't user-readable but is user-writable would
not be properly avoided and would get overwritten.

Reported-by: BrumBrum on hackerone
Assisted-by: Jay Satiro
Bug: https://hackerone.com/reports/926638
Closes #5731

lib/memdebug.c
lib/memdebug.h
src/tool_cb_wrt.c

index 1c6b151493a01f311785e30d50f88338565eb700..da75c9f5db43295f795f5da6c06bf8a1b9ebd196 100644 (file)
@@ -456,6 +456,16 @@ FILE *curl_dbg_fopen(const char *file, const char *mode,
   return res;
 }
 
+FILE *curl_dbg_fdopen(int filedes, const char *mode,
+                      int line, const char *source)
+{
+  FILE *res = fdopen(filedes, mode);
+  if(source)
+    curl_dbg_log("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n",
+                 source, line, filedes, mode, (void *)res);
+  return res;
+}
+
 int curl_dbg_fclose(FILE *file, int line, const char *source)
 {
   int res;
index 7ca44262690e069a0ab89582b3d1d0b5f1e0d2b7..4edafdfb5c27b9c47d1014d1ac76565cebcef1c0 100644 (file)
@@ -8,7 +8,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -79,6 +79,9 @@ CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd,
 /* FILE functions */
 CURL_EXTERN FILE *curl_dbg_fopen(const char *file, const char *mode, int line,
                                  const char *source);
+CURL_EXTERN FILE *curl_dbg_fdopen(int filedes, const char *mode,
+                                  int line, const char *source);
+
 CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source);
 
 #ifndef MEMDEBUG_NODEFINES
index ed108911ef589af4c5ebc09a7612004f4ad62ab4..e0742630ba658a23c605087e8a73ff3cbc1167fc 100644 (file)
  ***************************************************************************/
 #include "tool_setup.h"
 
+#ifdef HAVE_FCNTL_H
+/* for open() */
+#include <fcntl.h>
+#endif
+
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
 #include "curlx.h"
@@ -37,7 +42,7 @@ bool tool_create_output_file(struct OutStruct *outs,
                              struct OperationConfig *config)
 {
   struct GlobalConfig *global;
-  FILE *file;
+  FILE *file = NULL;
   DEBUGASSERT(outs);
   DEBUGASSERT(config);
   global = config->global;
@@ -48,17 +53,25 @@ bool tool_create_output_file(struct OutStruct *outs,
 
   if(outs->is_cd_filename) {
     /* don't overwrite existing files */
-    file = fopen(outs->filename, "rb");
-    if(file) {
-      fclose(file);
-      warnf(global, "Refusing to overwrite %s: %s\n", outs->filename,
-            strerror(EEXIST));
-      return FALSE;
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+    int fd = open(outs->filename, O_CREAT | O_WRONLY | O_EXCL | O_BINARY,
+                  S_IRUSR | S_IWUSR
+#ifdef S_IRGRP
+                  | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
+#endif
+      );
+    if(fd != -1) {
+      file = fdopen(fd, "wb");
+      if(!file)
+        close(fd);
     }
   }
+  else
+    /* open file for writing */
+    file = fopen(outs->filename, "wb");
 
-  /* open file for writing */
-  file = fopen(outs->filename, "wb");
   if(!file) {
     warnf(global, "Failed to create the file %s: %s\n", outs->filename,
           strerror(errno));