зеркало из https://github.com/microsoft/git.git
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:
Коммит
c5baf18a40
22
config.c
22
config.c
|
@ -1937,6 +1937,8 @@ int git_config_set_multivar_in_file(const char *config_filename,
|
||||||
int ret;
|
int ret;
|
||||||
struct lock_file *lock = NULL;
|
struct lock_file *lock = NULL;
|
||||||
char *filename_buf = NULL;
|
char *filename_buf = NULL;
|
||||||
|
char *contents = NULL;
|
||||||
|
size_t contents_sz;
|
||||||
|
|
||||||
/* parse-key returns negative; flip the sign to feed exit(3) */
|
/* parse-key returns negative; flip the sign to feed exit(3) */
|
||||||
ret = 0 - git_config_parse_key(key, &store.key, &store.baselen);
|
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;
|
goto write_err_out;
|
||||||
} else {
|
} else {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *contents;
|
size_t copy_begin, copy_end;
|
||||||
size_t contents_sz, copy_begin, copy_end;
|
|
||||||
int i, new_line = 0;
|
int i, new_line = 0;
|
||||||
|
|
||||||
if (value_regex == NULL)
|
if (value_regex == NULL)
|
||||||
|
@ -2050,8 +2051,17 @@ int git_config_set_multivar_in_file(const char *config_filename,
|
||||||
|
|
||||||
fstat(in_fd, &st);
|
fstat(in_fd, &st);
|
||||||
contents_sz = xsize_t(st.st_size);
|
contents_sz = xsize_t(st.st_size);
|
||||||
contents = xmmap(NULL, contents_sz, PROT_READ,
|
contents = xmmap_gently(NULL, contents_sz, PROT_READ,
|
||||||
MAP_PRIVATE, in_fd, 0);
|
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);
|
close(in_fd);
|
||||||
|
|
||||||
if (chmod(lock->filename.buf, st.st_mode & 07777) < 0) {
|
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) <
|
||||||
contents_sz - copy_begin)
|
contents_sz - copy_begin)
|
||||||
goto write_err_out;
|
goto write_err_out;
|
||||||
|
|
||||||
munmap(contents, contents_sz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commit_lock_file(lock) < 0) {
|
if (commit_lock_file(lock) < 0) {
|
||||||
|
@ -2133,6 +2141,8 @@ out_free:
|
||||||
if (lock)
|
if (lock)
|
||||||
rollback_lock_file(lock);
|
rollback_lock_file(lock);
|
||||||
free(filename_buf);
|
free(filename_buf);
|
||||||
|
if (contents)
|
||||||
|
munmap(contents, contents_sz);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
write_err_out:
|
write_err_out:
|
||||||
|
|
|
@ -717,6 +717,7 @@ extern char *xstrndup(const char *str, size_t len);
|
||||||
extern void *xrealloc(void *ptr, size_t size);
|
extern void *xrealloc(void *ptr, size_t size);
|
||||||
extern void *xcalloc(size_t nmemb, size_t size);
|
extern void *xcalloc(size_t nmemb, size_t size);
|
||||||
extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
|
extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
|
||||||
|
extern void *xmmap_gently(void *start, size_t length, int prot, int flags, int fd, off_t offset);
|
||||||
extern ssize_t xread(int fd, void *buf, size_t len);
|
extern ssize_t xread(int fd, void *buf, size_t len);
|
||||||
extern ssize_t xwrite(int fd, const void *buf, size_t len);
|
extern ssize_t xwrite(int fd, const void *buf, size_t len);
|
||||||
extern ssize_t xpread(int fd, void *buf, size_t len, off_t offset);
|
extern ssize_t xpread(int fd, void *buf, size_t len, off_t offset);
|
||||||
|
|
|
@ -1540,7 +1540,7 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
|
||||||
if (mmap_size < sizeof(struct cache_header) + 20)
|
if (mmap_size < sizeof(struct cache_header) + 20)
|
||||||
die("index file smaller than expected");
|
die("index file smaller than expected");
|
||||||
|
|
||||||
mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
mmap = xmmap(NULL, mmap_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
if (mmap == MAP_FAILED)
|
if (mmap == MAP_FAILED)
|
||||||
die_errno("unable to map index file");
|
die_errno("unable to map index file");
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
15
sha1_file.c
15
sha1_file.c
|
@ -707,8 +707,8 @@ static void mmap_limit_check(size_t length)
|
||||||
(uintmax_t)length, (uintmax_t)limit);
|
(uintmax_t)length, (uintmax_t)limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *xmmap(void *start, size_t length,
|
void *xmmap_gently(void *start, size_t length,
|
||||||
int prot, int flags, int fd, off_t offset)
|
int prot, int flags, int fd, off_t offset)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
|
@ -719,12 +719,19 @@ void *xmmap(void *start, size_t length,
|
||||||
return NULL;
|
return NULL;
|
||||||
release_pack_memory(length);
|
release_pack_memory(length);
|
||||||
ret = mmap(start, length, prot, flags, fd, offset);
|
ret = mmap(start, length, prot, flags, fd, offset);
|
||||||
if (ret == MAP_FAILED)
|
|
||||||
die_errno("Out of memory? mmap failed");
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *xmmap(void *start, size_t length,
|
||||||
|
int prot, int flags, int fd, off_t offset)
|
||||||
|
{
|
||||||
|
void *ret = xmmap_gently(start, length, prot, flags, fd, offset);
|
||||||
|
if (ret == MAP_FAILED)
|
||||||
|
die_errno("mmap failed");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void close_pack_windows(struct packed_git *p)
|
void close_pack_windows(struct packed_git *p)
|
||||||
{
|
{
|
||||||
while (p->windows) {
|
while (p->windows) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче