Skip to content

Commit 40ffa07

Browse files
committed
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.
1 parent 26416f6 commit 40ffa07

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

src/sortedcache.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,26 +200,34 @@ void git_sortedcache_runlock(git_sortedcache *sc)
200200
int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf)
201201
{
202202
int error, fd;
203+
struct stat st;
203204

204205
if ((error = git_sortedcache_wlock(sc)) < 0)
205206
return error;
206207

207208
if ((error = git_futils_filestamp_check(&sc->stamp, sc->path)) <= 0)
208209
goto unlock;
209210

210-
if (!git__is_sizet(sc->stamp.size)) {
211-
giterr_set(GITERR_INVALID, "Unable to load file larger than size_t");
211+
if ((fd = git_futils_open_ro(sc->path)) < 0) {
212+
error = fd;
213+
goto unlock;
214+
}
215+
216+
if (p_fstat(fd, &st) < 0) {
217+
giterr_set(GITERR_OS, "failed to stat file");
212218
error = -1;
213219
goto unlock;
214220
}
215221

216-
if ((fd = git_futils_open_ro(sc->path)) < 0) {
217-
error = fd;
222+
if (!git__is_sizet(st.st_size)) {
223+
giterr_set(GITERR_INVALID, "Unable to load file larger than size_t");
224+
error = -1;
225+
(void)p_close(fd);
218226
goto unlock;
219227
}
220228

221229
if (buf)
222-
error = git_futils_readbuffer_fd(buf, fd, (size_t)sc->stamp.size);
230+
error = git_futils_readbuffer_fd(buf, fd, (size_t)st.st_size);
223231

224232
(void)p_close(fd);
225233

0 commit comments

Comments
 (0)