From 152da3dfcf2c16d7c240a0dbdcb8a3ae1d332d81 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 25 Sep 2005 16:28:51 -0700 Subject: Plug a small race in update-ref.c. Signed-off-by: Junio C Hamano diff --git a/update-ref.c b/update-ref.c index 127ef99..01496f6 100644 --- a/update-ref.c +++ b/update-ref.c @@ -1,5 +1,6 @@ #include "cache.h" #include "refs.h" +#include static const char git_update_ref_usage[] = "git-update-ref []"; @@ -50,6 +51,19 @@ const char *resolve_ref(const char *path, unsigned char *sha1) return path; } +static int re_verify(const char *path, unsigned char *oldsha1, unsigned char *currsha1) +{ + char buf[40]; + int fd = open(path, O_RDONLY), nr; + if (fd < 0) + return -1; + nr = read(fd, buf, 40); + close(fd); + if (nr != 40 || get_sha1_hex(buf, currsha1) < 0) + return -1; + return memcmp(oldsha1, currsha1, 20) ? -1 : 0; +} + int main(int argc, char **argv) { char *hex; @@ -97,12 +111,16 @@ int main(int argc, char **argv) } /* - * FIXME! - * - * We should re-read the old ref here, and re-verify that it - * matches "oldsha1". Otherwise there's a small race. + * Re-read the ref after getting the lock to verify */ + if (oldval && re_verify(path, oldsha1, currsha1) < 0) { + unlink(lockpath); + die("Ref lock failed"); + } + /* + * Finally, replace the old ref with the new one + */ if (rename(lockpath, path) < 0) { unlink(lockpath); die("Unable to create %s", path); -- cgit v0.10.2-6-g49f6