From 114b71b75182dbff4c2bb76335665d6376934bb3 Mon Sep 17 00:00:00 2001 From: ed Date: Wed, 16 Oct 2024 15:32:58 +0000 Subject: [PATCH] up2k: fix filesystem toctou previously and currently, as an upload completes, its "done" flag is not set until all the data has been flushed to disk however, the list of missing chunks becomes empty before the flush, and that list was incorrectly used to determine completion state in some dedup-related logic as a result, duplicate uploads could initially fail, and would succeed after the client automatically retried a handful of times --- copyparty/up2k.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/copyparty/up2k.py b/copyparty/up2k.py index 68c89e49..78c32fb2 100644 --- a/copyparty/up2k.py +++ b/copyparty/up2k.py @@ -2966,7 +2966,7 @@ class Up2k(object): path = djoin(rj["ptop"], rj["prel"], fn) try: st = bos.stat(path) - if st.st_size > 0 or not rj["need"]: + if st.st_size > 0 or "done" in rj: # upload completed or both present break except: @@ -2980,7 +2980,7 @@ class Up2k(object): inc_ap = djoin(cj["ptop"], cj["prel"], cj["name"]) orig_ap = djoin(rj["ptop"], rj["prel"], rj["name"]) - if self.args.nw or n4g or not st: + if self.args.nw or n4g or not st or "done" not in rj: pass elif st.st_size != rj["size"]: @@ -3012,7 +3012,7 @@ class Up2k(object): dst = djoin(cj["ptop"], cj["prel"], cj["name"]) vsrc = djoin(job["vtop"], job["prel"], job["name"]) vsrc = vsrc.replace("\\", "/") # just for prints anyways - if job["need"]: + if "done" not in job: self.log("unfinished:\n {0}\n {1}".format(src, dst)) err = "partial upload exists at a different location; please resume uploading here instead:\n" err += "/" + quotep(vsrc) + " "