summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2020-07-27 12:44:19 +0200
committerDaniel Stenberg <daniel@haxx.se>2020-07-28 23:28:40 +0200
commit81b4e99b1e1a5a6ac06bcfba1bf4464085ea9688 (patch)
tree63f2ee22b9ce47890b95ae4b2f7a7130df5e1ab4
parent2b6b843bb133b1a2928a82def520084c093076d0 (diff)
downloadcurl-81b4e99b1e1a5a6ac06bcfba1bf4464085ea9688.tar.gz
curl: improve the existing file check with -J
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
-rw-r--r--lib/memdebug.c10
-rw-r--r--lib/memdebug.h5
-rw-r--r--src/tool_cb_wrt.c31
3 files changed, 36 insertions, 10 deletions
diff --git a/lib/memdebug.c b/lib/memdebug.c
index 1c6b15149..da75c9f5d 100644
--- a/lib/memdebug.c
+++ b/lib/memdebug.c
@@ -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;
diff --git a/lib/memdebug.h b/lib/memdebug.h
index 7ca442626..4edafdfb5 100644
--- a/lib/memdebug.h
+++ b/lib/memdebug.h
@@ -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
diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c
index ed108911e..e0742630b 100644
--- a/src/tool_cb_wrt.c
+++ b/src/tool_cb_wrt.c
@@ -21,6 +21,11 @@
***************************************************************************/
#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));