Module Name: src Committed By: christos Date: Tue May 22 02:40:06 UTC 2012
Modified Files: src/sys/kern: exec_elf.c src/sys/sys: exec_elf.h Log Message: - Recognize the SuSE ABI note. - Restructure the code to do the checking in the appropriate note type, and harmonize all the checks to be positive. - Print only the tag data being careful not to overrun the allocated buffer. To generate a diff of this commit: cvs rdiff -u -r1.38 -r1.39 src/sys/kern/exec_elf.c cvs rdiff -u -r1.122 -r1.123 src/sys/sys/exec_elf.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/exec_elf.c diff -u src/sys/kern/exec_elf.c:1.38 src/sys/kern/exec_elf.c:1.39 --- src/sys/kern/exec_elf.c:1.38 Sun Apr 8 07:27:44 2012 +++ src/sys/kern/exec_elf.c Mon May 21 22:40:05 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: exec_elf.c,v 1.38 2012/04/08 11:27:44 martin Exp $ */ +/* $NetBSD: exec_elf.c,v 1.39 2012/05/22 02:40:05 christos Exp $ */ /*- * Copyright (c) 1994, 2000, 2005 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.38 2012/04/08 11:27:44 martin Exp $"); +__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.39 2012/05/22 02:40:05 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_pax.h" @@ -891,15 +891,40 @@ netbsd_elf_signature(struct lwp *l, stru continue; ndata = (char *)(np + 1); + unsigned int maxlen = (unsigned int)(shp->sh_size - + ((char *)ndata - (char *)np)); + if (maxlen < np->n_namesz) + goto bad; switch (np->n_type) { case ELF_NOTE_TYPE_NETBSD_TAG: - if (np->n_namesz != ELF_NOTE_NETBSD_NAMESZ || - np->n_descsz != ELF_NOTE_NETBSD_DESCSZ || + /* + * It is us + */ + if (np->n_namesz == ELF_NOTE_NETBSD_NAMESZ && + np->n_descsz == ELF_NOTE_NETBSD_DESCSZ && memcmp(ndata, ELF_NOTE_NETBSD_NAME, - ELF_NOTE_NETBSD_NAMESZ)) - goto bad; - isnetbsd = 1; - break; + ELF_NOTE_NETBSD_NAMESZ) == 0) { + isnetbsd = 1; + break; + } + /* + * Ignore GNU tags + */ + if (np->n_namesz == ELF_NOTE_GNU_NAMESZ && + memcmp(ndata, ELF_NOTE_GNU_NAME, + ELF_NOTE_GNU_NAMESZ) == 0) + break; + /* + * Ignore SuSE tags + */ + if (np->n_namesz == ELF_NOTE_SUSE_NAMESZ && + memcmp(ndata, ELF_NOTE_SUSE_NAME, + ELF_NOTE_SUSE_NAMESZ) == 0) + break; + /* + * Dunno, warn for diagnostic + */ + goto bad; case ELF_NOTE_TYPE_PAX_TAG: if (np->n_namesz != ELF_NOTE_PAX_NAMESZ || @@ -907,26 +932,14 @@ netbsd_elf_signature(struct lwp *l, stru memcmp(ndata, ELF_NOTE_PAX_NAME, ELF_NOTE_PAX_NAMESZ)) { bad: - /* - * Ignore GNU tags - */ - if (np->n_namesz == ELF_NOTE_GNU_NAMESZ && - memcmp(ndata, ELF_NOTE_GNU_NAME, - ELF_NOTE_GNU_NAMESZ) == 0) - break; #ifdef DIAGNOSTIC - printf("%s: bad tag %d: " - "[%d %d, %d %d, %*.*s %*.*s]\n", - epp->ep_kname, - np->n_type, - np->n_namesz, ELF_NOTE_PAX_NAMESZ, - np->n_descsz, ELF_NOTE_PAX_DESCSZ, - ELF_NOTE_PAX_NAMESZ, - ELF_NOTE_PAX_NAMESZ, - ndata, - ELF_NOTE_PAX_NAMESZ, - ELF_NOTE_PAX_NAMESZ, - ELF_NOTE_PAX_NAME); + { + int ns = MIN(np->n_namesz, maxlen); + printf("%s: Unknown elf note type %d: " + "[namesz=%d, descsz=%d name=%*.*s]\n", + epp->ep_kname, np->n_type, np->n_namesz, + np->n_descsz, ns, ns, ndata); + } #endif continue; } @@ -935,7 +948,7 @@ bad: sizeof(epp->ep_pax_flags)); break; - case ELF_NOTE_TYPE_SUSE_TAG: + case ELF_NOTE_TYPE_SUSE_VERSION_TAG: break; default: Index: src/sys/sys/exec_elf.h diff -u src/sys/sys/exec_elf.h:1.122 src/sys/sys/exec_elf.h:1.123 --- src/sys/sys/exec_elf.h:1.122 Sat Feb 4 13:12:02 2012 +++ src/sys/sys/exec_elf.h Mon May 21 22:40:06 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: exec_elf.h,v 1.122 2012/02/04 18:12:02 joerg Exp $ */ +/* $NetBSD: exec_elf.h,v 1.123 2012/05/22 02:40:06 christos Exp $ */ /*- * Copyright (c) 1994 The NetBSD Foundation, Inc. @@ -805,6 +805,23 @@ typedef struct { */ #define ELF_NOTE_TYPE_GNU_BUILD_ID 3 +/* SuSE-specific note type: ABI + * name: SuSE\0 + * namesz: 5 + * desc: + * half[0] = MMmm + * + * M = product major version + * m = product minor version + * descsz: 2 + */ +#define ELF_NOTE_TYPE_SUSE_TAG 1 +/* SuSE-specific note name and description sizes */ +#define ELF_NOTE_SUSE_NAMESZ 5 +#define ELF_NOTE_SUSE_DESCSZ 2 +/* SuSE-specific note name */ +#define ELF_NOTE_SUSE_NAME "SuSE\0" + /* SuSE-specific note type: version * name: SuSE\0\0\0\0 * namesz: 8 @@ -817,12 +834,12 @@ typedef struct { * m = product minor version * descsz: 8 */ -#define ELF_NOTE_TYPE_SUSE_TAG 0x45537553 /* SuSE in LE */ +#define ELF_NOTE_TYPE_SUSE_VERSION_TAG 0x45537553 /* SuSE in LE */ /* SuSE-specific note name and description sizes */ -#define ELF_NOTE_SUSE_NAMESZ 8 -#define ELF_NOTE_SUSE_DESCSZ 8 +#define ELF_NOTE_SUSE_VERSION_NAMESZ 8 +#define ELF_NOTE_SUSE_VERSION_DESCSZ 8 /* SuSE-specific note name */ -#define ELF_NOTE_SUSE_NAME "SuSE\0\0\0\0" +#define ELF_NOTE_SUSE_VERSION_NAME "SuSE\0\0\0\0" /* NetBSD-specific note type: Emulation name. * name: NetBSD\0\0