diff options
author | Jeff King <peff@peff.net> | 2014-03-14 23:47:06 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-03-17 15:03:32 -0700 |
commit | 7839632167bc6ceef20f28bd046f7001493b070f (patch) | |
tree | a61644530405b976da4af5eed725a9d9930788ea /shallow.c | |
parent | 0179c945fce361c56b465e8a3f0fdf0962a816a1 (diff) | |
download | git-7839632167bc6ceef20f28bd046f7001493b070f.tar.gz |
shallow: verify shallow file after taking lockjk/shallow-update-fix
Before writing the shallow file, we stat() the existing file
to make sure it has not been updated since our operation
began. However, we do not do so under a lock, so there is a
possible race:
1. Process A takes the lock.
2. Process B calls check_shallow_file_for_update and finds
no update.
3. Process A commits the lockfile.
4. Process B takes the lock, then overwrite's process A's
changes.
We can fix this by doing our check while we hold the lock.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'shallow.c')
-rw-r--r-- | shallow.c | 4 |
1 files changed, 2 insertions, 2 deletions
@@ -263,9 +263,9 @@ void setup_alternate_shallow(struct lock_file *shallow_lock, struct strbuf sb = STRBUF_INIT; int fd; - check_shallow_file_for_update(); fd = hold_lock_file_for_update(shallow_lock, git_path("shallow"), LOCK_DIE_ON_ERROR); + check_shallow_file_for_update(); if (write_shallow_commits(&sb, 0, extra)) { if (write_in_full(fd, sb.buf, sb.len) != sb.len) die_errno("failed to write to %s", @@ -310,9 +310,9 @@ void prune_shallow(int show_only) strbuf_release(&sb); return; } - check_shallow_file_for_update(); fd = hold_lock_file_for_update(&shallow_lock, git_path("shallow"), LOCK_DIE_ON_ERROR); + check_shallow_file_for_update(); if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) { if (write_in_full(fd, sb.buf, sb.len) != sb.len) die_errno("failed to write to %s", |