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 indexmaint
						commit
						c5baf18a40
					
				
							
								
								
									
										20
									
								
								config.c
								
								
								
								
							
							
						
						
									
										20
									
								
								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); | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								sha1_file.c
								
								
								
								
							
							
						
						
									
										13
									
								
								sha1_file.c
								
								
								
								
							|  | @ -707,7 +707,7 @@ 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) { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano