| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: exec_elf.c,v 1.38 2012/04/08 11:27:44 martin Exp $ */ | | 1 | /* $NetBSD: exec_elf.c,v 1.39 2012/05/22 02:40:05 christos Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1994, 2000, 2005 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1994, 2000, 2005 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Christos Zoulas. | | 8 | * by Christos Zoulas. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -47,27 +47,27 @@ | | | @@ -47,27 +47,27 @@ |
47 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 47 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
48 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 48 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
49 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 49 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
50 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 50 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
51 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 51 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
52 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 52 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
53 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 53 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
54 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 54 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
55 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 55 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
56 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 56 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
57 | */ | | 57 | */ |
58 | | | 58 | |
59 | #include <sys/cdefs.h> | | 59 | #include <sys/cdefs.h> |
60 | __KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.38 2012/04/08 11:27:44 martin Exp $"); | | 60 | __KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.39 2012/05/22 02:40:05 christos Exp $"); |
61 | | | 61 | |
62 | #ifdef _KERNEL_OPT | | 62 | #ifdef _KERNEL_OPT |
63 | #include "opt_pax.h" | | 63 | #include "opt_pax.h" |
64 | #endif /* _KERNEL_OPT */ | | 64 | #endif /* _KERNEL_OPT */ |
65 | | | 65 | |
66 | #include <sys/param.h> | | 66 | #include <sys/param.h> |
67 | #include <sys/proc.h> | | 67 | #include <sys/proc.h> |
68 | #include <sys/kmem.h> | | 68 | #include <sys/kmem.h> |
69 | #include <sys/namei.h> | | 69 | #include <sys/namei.h> |
70 | #include <sys/vnode.h> | | 70 | #include <sys/vnode.h> |
71 | #include <sys/exec.h> | | 71 | #include <sys/exec.h> |
72 | #include <sys/exec_elf.h> | | 72 | #include <sys/exec_elf.h> |
73 | #include <sys/syscall.h> | | 73 | #include <sys/syscall.h> |
| @@ -881,71 +881,84 @@ netbsd_elf_signature(struct lwp *l, stru | | | @@ -881,71 +881,84 @@ netbsd_elf_signature(struct lwp *l, stru |
881 | Elf_Shdr *shp = &sh[i]; | | 881 | Elf_Shdr *shp = &sh[i]; |
882 | | | 882 | |
883 | if (shp->sh_type != SHT_NOTE || | | 883 | if (shp->sh_type != SHT_NOTE || |
884 | shp->sh_size > MAXNOTESIZE || | | 884 | shp->sh_size > MAXNOTESIZE || |
885 | shp->sh_size < sizeof(Elf_Nhdr) + ELF_NOTE_NETBSD_NAMESZ) | | 885 | shp->sh_size < sizeof(Elf_Nhdr) + ELF_NOTE_NETBSD_NAMESZ) |
886 | continue; | | 886 | continue; |
887 | | | 887 | |
888 | error = exec_read_from(l, epp->ep_vp, shp->sh_offset, np, | | 888 | error = exec_read_from(l, epp->ep_vp, shp->sh_offset, np, |
889 | shp->sh_size); | | 889 | shp->sh_size); |
890 | if (error) | | 890 | if (error) |
891 | continue; | | 891 | continue; |
892 | | | 892 | |
893 | ndata = (char *)(np + 1); | | 893 | ndata = (char *)(np + 1); |
| | | 894 | unsigned int maxlen = (unsigned int)(shp->sh_size - |
| | | 895 | ((char *)ndata - (char *)np)); |
| | | 896 | if (maxlen < np->n_namesz) |
| | | 897 | goto bad; |
894 | switch (np->n_type) { | | 898 | switch (np->n_type) { |
895 | case ELF_NOTE_TYPE_NETBSD_TAG: | | 899 | case ELF_NOTE_TYPE_NETBSD_TAG: |
896 | if (np->n_namesz != ELF_NOTE_NETBSD_NAMESZ || | | 900 | /* |
897 | np->n_descsz != ELF_NOTE_NETBSD_DESCSZ || | | 901 | * It is us |
| | | 902 | */ |
| | | 903 | if (np->n_namesz == ELF_NOTE_NETBSD_NAMESZ && |
| | | 904 | np->n_descsz == ELF_NOTE_NETBSD_DESCSZ && |
898 | memcmp(ndata, ELF_NOTE_NETBSD_NAME, | | 905 | memcmp(ndata, ELF_NOTE_NETBSD_NAME, |
899 | ELF_NOTE_NETBSD_NAMESZ)) | | 906 | ELF_NOTE_NETBSD_NAMESZ) == 0) { |
900 | goto bad; | | 907 | isnetbsd = 1; |
901 | isnetbsd = 1; | | 908 | break; |
902 | break; | | 909 | } |
| | | 910 | /* |
| | | 911 | * Ignore GNU tags |
| | | 912 | */ |
| | | 913 | if (np->n_namesz == ELF_NOTE_GNU_NAMESZ && |
| | | 914 | memcmp(ndata, ELF_NOTE_GNU_NAME, |
| | | 915 | ELF_NOTE_GNU_NAMESZ) == 0) |
| | | 916 | break; |
| | | 917 | /* |
| | | 918 | * Ignore SuSE tags |
| | | 919 | */ |
| | | 920 | if (np->n_namesz == ELF_NOTE_SUSE_NAMESZ && |
| | | 921 | memcmp(ndata, ELF_NOTE_SUSE_NAME, |
| | | 922 | ELF_NOTE_SUSE_NAMESZ) == 0) |
| | | 923 | break; |
| | | 924 | /* |
| | | 925 | * Dunno, warn for diagnostic |
| | | 926 | */ |
| | | 927 | goto bad; |
903 | | | 928 | |
904 | case ELF_NOTE_TYPE_PAX_TAG: | | 929 | case ELF_NOTE_TYPE_PAX_TAG: |
905 | if (np->n_namesz != ELF_NOTE_PAX_NAMESZ || | | 930 | if (np->n_namesz != ELF_NOTE_PAX_NAMESZ || |
906 | np->n_descsz != ELF_NOTE_PAX_DESCSZ || | | 931 | np->n_descsz != ELF_NOTE_PAX_DESCSZ || |
907 | memcmp(ndata, ELF_NOTE_PAX_NAME, | | 932 | memcmp(ndata, ELF_NOTE_PAX_NAME, |
908 | ELF_NOTE_PAX_NAMESZ)) { | | 933 | ELF_NOTE_PAX_NAMESZ)) { |
909 | bad: | | 934 | bad: |
910 | /* | | | |
911 | * Ignore GNU tags | | | |
912 | */ | | | |
913 | if (np->n_namesz == ELF_NOTE_GNU_NAMESZ && | | | |
914 | memcmp(ndata, ELF_NOTE_GNU_NAME, | | | |
915 | ELF_NOTE_GNU_NAMESZ) == 0) | | | |
916 | break; | | | |
917 | #ifdef DIAGNOSTIC | | 935 | #ifdef DIAGNOSTIC |
918 | printf("%s: bad tag %d: " | | 936 | { |
919 | "[%d %d, %d %d, %*.*s %*.*s]\n", | | 937 | int ns = MIN(np->n_namesz, maxlen); |
920 | epp->ep_kname, | | 938 | printf("%s: Unknown elf note type %d: " |
921 | np->n_type, | | 939 | "[namesz=%d, descsz=%d name=%*.*s]\n", |
922 | np->n_namesz, ELF_NOTE_PAX_NAMESZ, | | 940 | epp->ep_kname, np->n_type, np->n_namesz, |
923 | np->n_descsz, ELF_NOTE_PAX_DESCSZ, | | 941 | np->n_descsz, ns, ns, ndata); |
924 | ELF_NOTE_PAX_NAMESZ, | | 942 | } |
925 | ELF_NOTE_PAX_NAMESZ, | | | |
926 | ndata, | | | |
927 | ELF_NOTE_PAX_NAMESZ, | | | |
928 | ELF_NOTE_PAX_NAMESZ, | | | |
929 | ELF_NOTE_PAX_NAME); | | | |
930 | #endif | | 943 | #endif |
931 | continue; | | 944 | continue; |
932 | } | | 945 | } |
933 | (void)memcpy(&epp->ep_pax_flags, | | 946 | (void)memcpy(&epp->ep_pax_flags, |
934 | ndata + ELF_NOTE_PAX_NAMESZ, | | 947 | ndata + ELF_NOTE_PAX_NAMESZ, |
935 | sizeof(epp->ep_pax_flags)); | | 948 | sizeof(epp->ep_pax_flags)); |
936 | break; | | 949 | break; |
937 | | | 950 | |
938 | case ELF_NOTE_TYPE_SUSE_TAG: | | 951 | case ELF_NOTE_TYPE_SUSE_VERSION_TAG: |
939 | break; | | 952 | break; |
940 | | | 953 | |
941 | default: | | 954 | default: |
942 | #ifdef DIAGNOSTIC | | 955 | #ifdef DIAGNOSTIC |
943 | printf("%s: unknown note type %d\n", epp->ep_kname, | | 956 | printf("%s: unknown note type %d\n", epp->ep_kname, |
944 | np->n_type); | | 957 | np->n_type); |
945 | #endif | | 958 | #endif |
946 | break; | | 959 | break; |
947 | } | | 960 | } |
948 | } | | 961 | } |
949 | kmem_free(np, MAXNOTESIZE); | | 962 | kmem_free(np, MAXNOTESIZE); |
950 | | | 963 | |
951 | error = isnetbsd ? 0 : ENOEXEC; | | 964 | error = isnetbsd ? 0 : ENOEXEC; |