imlib_load_image_mem(): crashes on mmap-ed files #1

Closed
opened 2022-09-28 15:58:02 -07:00 by NRK · 2 comments

However it works fine if the file is malloc-ed. The crash also happens on the 3rd load attempt.

imlib_load_image_frame_mem() also affected. Here's a sample code tested vs master (9f9779e):

/* gcc -o test_bin test.c -lImlib2 -I/usr/local/include -L/usr/local/lib -g -fsanitize=address,undefined -DMMAP=1 */
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

#include <Imlib2.h>

static void *
filemap(const char *path, size_t *len)
{
#if MMAP
	int fd;
	void *buf = MAP_FAILED;
	struct stat statbuf = {0};

	if ((fd = open(path, O_RDONLY)) < 0)
		return MAP_FAILED;
	if (fstat(fd, &statbuf) == 0) {
		*len = statbuf.st_size;
		buf = mmap(NULL, *len, PROT_READ, MAP_PRIVATE, fd, 0);
	}
	close(fd);
	return buf;
#else
	FILE *f = fopen(path, "rb");
	assert(f);
	fseek(f, 0L, SEEK_END);
	*len = ftell(f);
	rewind(f);
	void *data = malloc(*len);
	assert(data);
	assert(fread(data, 1, *len, f) == *len);
	fclose(f);
	return data;
#endif
}

extern int
main(int argc, char *argv[])
{
	if (argc < 2) return 1;
	const char *file = argv[1];
	size_t data_len;
	void *data = filemap(file, &data_len);
	fprintf(stderr, "data: %p\n", data);
	fprintf(stderr, "data_len: %zu\n", data_len);
	if (data == MAP_FAILED) return 1;
	for (size_t n = 1; n <= 16; ++n) {
		Imlib_Image im;
		fprintf(stderr, "n: %zu\n", n);
		if (0)
			im = imlib_load_image_frame_mem(file, n, data, data_len);
		else
			im = imlib_load_image_mem(file, NULL, data, data_len);
		if (im != NULL) {
			imlib_context_set_image(im);
			imlib_free_image();
		} else fputs("im == NULL\n", stderr);
	}
#if MMAP
	munmap(data, data_len);
#else
	free(data);
#endif
}
However it works fine if the file is `malloc`-ed. The crash also happens on the 3rd load attempt. `imlib_load_image_frame_mem()` also affected. Here's a sample code tested vs `master (9f9779e)`: ```c /* gcc -o test_bin test.c -lImlib2 -I/usr/local/include -L/usr/local/lib -g -fsanitize=address,undefined -DMMAP=1 */ #include <assert.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <sys/stat.h> #include <unistd.h> #include <Imlib2.h> static void * filemap(const char *path, size_t *len) { #if MMAP int fd; void *buf = MAP_FAILED; struct stat statbuf = {0}; if ((fd = open(path, O_RDONLY)) < 0) return MAP_FAILED; if (fstat(fd, &statbuf) == 0) { *len = statbuf.st_size; buf = mmap(NULL, *len, PROT_READ, MAP_PRIVATE, fd, 0); } close(fd); return buf; #else FILE *f = fopen(path, "rb"); assert(f); fseek(f, 0L, SEEK_END); *len = ftell(f); rewind(f); void *data = malloc(*len); assert(data); assert(fread(data, 1, *len, f) == *len); fclose(f); return data; #endif } extern int main(int argc, char *argv[]) { if (argc < 2) return 1; const char *file = argv[1]; size_t data_len; void *data = filemap(file, &data_len); fprintf(stderr, "data: %p\n", data); fprintf(stderr, "data_len: %zu\n", data_len); if (data == MAP_FAILED) return 1; for (size_t n = 1; n <= 16; ++n) { Imlib_Image im; fprintf(stderr, "n: %zu\n", n); if (0) im = imlib_load_image_frame_mem(file, n, data, data_len); else im = imlib_load_image_mem(file, NULL, data, data_len); if (im != NULL) { imlib_context_set_image(im); imlib_free_image(); } else fputs("im == NULL\n", stderr); } #if MMAP munmap(data, data_len); #else free(data); #endif } ```
Owner

Should now be fixed in git.

Should now be fixed in git.
Author

Aye, seems to be working fine indeed. Closing.

Aye, seems to be working fine indeed. Closing.
NRK closed this issue 2022-09-29 12:45:47 -07:00
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: old/legacy-imlib2#1
No description provided.