From 81b4e99b1e1a5a6ac06bcfba1bf4464085ea9688 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 27 Jul 2020 12:44:19 +0200 Subject: [PATCH] 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 --- lib/memdebug.c | 10 ++++++++++ lib/memdebug.h | 5 ++++- src/tool_cb_wrt.c | 31 ++++++++++++++++++++++--------- 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, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , 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 +#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));