1*12929SMisaki.Miyashita@Oracle.COM /*
2*12929SMisaki.Miyashita@Oracle.COM * CDDL HEADER START
3*12929SMisaki.Miyashita@Oracle.COM *
4*12929SMisaki.Miyashita@Oracle.COM * The contents of this file are subject to the terms of the
5*12929SMisaki.Miyashita@Oracle.COM * Common Development and Distribution License (the "License").
6*12929SMisaki.Miyashita@Oracle.COM * You may not use this file except in compliance with the License.
7*12929SMisaki.Miyashita@Oracle.COM *
8*12929SMisaki.Miyashita@Oracle.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12929SMisaki.Miyashita@Oracle.COM * or http://www.opensolaris.org/os/licensing.
10*12929SMisaki.Miyashita@Oracle.COM * See the License for the specific language governing permissions
11*12929SMisaki.Miyashita@Oracle.COM * and limitations under the License.
12*12929SMisaki.Miyashita@Oracle.COM *
13*12929SMisaki.Miyashita@Oracle.COM * When distributing Covered Code, include this CDDL HEADER in each
14*12929SMisaki.Miyashita@Oracle.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12929SMisaki.Miyashita@Oracle.COM * If applicable, add the following below this CDDL HEADER, with the
16*12929SMisaki.Miyashita@Oracle.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*12929SMisaki.Miyashita@Oracle.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*12929SMisaki.Miyashita@Oracle.COM *
19*12929SMisaki.Miyashita@Oracle.COM * CDDL HEADER END
20*12929SMisaki.Miyashita@Oracle.COM */
21*12929SMisaki.Miyashita@Oracle.COM /*
22*12929SMisaki.Miyashita@Oracle.COM * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23*12929SMisaki.Miyashita@Oracle.COM */
24*12929SMisaki.Miyashita@Oracle.COM
25*12929SMisaki.Miyashita@Oracle.COM
26*12929SMisaki.Miyashita@Oracle.COM #include <fips/fips_checksum.h>
27*12929SMisaki.Miyashita@Oracle.COM
28*12929SMisaki.Miyashita@Oracle.COM
29*12929SMisaki.Miyashita@Oracle.COM #ifdef _KERNEL
30*12929SMisaki.Miyashita@Oracle.COM #define FIPS_ALLOC(size) kmem_alloc(size, KM_SLEEP)
31*12929SMisaki.Miyashita@Oracle.COM #define FIPS_FREE(buf, size) kmem_free(buf, size)
32*12929SMisaki.Miyashita@Oracle.COM #define FIPS_READ_FILE kobj_read_file
33*12929SMisaki.Miyashita@Oracle.COM #define ERRLOG0(str) cmn_err(CE_NOTE, str)
34*12929SMisaki.Miyashita@Oracle.COM #define ERRLOG1(fmt, arg) cmn_err(CE_NOTE, fmt, arg)
35*12929SMisaki.Miyashita@Oracle.COM #include <sys/sunddi.h>
36*12929SMisaki.Miyashita@Oracle.COM
37*12929SMisaki.Miyashita@Oracle.COM struct _buf *kobj_open_file(char *name);
38*12929SMisaki.Miyashita@Oracle.COM int kobj_read_file(struct _buf *file, char *buf, uint_t size, uint_t off);
39*12929SMisaki.Miyashita@Oracle.COM #else
40*12929SMisaki.Miyashita@Oracle.COM
41*12929SMisaki.Miyashita@Oracle.COM #define FIPS_ALLOC(size) malloc(size)
42*12929SMisaki.Miyashita@Oracle.COM #define FIPS_FREE(buf, size) free(buf)
43*12929SMisaki.Miyashita@Oracle.COM #define FIPS_READ_FILE fips_read_file
44*12929SMisaki.Miyashita@Oracle.COM #define ERRLOG0(str) (void) printf(str)
45*12929SMisaki.Miyashita@Oracle.COM #define ERRLOG1(fmt, arg) (void) printf(fmt, arg)
46*12929SMisaki.Miyashita@Oracle.COM #endif
47*12929SMisaki.Miyashita@Oracle.COM
48*12929SMisaki.Miyashita@Oracle.COM #define NUM_SECTIONS (sizeof (checked_sec_names) / sizeof (char *))
49*12929SMisaki.Miyashita@Oracle.COM
50*12929SMisaki.Miyashita@Oracle.COM static char *checked_sec_names[] = {
51*12929SMisaki.Miyashita@Oracle.COM ".strtab",
52*12929SMisaki.Miyashita@Oracle.COM ".dynamic",
53*12929SMisaki.Miyashita@Oracle.COM ".compcom",
54*12929SMisaki.Miyashita@Oracle.COM ".comment",
55*12929SMisaki.Miyashita@Oracle.COM ".dynstr",
56*12929SMisaki.Miyashita@Oracle.COM ".shstrtab",
57*12929SMisaki.Miyashita@Oracle.COM ".rela.text",
58*12929SMisaki.Miyashita@Oracle.COM ".rela.data",
59*12929SMisaki.Miyashita@Oracle.COM ".text",
60*12929SMisaki.Miyashita@Oracle.COM ".rodata",
61*12929SMisaki.Miyashita@Oracle.COM ".rodata1",
62*12929SMisaki.Miyashita@Oracle.COM ".data",
63*12929SMisaki.Miyashita@Oracle.COM ".symtab",
64*12929SMisaki.Miyashita@Oracle.COM ".SUNW_ctf",
65*12929SMisaki.Miyashita@Oracle.COM ".bss"
66*12929SMisaki.Miyashita@Oracle.COM };
67*12929SMisaki.Miyashita@Oracle.COM
68*12929SMisaki.Miyashita@Oracle.COM
69*12929SMisaki.Miyashita@Oracle.COM static int
70*12929SMisaki.Miyashita@Oracle.COM #ifdef _KERNEL
process_section(SHA1_CTX * shactx,Elf64_Shdr * section,struct _buf * file,char * shstrtab)71*12929SMisaki.Miyashita@Oracle.COM process_section(SHA1_CTX *shactx, Elf64_Shdr *section, struct _buf *file,
72*12929SMisaki.Miyashita@Oracle.COM char *shstrtab)
73*12929SMisaki.Miyashita@Oracle.COM #else
74*12929SMisaki.Miyashita@Oracle.COM process_section(SHA1_CTX *shactx, Elf64_Shdr *section, int file,
75*12929SMisaki.Miyashita@Oracle.COM char *shstrtab)
76*12929SMisaki.Miyashita@Oracle.COM #endif
77*12929SMisaki.Miyashita@Oracle.COM {
78*12929SMisaki.Miyashita@Oracle.COM size_t size, offs;
79*12929SMisaki.Miyashita@Oracle.COM char *name;
80*12929SMisaki.Miyashita@Oracle.COM int doit = 0;
81*12929SMisaki.Miyashita@Oracle.COM char *buf;
82*12929SMisaki.Miyashita@Oracle.COM int i;
83*12929SMisaki.Miyashita@Oracle.COM
84*12929SMisaki.Miyashita@Oracle.COM size = section->sh_size;
85*12929SMisaki.Miyashita@Oracle.COM offs = section->sh_offset;
86*12929SMisaki.Miyashita@Oracle.COM name = shstrtab + section->sh_name;
87*12929SMisaki.Miyashita@Oracle.COM for (i = 0; i < NUM_SECTIONS; i++) {
88*12929SMisaki.Miyashita@Oracle.COM if (strncmp(name, checked_sec_names[i],
89*12929SMisaki.Miyashita@Oracle.COM strlen(checked_sec_names[i]) + 1) == 0) {
90*12929SMisaki.Miyashita@Oracle.COM doit++;
91*12929SMisaki.Miyashita@Oracle.COM break;
92*12929SMisaki.Miyashita@Oracle.COM }
93*12929SMisaki.Miyashita@Oracle.COM }
94*12929SMisaki.Miyashita@Oracle.COM
95*12929SMisaki.Miyashita@Oracle.COM if (!doit) {
96*12929SMisaki.Miyashita@Oracle.COM return (0);
97*12929SMisaki.Miyashita@Oracle.COM }
98*12929SMisaki.Miyashita@Oracle.COM
99*12929SMisaki.Miyashita@Oracle.COM /* hash the size of .bss section */
100*12929SMisaki.Miyashita@Oracle.COM if (strcmp(name, ".bss") == 0) {
101*12929SMisaki.Miyashita@Oracle.COM char szstr[32];
102*12929SMisaki.Miyashita@Oracle.COM (void) snprintf(szstr, sizeof (szstr), "%ld", size);
103*12929SMisaki.Miyashita@Oracle.COM SHA1Update(shactx, szstr, strlen(szstr));
104*12929SMisaki.Miyashita@Oracle.COM return (0);
105*12929SMisaki.Miyashita@Oracle.COM }
106*12929SMisaki.Miyashita@Oracle.COM
107*12929SMisaki.Miyashita@Oracle.COM
108*12929SMisaki.Miyashita@Oracle.COM /* hash the contents of the section */
109*12929SMisaki.Miyashita@Oracle.COM if ((buf = FIPS_ALLOC(size)) == NULL) {
110*12929SMisaki.Miyashita@Oracle.COM ERRLOG1("Not enough memory for section %s\n", name);
111*12929SMisaki.Miyashita@Oracle.COM return (-1);
112*12929SMisaki.Miyashita@Oracle.COM }
113*12929SMisaki.Miyashita@Oracle.COM
114*12929SMisaki.Miyashita@Oracle.COM if (FIPS_READ_FILE(file, buf, size, offs) < 0) {
115*12929SMisaki.Miyashita@Oracle.COM FIPS_FREE(buf, size);
116*12929SMisaki.Miyashita@Oracle.COM return (-2);
117*12929SMisaki.Miyashita@Oracle.COM }
118*12929SMisaki.Miyashita@Oracle.COM
119*12929SMisaki.Miyashita@Oracle.COM SHA1Update(shactx, buf, size);
120*12929SMisaki.Miyashita@Oracle.COM
121*12929SMisaki.Miyashita@Oracle.COM FIPS_FREE(buf, size);
122*12929SMisaki.Miyashita@Oracle.COM
123*12929SMisaki.Miyashita@Oracle.COM return (0);
124*12929SMisaki.Miyashita@Oracle.COM }
125*12929SMisaki.Miyashita@Oracle.COM
126*12929SMisaki.Miyashita@Oracle.COM int
127*12929SMisaki.Miyashita@Oracle.COM #ifdef _KERNEL
fips_calc_checksum(struct _buf * file,Elf64_Ehdr * ehdr,char * sha1buf)128*12929SMisaki.Miyashita@Oracle.COM fips_calc_checksum(struct _buf *file, Elf64_Ehdr *ehdr, char *sha1buf)
129*12929SMisaki.Miyashita@Oracle.COM #else
130*12929SMisaki.Miyashita@Oracle.COM fips_calc_checksum(int file, Elf64_Ehdr *ehdr, char *sha1buf)
131*12929SMisaki.Miyashita@Oracle.COM #endif
132*12929SMisaki.Miyashita@Oracle.COM {
133*12929SMisaki.Miyashita@Oracle.COM unsigned int size, numsec;
134*12929SMisaki.Miyashita@Oracle.COM Elf64_Shdr *shdrs;
135*12929SMisaki.Miyashita@Oracle.COM Elf64_Shdr *section;
136*12929SMisaki.Miyashita@Oracle.COM SHA1_CTX sha1ctx;
137*12929SMisaki.Miyashita@Oracle.COM char *shstrtab;
138*12929SMisaki.Miyashita@Oracle.COM int i;
139*12929SMisaki.Miyashita@Oracle.COM
140*12929SMisaki.Miyashita@Oracle.COM numsec = ehdr->e_shnum;
141*12929SMisaki.Miyashita@Oracle.COM size = ehdr->e_shentsize * numsec;
142*12929SMisaki.Miyashita@Oracle.COM if ((shdrs = (Elf64_Shdr *)FIPS_ALLOC(size)) == NULL) {
143*12929SMisaki.Miyashita@Oracle.COM ERRLOG0("Not enough memory for shdrs\n");
144*12929SMisaki.Miyashita@Oracle.COM return (FAILURE);
145*12929SMisaki.Miyashita@Oracle.COM }
146*12929SMisaki.Miyashita@Oracle.COM if (FIPS_READ_FILE(file, (char *)shdrs, size, ehdr->e_shoff) < 0) {
147*12929SMisaki.Miyashita@Oracle.COM return (FAILURE);
148*12929SMisaki.Miyashita@Oracle.COM }
149*12929SMisaki.Miyashita@Oracle.COM
150*12929SMisaki.Miyashita@Oracle.COM /* Obtain the .shstrtab data buffer */
151*12929SMisaki.Miyashita@Oracle.COM section = &(shdrs[ehdr->e_shstrndx]);
152*12929SMisaki.Miyashita@Oracle.COM size = section->sh_size;
153*12929SMisaki.Miyashita@Oracle.COM if ((shstrtab = (char *)FIPS_ALLOC(size)) == NULL) {
154*12929SMisaki.Miyashita@Oracle.COM ERRLOG0("Not enough memory for shstrtab\n");
155*12929SMisaki.Miyashita@Oracle.COM return (FAILURE);
156*12929SMisaki.Miyashita@Oracle.COM }
157*12929SMisaki.Miyashita@Oracle.COM if (FIPS_READ_FILE(file, shstrtab, size, section->sh_offset) < 0) {
158*12929SMisaki.Miyashita@Oracle.COM return (FAILURE);
159*12929SMisaki.Miyashita@Oracle.COM }
160*12929SMisaki.Miyashita@Oracle.COM
161*12929SMisaki.Miyashita@Oracle.COM SHA1Init(&sha1ctx);
162*12929SMisaki.Miyashita@Oracle.COM for (i = 0; i < numsec; i++) {
163*12929SMisaki.Miyashita@Oracle.COM if (process_section(&sha1ctx, &(shdrs[i]),
164*12929SMisaki.Miyashita@Oracle.COM file, shstrtab) < 0) {
165*12929SMisaki.Miyashita@Oracle.COM return (FAILURE);
166*12929SMisaki.Miyashita@Oracle.COM }
167*12929SMisaki.Miyashita@Oracle.COM }
168*12929SMisaki.Miyashita@Oracle.COM SHA1Final(sha1buf, &sha1ctx);
169*12929SMisaki.Miyashita@Oracle.COM
170*12929SMisaki.Miyashita@Oracle.COM return (0);
171*12929SMisaki.Miyashita@Oracle.COM }
172*12929SMisaki.Miyashita@Oracle.COM
173*12929SMisaki.Miyashita@Oracle.COM
174*12929SMisaki.Miyashita@Oracle.COM #ifndef _KERNEL
175*12929SMisaki.Miyashita@Oracle.COM
176*12929SMisaki.Miyashita@Oracle.COM int
fips_read_file(int fd,char * buf,int size,int offs)177*12929SMisaki.Miyashita@Oracle.COM fips_read_file(int fd, char *buf, int size, int offs)
178*12929SMisaki.Miyashita@Oracle.COM {
179*12929SMisaki.Miyashita@Oracle.COM int i;
180*12929SMisaki.Miyashita@Oracle.COM
181*12929SMisaki.Miyashita@Oracle.COM if (lseek(fd, offs, SEEK_SET) == (off_t)(-1)) {
182*12929SMisaki.Miyashita@Oracle.COM (void) fprintf(stderr,
183*12929SMisaki.Miyashita@Oracle.COM "lseek returned an error for file %d\n", fd);
184*12929SMisaki.Miyashita@Oracle.COM return (-1);
185*12929SMisaki.Miyashita@Oracle.COM }
186*12929SMisaki.Miyashita@Oracle.COM while ((i = read(fd, buf, size)) >= 0) {
187*12929SMisaki.Miyashita@Oracle.COM if (size == i) {
188*12929SMisaki.Miyashita@Oracle.COM break;
189*12929SMisaki.Miyashita@Oracle.COM } else {
190*12929SMisaki.Miyashita@Oracle.COM size -= i;
191*12929SMisaki.Miyashita@Oracle.COM buf += i;
192*12929SMisaki.Miyashita@Oracle.COM }
193*12929SMisaki.Miyashita@Oracle.COM }
194*12929SMisaki.Miyashita@Oracle.COM if (i < 0) {
195*12929SMisaki.Miyashita@Oracle.COM (void) fprintf(stderr, "read failed for file %d\n", fd);
196*12929SMisaki.Miyashita@Oracle.COM return (-2);
197*12929SMisaki.Miyashita@Oracle.COM }
198*12929SMisaki.Miyashita@Oracle.COM
199*12929SMisaki.Miyashita@Oracle.COM return (0);
200*12929SMisaki.Miyashita@Oracle.COM }
201*12929SMisaki.Miyashita@Oracle.COM
202*12929SMisaki.Miyashita@Oracle.COM #else
203*12929SMisaki.Miyashita@Oracle.COM
204*12929SMisaki.Miyashita@Oracle.COM static int
get_fips_section(Elf64_Ehdr * ehdr,struct _buf * file,char * expected_checksum)205*12929SMisaki.Miyashita@Oracle.COM get_fips_section(Elf64_Ehdr *ehdr, struct _buf *file, char *expected_checksum)
206*12929SMisaki.Miyashita@Oracle.COM {
207*12929SMisaki.Miyashita@Oracle.COM unsigned int shdrssz, shstrtabsz, numsec;
208*12929SMisaki.Miyashita@Oracle.COM Elf64_Shdr *shdrs = NULL;
209*12929SMisaki.Miyashita@Oracle.COM Elf64_Shdr *section;
210*12929SMisaki.Miyashita@Oracle.COM char *shstrtab = NULL;
211*12929SMisaki.Miyashita@Oracle.COM char *name;
212*12929SMisaki.Miyashita@Oracle.COM int rv = FAILURE;
213*12929SMisaki.Miyashita@Oracle.COM int i;
214*12929SMisaki.Miyashita@Oracle.COM
215*12929SMisaki.Miyashita@Oracle.COM numsec = ehdr->e_shnum;
216*12929SMisaki.Miyashita@Oracle.COM shdrssz = ehdr->e_shentsize * numsec;
217*12929SMisaki.Miyashita@Oracle.COM if ((shdrs = (Elf64_Shdr *)FIPS_ALLOC(shdrssz)) == NULL) {
218*12929SMisaki.Miyashita@Oracle.COM ERRLOG0("Not enough memory for shdrs\n");
219*12929SMisaki.Miyashita@Oracle.COM return (FAILURE);
220*12929SMisaki.Miyashita@Oracle.COM }
221*12929SMisaki.Miyashita@Oracle.COM if (FIPS_READ_FILE(file, (char *)shdrs, shdrssz, ehdr->e_shoff) < 0) {
222*12929SMisaki.Miyashita@Oracle.COM goto exit;
223*12929SMisaki.Miyashita@Oracle.COM }
224*12929SMisaki.Miyashita@Oracle.COM
225*12929SMisaki.Miyashita@Oracle.COM /* Obtain the .shstrtab data buffer */
226*12929SMisaki.Miyashita@Oracle.COM section = &(shdrs[ehdr->e_shstrndx]);
227*12929SMisaki.Miyashita@Oracle.COM shstrtabsz = section->sh_size;
228*12929SMisaki.Miyashita@Oracle.COM if ((shstrtab = (char *)FIPS_ALLOC(shstrtabsz)) == NULL) {
229*12929SMisaki.Miyashita@Oracle.COM ERRLOG0("Not enough memory for shstrtab\n");
230*12929SMisaki.Miyashita@Oracle.COM goto exit;
231*12929SMisaki.Miyashita@Oracle.COM }
232*12929SMisaki.Miyashita@Oracle.COM if (FIPS_READ_FILE(file, shstrtab, shstrtabsz,
233*12929SMisaki.Miyashita@Oracle.COM section->sh_offset) < 0) {
234*12929SMisaki.Miyashita@Oracle.COM goto exit;
235*12929SMisaki.Miyashita@Oracle.COM }
236*12929SMisaki.Miyashita@Oracle.COM
237*12929SMisaki.Miyashita@Oracle.COM for (i = 0; i < numsec; i++) {
238*12929SMisaki.Miyashita@Oracle.COM section = &shdrs[i];
239*12929SMisaki.Miyashita@Oracle.COM name = shstrtab + section->sh_name;
240*12929SMisaki.Miyashita@Oracle.COM /* Get the checksum stored in the .SUNW_fips section */
241*12929SMisaki.Miyashita@Oracle.COM if (strcmp(name, ".SUNW_fips") == 0) {
242*12929SMisaki.Miyashita@Oracle.COM if (section->sh_size != SHA1_DIGEST_LENGTH) {
243*12929SMisaki.Miyashita@Oracle.COM goto exit;
244*12929SMisaki.Miyashita@Oracle.COM }
245*12929SMisaki.Miyashita@Oracle.COM if (FIPS_READ_FILE(file, expected_checksum,
246*12929SMisaki.Miyashita@Oracle.COM section->sh_size, section->sh_offset) < 0) {
247*12929SMisaki.Miyashita@Oracle.COM goto exit;
248*12929SMisaki.Miyashita@Oracle.COM }
249*12929SMisaki.Miyashita@Oracle.COM rv = 0;
250*12929SMisaki.Miyashita@Oracle.COM goto exit;
251*12929SMisaki.Miyashita@Oracle.COM }
252*12929SMisaki.Miyashita@Oracle.COM }
253*12929SMisaki.Miyashita@Oracle.COM
254*12929SMisaki.Miyashita@Oracle.COM
255*12929SMisaki.Miyashita@Oracle.COM exit:
256*12929SMisaki.Miyashita@Oracle.COM if (shdrs != NULL) {
257*12929SMisaki.Miyashita@Oracle.COM FIPS_FREE(shdrs, shdrssz);
258*12929SMisaki.Miyashita@Oracle.COM }
259*12929SMisaki.Miyashita@Oracle.COM if (shstrtab != NULL) {
260*12929SMisaki.Miyashita@Oracle.COM FIPS_FREE(shstrtab, shstrtabsz);
261*12929SMisaki.Miyashita@Oracle.COM }
262*12929SMisaki.Miyashita@Oracle.COM
263*12929SMisaki.Miyashita@Oracle.COM return (rv);
264*12929SMisaki.Miyashita@Oracle.COM }
265*12929SMisaki.Miyashita@Oracle.COM
266*12929SMisaki.Miyashita@Oracle.COM
267*12929SMisaki.Miyashita@Oracle.COM int
fips_check_module(char * modname,void * _initaddr)268*12929SMisaki.Miyashita@Oracle.COM fips_check_module(char *modname, void *_initaddr)
269*12929SMisaki.Miyashita@Oracle.COM {
270*12929SMisaki.Miyashita@Oracle.COM struct modctl *modctlp = NULL;
271*12929SMisaki.Miyashita@Oracle.COM struct module *mp = NULL;
272*12929SMisaki.Miyashita@Oracle.COM struct _buf *file;
273*12929SMisaki.Miyashita@Oracle.COM char *filename;
274*12929SMisaki.Miyashita@Oracle.COM Elf64_Ehdr ehdr;
275*12929SMisaki.Miyashita@Oracle.COM unsigned int size, i;
276*12929SMisaki.Miyashita@Oracle.COM char sha1buf[SHA1_DIGEST_LENGTH];
277*12929SMisaki.Miyashita@Oracle.COM char expected_checksum[SHA1_DIGEST_LENGTH];
278*12929SMisaki.Miyashita@Oracle.COM
279*12929SMisaki.Miyashita@Oracle.COM modctlp = mod_find_by_filename(NULL, modname);
280*12929SMisaki.Miyashita@Oracle.COM if (modctlp == NULL) {
281*12929SMisaki.Miyashita@Oracle.COM ERRLOG1("module with modname %s not found\n", modname);
282*12929SMisaki.Miyashita@Oracle.COM return (FAILURE);
283*12929SMisaki.Miyashita@Oracle.COM }
284*12929SMisaki.Miyashita@Oracle.COM mp = (struct module *)modctlp->mod_mp;
285*12929SMisaki.Miyashita@Oracle.COM if (mp != NULL && mp->filename != NULL) {
286*12929SMisaki.Miyashita@Oracle.COM filename = mp->filename;
287*12929SMisaki.Miyashita@Oracle.COM } else {
288*12929SMisaki.Miyashita@Oracle.COM /* filename does not exist */
289*12929SMisaki.Miyashita@Oracle.COM return (FAILURE);
290*12929SMisaki.Miyashita@Oracle.COM }
291*12929SMisaki.Miyashita@Oracle.COM if ((mp->text > (char *)_initaddr) ||
292*12929SMisaki.Miyashita@Oracle.COM (mp->text + mp->text_size < (char *)_initaddr)) {
293*12929SMisaki.Miyashita@Oracle.COM ERRLOG1("_init() is not in module %s\n", modname);
294*12929SMisaki.Miyashita@Oracle.COM return (FAILURE);
295*12929SMisaki.Miyashita@Oracle.COM }
296*12929SMisaki.Miyashita@Oracle.COM
297*12929SMisaki.Miyashita@Oracle.COM if ((file = kobj_open_file(filename)) == (struct _buf *)-1) {
298*12929SMisaki.Miyashita@Oracle.COM ERRLOG1("Cannot open %s\n", filename);
299*12929SMisaki.Miyashita@Oracle.COM return (FAILURE);
300*12929SMisaki.Miyashita@Oracle.COM }
301*12929SMisaki.Miyashita@Oracle.COM /* Read the ELF header */
302*12929SMisaki.Miyashita@Oracle.COM size = sizeof (ehdr);
303*12929SMisaki.Miyashita@Oracle.COM if (kobj_read_file(file, (char *)(&ehdr), size, 0) < 0) {
304*12929SMisaki.Miyashita@Oracle.COM goto fail_exit;
305*12929SMisaki.Miyashita@Oracle.COM }
306*12929SMisaki.Miyashita@Oracle.COM
307*12929SMisaki.Miyashita@Oracle.COM /* check if it is an ELF file */
308*12929SMisaki.Miyashita@Oracle.COM for (i = 0; i < SELFMAG; i++) {
309*12929SMisaki.Miyashita@Oracle.COM if (ehdr.e_ident[i] != ELFMAG[i]) {
310*12929SMisaki.Miyashita@Oracle.COM ERRLOG1("%s not an elf file\n", filename);
311*12929SMisaki.Miyashita@Oracle.COM goto fail_exit;
312*12929SMisaki.Miyashita@Oracle.COM }
313*12929SMisaki.Miyashita@Oracle.COM }
314*12929SMisaki.Miyashita@Oracle.COM
315*12929SMisaki.Miyashita@Oracle.COM /* check if it is relocatable */
316*12929SMisaki.Miyashita@Oracle.COM if (ehdr.e_type != ET_REL) {
317*12929SMisaki.Miyashita@Oracle.COM ERRLOG1("%s isn't a relocatable (ET_REL) "
318*12929SMisaki.Miyashita@Oracle.COM "module\n", filename);
319*12929SMisaki.Miyashita@Oracle.COM goto fail_exit;
320*12929SMisaki.Miyashita@Oracle.COM }
321*12929SMisaki.Miyashita@Oracle.COM
322*12929SMisaki.Miyashita@Oracle.COM if (fips_calc_checksum(file, &ehdr, sha1buf) < 0) {
323*12929SMisaki.Miyashita@Oracle.COM goto fail_exit;
324*12929SMisaki.Miyashita@Oracle.COM }
325*12929SMisaki.Miyashita@Oracle.COM
326*12929SMisaki.Miyashita@Oracle.COM if (get_fips_section(&ehdr, file, expected_checksum) < 0) {
327*12929SMisaki.Miyashita@Oracle.COM goto fail_exit;
328*12929SMisaki.Miyashita@Oracle.COM }
329*12929SMisaki.Miyashita@Oracle.COM
330*12929SMisaki.Miyashita@Oracle.COM if (memcmp(sha1buf, expected_checksum, SHA1_DIGEST_LENGTH) != 0) {
331*12929SMisaki.Miyashita@Oracle.COM goto fail_exit;
332*12929SMisaki.Miyashita@Oracle.COM }
333*12929SMisaki.Miyashita@Oracle.COM
334*12929SMisaki.Miyashita@Oracle.COM kobj_close_file(file);
335*12929SMisaki.Miyashita@Oracle.COM
336*12929SMisaki.Miyashita@Oracle.COM return (SUCCESS);
337*12929SMisaki.Miyashita@Oracle.COM
338*12929SMisaki.Miyashita@Oracle.COM fail_exit:
339*12929SMisaki.Miyashita@Oracle.COM
340*12929SMisaki.Miyashita@Oracle.COM kobj_close_file(file);
341*12929SMisaki.Miyashita@Oracle.COM
342*12929SMisaki.Miyashita@Oracle.COM return (FAILURE);
343*12929SMisaki.Miyashita@Oracle.COM
344*12929SMisaki.Miyashita@Oracle.COM }
345*12929SMisaki.Miyashita@Oracle.COM
346*12929SMisaki.Miyashita@Oracle.COM #endif
347