Code change for CVE-2014-3710

ext/fileinfo/libmagic/readelf.c

function header

private size_t donote(struct magic_set *, unsigned char *, size_t, size_t, int, int, size_t, int *);

CODE CHANGE

— a/ext/fileinfo/libmagic/readelf.c

+++ b/ext/fileinfo/libmagic/readelf.c

@@ -372,6 +372,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, uint32_t namesz, descsz; unsigned char *nbuf = CAST(unsigned char *, vbuf);

+       if (xnh_sizeof + offset > size) {

+               /*

+                * We’re out of note headers.

+                */

+               return xnh_sizeof + offset;

+       }

+ (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);

offset += xnh_sizeof;

EXAMPLE CALLING CODE

if (offset >= (size_t)bufsize)

break;

offset = donote(ms, nbuf, offset, (size_t)bufsize, clazz, swap, 4, flags);

What is a note header?

The elf(5) man page states that a note may appear in two places.  The Section header and the Program Header.  It is denoted by either SHN_NOTE or PT_NOTE when the ElfN_Shdr or ElfN_Phdr define a note structure.

Digging a little further into the PHP source code for the fileinfo extension I discovered that a note header can be defined as

typedef struct {

ElfN_Word n_namesz;

ElfN_Word n_descsz;

ElfN_Word n_type;

} ElfN_Nhdr;

Conclusion

The code change to the file c code mitigated a buffer overflow by stopping the current function call when the elf file note header was not complete.