Commit 40ffa07f by Carlos Martín Nieto

sortedcache: check file size after opening the file

Checking the size before we open the file descriptor can lead to the
file being replaced from under us when renames aren't quite atomic, so
we can end up reading too little of the file, leading to us thinking the
file is corrupted.
parent 26416f6d
...@@ -200,6 +200,7 @@ void git_sortedcache_runlock(git_sortedcache *sc) ...@@ -200,6 +200,7 @@ void git_sortedcache_runlock(git_sortedcache *sc)
int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf) int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf)
{ {
int error, fd; int error, fd;
struct stat st;
if ((error = git_sortedcache_wlock(sc)) < 0) if ((error = git_sortedcache_wlock(sc)) < 0)
return error; return error;
...@@ -207,19 +208,26 @@ int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf) ...@@ -207,19 +208,26 @@ int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf)
if ((error = git_futils_filestamp_check(&sc->stamp, sc->path)) <= 0) if ((error = git_futils_filestamp_check(&sc->stamp, sc->path)) <= 0)
goto unlock; goto unlock;
if (!git__is_sizet(sc->stamp.size)) { if ((fd = git_futils_open_ro(sc->path)) < 0) {
giterr_set(GITERR_INVALID, "Unable to load file larger than size_t"); error = fd;
goto unlock;
}
if (p_fstat(fd, &st) < 0) {
giterr_set(GITERR_OS, "failed to stat file");
error = -1; error = -1;
goto unlock; goto unlock;
} }
if ((fd = git_futils_open_ro(sc->path)) < 0) { if (!git__is_sizet(st.st_size)) {
error = fd; giterr_set(GITERR_INVALID, "Unable to load file larger than size_t");
error = -1;
(void)p_close(fd);
goto unlock; goto unlock;
} }
if (buf) if (buf)
error = git_futils_readbuffer_fd(buf, fd, (size_t)sc->stamp.size); error = git_futils_readbuffer_fd(buf, fd, (size_t)st.st_size);
(void)p_close(fd); (void)p_close(fd);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment