diff options
author | Daniel Stenberg <daniel@haxx.se> | 2020-07-27 12:44:19 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2020-07-28 23:28:40 +0200 |
commit | 81b4e99b1e1a5a6ac06bcfba1bf4464085ea9688 (patch) | |
tree | 63f2ee22b9ce47890b95ae4b2f7a7130df5e1ab4 /src | |
parent | 2b6b843bb133b1a2928a82def520084c093076d0 (diff) | |
download | curl-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
Diffstat (limited to 'src')
-rw-r--r-- | src/tool_cb_wrt.c | 31 |
1 files changed, 22 insertions, 9 deletions
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)); |