Skip to content

gvfs-helper: fix race condition when creating loose object dirs #205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion gvfs-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,9 @@ static void create_tempfile_for_loose(
strbuf_complete(&buf_path, '/');
strbuf_add(&buf_path, hex, 2);

if (!file_exists(buf_path.buf) && mkdir(buf_path.buf, 0777) == -1) {
if (!file_exists(buf_path.buf) &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit unrelated, do you know if there is a function dir_exists that checks if the path exists as a directory (or should we add one to use here)?

I couldn't find one in dir.c, but I imagine all it would need is:

int dir_exists(const char *f)
{
	struct stat sb;
	if (lstat(f, &sb) != 0)
		return false;

	return S_ISDIR(sb.st_mode);
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following exists in builtin/clone.c:

static int dir_exists(const char *path)
{
	struct stat sb;
	return !stat(path, &sb);
}

It doesn't check the S_ISDIR().

I do see your interest in checking the type to make sure there isn't a file in the way. I'm not sure if there is enough value.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if there is enough value.

Yeah I was on the fence as well, we've not seen this be a problem thus far.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Thanks!
I'll fix it Monday. I think I can just try the mkdir() and catch the EEXIST error code.
I avoided that because of the platform nature of the error codes.
(or just try the lstat() again inside the error case.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that there is not only a dir_exists(), but also an is_directory() function (the latter of which is public). There is even a ticket to reconcile them: gitgitgadget#230

mkdir(buf_path.buf, 0777) == -1 &&
!file_exists(buf_path.buf)) {
strbuf_addf(&status->error_message,
"cannot create directory for loose object '%s'",
buf_path.buf);
Expand Down