diff --git a/net/cgi-io/Makefile b/net/cgi-io/Makefile index c8e4164ef..32498bc8e 100644 --- a/net/cgi-io/Makefile +++ b/net/cgi-io/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=cgi-io -PKG_RELEASE:=17 +PKG_RELEASE:=18 PKG_LICENSE:=GPL-2.0-or-later diff --git a/net/cgi-io/src/main.c b/net/cgi-io/src/main.c index 6e9112c0f..d45c67b85 100644 --- a/net/cgi-io/src/main.c +++ b/net/cgi-io/src/main.c @@ -436,32 +436,44 @@ filecopy(void) return response(false, "No file data received"); } - if (lseek(st.tempfd, 0, SEEK_SET) < 0) + snprintf(buf, sizeof(buf), "/proc/self/fd/%d", st.tempfd); + + if (unlink(st.filename) < 0 && errno != ENOENT) { close(st.tempfd); - return response(false, "Failed to rewind temp file"); + return response(false, "Failed to unlink existing file"); } - st.filefd = open(st.filename, O_CREAT | O_TRUNC | O_WRONLY, 0600); - - if (st.filefd < 0) + if (linkat(AT_FDCWD, buf, AT_FDCWD, st.filename, AT_SYMLINK_FOLLOW) < 0) { - close(st.tempfd); - return response(false, "Failed to open target file"); - } - - while ((len = read(st.tempfd, buf, sizeof(buf))) > 0) - { - if (write(st.filefd, buf, len) != len) + if (lseek(st.tempfd, 0, SEEK_SET) < 0) { close(st.tempfd); - close(st.filefd); - return response(false, "I/O failure while writing target file"); + return response(false, "Failed to rewind temp file"); } + + st.filefd = open(st.filename, O_CREAT | O_TRUNC | O_WRONLY, 0600); + + if (st.filefd < 0) + { + close(st.tempfd); + return response(false, "Failed to open target file"); + } + + while ((len = read(st.tempfd, buf, sizeof(buf))) > 0) + { + if (write(st.filefd, buf, len) != len) + { + close(st.tempfd); + close(st.filefd); + return response(false, "I/O failure while writing target file"); + } + } + + close(st.filefd); } close(st.tempfd); - close(st.filefd); if (chmod(st.filename, st.filemode)) return response(false, "Failed to chmod target file"); @@ -510,8 +522,6 @@ header_value(multipart_parser *p, const char *data, size_t len) static int data_begin_cb(multipart_parser *p) { - char tmpname[24] = "/tmp/luci-upload.XXXXXX"; - if (st.parttype == PART_FILEDATA) { if (!st.sessionid) @@ -523,12 +533,10 @@ data_begin_cb(multipart_parser *p) if (!session_access(st.sessionid, "file", st.filename, "write")) return response(false, "Access to path denied by ACL"); - st.tempfd = mkstemp(tmpname); + st.tempfd = open("/tmp", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); if (st.tempfd < 0) return response(false, "Failed to create temporary file"); - - unlink(tmpname); } return 0;