Merge branch 'jk/diagnose-config-mmap-failure' into maint

The configuration reader/writer uses mmap(2) interface to access
the files; when we find a directory, it barfed with "Out of memory?".

* jk/diagnose-config-mmap-failure:
  xmmap(): drop "Out of memory?"
  config.c: rewrite ENODEV into EISDIR when mmap fails
  config.c: avoid xmmap error messages
  config.c: fix mmap leak when writing config
  read-cache.c: drop PROT_WRITE from mmap of index
This commit is contained in:
Junio C Hamano
2015-06-25 11:02:10 -07:00
4 changed files with 29 additions and 11 deletions

View File

@ -1937,6 +1937,8 @@ int git_config_set_multivar_in_file(const char *config_filename,
int ret;
struct lock_file *lock = NULL;
char *filename_buf = NULL;
char *contents = NULL;
size_t contents_sz;
/* parse-key returns negative; flip the sign to feed exit(3) */
ret = 0 - git_config_parse_key(key, &store.key, &store.baselen);
@ -1986,8 +1988,7 @@ int git_config_set_multivar_in_file(const char *config_filename,
goto write_err_out;
} else {
struct stat st;
char *contents;
size_t contents_sz, copy_begin, copy_end;
size_t copy_begin, copy_end;
int i, new_line = 0;
if (value_regex == NULL)
@ -2050,8 +2051,17 @@ int git_config_set_multivar_in_file(const char *config_filename,
fstat(in_fd, &st);
contents_sz = xsize_t(st.st_size);
contents = xmmap(NULL, contents_sz, PROT_READ,
MAP_PRIVATE, in_fd, 0);
contents = xmmap_gently(NULL, contents_sz, PROT_READ,
MAP_PRIVATE, in_fd, 0);
if (contents == MAP_FAILED) {
if (errno == ENODEV && S_ISDIR(st.st_mode))
errno = EISDIR;
error("unable to mmap '%s': %s",
config_filename, strerror(errno));
ret = CONFIG_INVALID_FILE;
contents = NULL;
goto out_free;
}
close(in_fd);
if (chmod(lock->filename.buf, st.st_mode & 07777) < 0) {
@ -2106,8 +2116,6 @@ int git_config_set_multivar_in_file(const char *config_filename,
contents_sz - copy_begin) <
contents_sz - copy_begin)
goto write_err_out;
munmap(contents, contents_sz);
}
if (commit_lock_file(lock) < 0) {
@ -2133,6 +2141,8 @@ out_free:
if (lock)
rollback_lock_file(lock);
free(filename_buf);
if (contents)
munmap(contents, contents_sz);
return ret;
write_err_out: