Your message dated Sun, 30 Aug 2009 10:19:33 -0500 with message-id <[email protected]> has caused the report #543915, regarding "libsepol.sepol_module_package_read: out of memory" to be marked as having been forwarded to the upstream software author(s) [email protected]
(NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact [email protected] immediately.) -- 543915: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=543915 Debian Bug Tracking System Contact [email protected] with problems
--- Begin Message ---Hi, This bug was discovered, and the analysis done, buy Max Kellermann. I have never been able to replicate the problem, so I can't help debug this error. Strace: --8<---------------cut here---------------start------------->8--- brk(0x3233000) = 0x3233000 mmap(NULL, 18446744073703178240, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory) mmap(NULL, 18446744073703313408, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory) mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7fdfda316000 --8<---------------cut here---------------end--------------->8--- > 0xffffffffff9ec000 == 18446744073703178240 (the size of the first > large allocation). It's also equal to -6373376. This just looks like > an integer underflow, doesn't it? --8<---------------cut here---------------start------------->8--- Breakpoint 4, 0x00007f9bc4c05400 in mmap64 () from /lib/libc.so.6 (gdb) p $rsi $25 = -6373376 (gdb) bt #0 0x00007f9bc4c05400 in mmap64 () from /lib/libc.so.6 #1 0x00007f9bc4baf6bb in _int_malloc () from /lib/libc.so.6 #2 0x00007f9bc4bb0a78 in malloc () from /lib/libc.so.6 #3 0x00007f9bc5301a8e in sepol_module_package_read (mod=0xb1d170, spf=0xb202e0, verbose=0) at module.c:533 #4 0x00007f9bc4ea7838 in ?? () from /lib/libsemanage.so.1 (gdb) frame 3 #3 0x00007f9bc5301a8e in sepol_module_package_read (mod=0xb1d170, spf=0xb202e0, verbose=0) at module.c:533 533 module.c: No such file or directory. in module.c (gdb) p len $26 = 18446744073703176358 (gdb) p i $27 = 3 (gdb) p nsec $30 = 4 (gdb) p offsets[i+1] $28 = 8192 (gdb) p offsets[i] $29 = 6383450 --8<---------------cut here---------------end--------------->8--- > line 456: > len = offsets[i + 1] - offsets[i]; > Voila, integer underflow. The function module_package_read_offsets() > reads the offsets from the input file, but does not verify them. > off[nsec] = policy_file_length(file); > Here, the check is missing. We should probably have: --8<---------------cut here---------------start------------->8--- off[nsec] = policy_file_length(file); if (off[nsec] < off[nsec-1]) { ERR(file->handle, "file size smaller than previous offset (at %u, " "offset %zu -> %zu", nsec, off[nsec - 1], off[nsec]); return -1; } --8<---------------cut here---------------end--------------->8--- > But why is the file length 8192? My base.pp has 6383597 bytes > (compressed), not 8192. Let's break in policy_file_length(): --8<---------------cut here---------------start------------->8--- (gdb) p prev_offset $4 = 28 (gdb) p end_offset $5 = 8192 (gdb) p fp->fp $6 = (FILE *) 0x1c42350 $7 = -1 --8<---------------cut here---------------end--------------->8--- > But why is the file descriptor negative? sepol_module_package_read() > is called by semanage_load_module(), which bunzips the file, closes > it, reopens it with fmemopen(). I don't understand this part. Upon successful completion fmemopen() returns a FILE pointer. Otherwise, NULL is returned, and that is checked for in In semanage_store.c: --8<---------------cut here---------------start------------->8--- ssize_t size; char *data = NULL; if ((size = bunzip(sh, fp, &data)) > 0) { fclose(fp); fp = fmemopen(data, size, "rb"); if (!fp) { ERR(sh, "Out of memory!"); goto cleanup; } } --8<---------------cut here---------------end--------------->8--- According to the man page, ever since glibc 2.9, the letter 'b' may be specified as the second character in mode. This provides "binary" mode: writes don't implicitly add a terminating null byte, and fseek(3) SEEK_END is relative to the end of the buffer (i.e., the value specified by the size argument), rather than the current string length. Anyway, I think that adding a defensive check when we set off[nsec] seems to be in order, and would not harm anything; and would have prevented the huge memory allocation issue, and perhaps given a better error message. manoj -- Manoj Srivastava <[email protected]> <http://www.golden-gryphon.com/> 1024D/BF24424C print 4966 F272 D093 B493 410B 924B 21BA DABB BF24 424C
--- End Message ---

