~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/insert-sys-cert.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/insert-sys-cert.c (Version linux-6.12-rc7) and /scripts/insert-sys-cert.c (Version ccs-tools-1.8.12)


  1 /* Write the contents of the <certfile> into k      1 
  2  *                                                
  3  * Copyright (C) IBM Corporation, 2015            
  4  *                                                
  5  * Author: Mehmet Kayaalp <mkayaalp@linux.vnet    
  6  *                                                
  7  * This software may be used and distributed a    
  8  * of the GNU General Public License, incorpor    
  9  *                                                
 10  * Usage: insert-sys-cert [-s <System.map> -b     
 11  */                                               
 12                                                   
 13 #define _GNU_SOURCE                               
 14 #include <stdio.h>                                
 15 #include <ctype.h>                                
 16 #include <string.h>                               
 17 #include <limits.h>                               
 18 #include <stdbool.h>                              
 19 #include <errno.h>                                
 20 #include <stdlib.h>                               
 21 #include <stdarg.h>                               
 22 #include <sys/types.h>                            
 23 #include <sys/stat.h>                             
 24 #include <sys/mman.h>                             
 25 #include <fcntl.h>                                
 26 #include <unistd.h>                               
 27 #include <elf.h>                                  
 28                                                   
 29 #define CERT_SYM  "system_extra_cert"             
 30 #define USED_SYM  "system_extra_cert_used"        
 31 #define LSIZE_SYM "system_certificate_list_siz    
 32                                                   
 33 #define info(format, args...) fprintf(stderr,     
 34 #define warn(format, args...) fprintf(stdout,     
 35 #define  err(format, args...) fprintf(stderr,     
 36                                                   
 37 #if UINTPTR_MAX == 0xffffffff                     
 38 #define CURRENT_ELFCLASS ELFCLASS32               
 39 #define Elf_Ehdr        Elf32_Ehdr                
 40 #define Elf_Shdr        Elf32_Shdr                
 41 #define Elf_Sym         Elf32_Sym                 
 42 #else                                             
 43 #define CURRENT_ELFCLASS ELFCLASS64               
 44 #define Elf_Ehdr        Elf64_Ehdr                
 45 #define Elf_Shdr        Elf64_Shdr                
 46 #define Elf_Sym         Elf64_Sym                 
 47 #endif                                            
 48                                                   
 49 static unsigned char endianness(void)             
 50 {                                                 
 51         uint16_t two_byte = 0x00FF;               
 52         uint8_t low_address = *((uint8_t *)&tw    
 53                                                   
 54         if (low_address == 0)                     
 55                 return ELFDATA2MSB;               
 56         else                                      
 57                 return ELFDATA2LSB;               
 58 }                                                 
 59                                                   
 60 struct sym {                                      
 61         char *name;                               
 62         unsigned long address;                    
 63         unsigned long offset;                     
 64         void *content;                            
 65         int size;                                 
 66 };                                                
 67                                                   
 68 static unsigned long get_offset_from_address(E    
 69 {                                                 
 70         Elf_Shdr *x;                              
 71         unsigned int i, num_sections;             
 72                                                   
 73         x = (void *)hdr + hdr->e_shoff;           
 74         if (hdr->e_shnum == SHN_UNDEF)            
 75                 num_sections = x[0].sh_size;      
 76         else                                      
 77                 num_sections = hdr->e_shnum;      
 78                                                   
 79         for (i = 1; i < num_sections; i++) {      
 80                 unsigned long start = x[i].sh_    
 81                 unsigned long end = start + x[    
 82                 unsigned long offset = x[i].sh    
 83                                                   
 84                 if (addr >= start && addr <= e    
 85                         return addr - start +     
 86         }                                         
 87         return 0;                                 
 88 }                                                 
 89                                                   
 90                                                   
 91 #define LINE_SIZE 100                             
 92                                                   
 93 static void get_symbol_from_map(Elf_Ehdr *hdr,    
 94                                 struct sym *s)    
 95 {                                                 
 96         char l[LINE_SIZE];                        
 97         char *w, *p, *n;                          
 98                                                   
 99         s->size = 0;                              
100         s->address = 0;                           
101         s->offset = 0;                            
102         if (fseek(f, 0, SEEK_SET) != 0) {         
103                 perror("File seek failed");       
104                 exit(EXIT_FAILURE);               
105         }                                         
106         while (fgets(l, LINE_SIZE, f)) {          
107                 p = strchr(l, '\n');              
108                 if (!p) {                         
109                         err("Missing line endi    
110                         return;                   
111                 }                                 
112                 n = strstr(l, name);              
113                 if (n)                            
114                         break;                    
115         }                                         
116         if (!n) {                                 
117                 err("Unable to find symbol: %s    
118                 return;                           
119         }                                         
120         w = strchr(l, ' ');                       
121         if (!w)                                   
122                 return;                           
123                                                   
124         *w = '\0';                                
125         s->address = strtoul(l, NULL, 16);        
126         if (s->address == 0)                      
127                 return;                           
128         s->offset = get_offset_from_address(hd    
129         s->name = name;                           
130         s->content = (void *)hdr + s->offset;     
131 }                                                 
132                                                   
133 static Elf_Sym *find_elf_symbol(Elf_Ehdr *hdr,    
134 {                                                 
135         Elf_Sym *sym, *symtab_start;              
136         char *strtab, *symname;                   
137         unsigned int link;                        
138         Elf_Shdr *x;                              
139         int i, n;                                 
140                                                   
141         x = (void *)hdr + hdr->e_shoff;           
142         link = symtab->sh_link;                   
143         symtab_start = (void *)hdr + symtab->s    
144         n = symtab->sh_size / symtab->sh_entsi    
145         strtab = (void *)hdr + x[link].sh_offs    
146                                                   
147         for (i = 0; i < n; i++) {                 
148                 sym = &symtab_start[i];           
149                 symname = strtab + sym->st_nam    
150                 if (strcmp(symname, name) == 0    
151                         return sym;               
152         }                                         
153         err("Unable to find symbol: %s\n", nam    
154         return NULL;                              
155 }                                                 
156                                                   
157 static void get_symbol_from_table(Elf_Ehdr *hd    
158                                   char *name,     
159 {                                                 
160         Elf_Shdr *sec;                            
161         int secndx;                               
162         Elf_Sym *elf_sym;                         
163         Elf_Shdr *x;                              
164                                                   
165         x = (void *)hdr + hdr->e_shoff;           
166         s->size = 0;                              
167         s->address = 0;                           
168         s->offset = 0;                            
169         elf_sym = find_elf_symbol(hdr, symtab,    
170         if (!elf_sym)                             
171                 return;                           
172         secndx = elf_sym->st_shndx;               
173         if (!secndx)                              
174                 return;                           
175         sec = &x[secndx];                         
176         s->size = elf_sym->st_size;               
177         s->address = elf_sym->st_value;           
178         s->offset = s->address - sec->sh_addr     
179                                + sec->sh_offse    
180         s->name = name;                           
181         s->content = (void *)hdr + s->offset;     
182 }                                                 
183                                                   
184 static Elf_Shdr *get_symbol_table(Elf_Ehdr *hd    
185 {                                                 
186         Elf_Shdr *x;                              
187         unsigned int i, num_sections;             
188                                                   
189         x = (void *)hdr + hdr->e_shoff;           
190         if (hdr->e_shnum == SHN_UNDEF)            
191                 num_sections = x[0].sh_size;      
192         else                                      
193                 num_sections = hdr->e_shnum;      
194                                                   
195         for (i = 1; i < num_sections; i++)        
196                 if (x[i].sh_type == SHT_SYMTAB    
197                         return &x[i];             
198         return NULL;                              
199 }                                                 
200                                                   
201 static void *map_file(char *file_name, int *si    
202 {                                                 
203         struct stat st;                           
204         void *map;                                
205         int fd;                                   
206                                                   
207         fd = open(file_name, O_RDWR);             
208         if (fd < 0) {                             
209                 perror(file_name);                
210                 return NULL;                      
211         }                                         
212         if (fstat(fd, &st)) {                     
213                 perror("Could not determine fi    
214                 close(fd);                        
215                 return NULL;                      
216         }                                         
217         *size = st.st_size;                       
218         map = mmap(NULL, *size, PROT_READ|PROT    
219         if (map == MAP_FAILED) {                  
220                 perror("Mapping to memory fail    
221                 close(fd);                        
222                 return NULL;                      
223         }                                         
224         close(fd);                                
225         return map;                               
226 }                                                 
227                                                   
228 static char *read_file(char *file_name, int *s    
229 {                                                 
230         struct stat st;                           
231         char *buf;                                
232         int fd;                                   
233                                                   
234         fd = open(file_name, O_RDONLY);           
235         if (fd < 0) {                             
236                 perror(file_name);                
237                 return NULL;                      
238         }                                         
239         if (fstat(fd, &st)) {                     
240                 perror("Could not determine fi    
241                 close(fd);                        
242                 return NULL;                      
243         }                                         
244         *size = st.st_size;                       
245         buf = malloc(*size);                      
246         if (!buf) {                               
247                 perror("Allocating memory fail    
248                 close(fd);                        
249                 return NULL;                      
250         }                                         
251         if (read(fd, buf, *size) != *size) {      
252                 perror("File read failed");       
253                 close(fd);                        
254                 return NULL;                      
255         }                                         
256         close(fd);                                
257         return buf;                               
258 }                                                 
259                                                   
260 static void print_sym(Elf_Ehdr *hdr, struct sy    
261 {                                                 
262         info("sym:    %s\n", s->name);            
263         info("addr:   0x%lx\n", s->address);      
264         info("size:   %d\n", s->size);            
265         info("offset: 0x%lx\n", (unsigned long    
266 }                                                 
267                                                   
268 static void print_usage(char *e)                  
269 {                                                 
270         printf("Usage %s [-s <System.map>] -b     
271 }                                                 
272                                                   
273 int main(int argc, char **argv)                   
274 {                                                 
275         char *system_map_file = NULL;             
276         char *vmlinux_file = NULL;                
277         char *cert_file = NULL;                   
278         int vmlinux_size;                         
279         int cert_size;                            
280         Elf_Ehdr *hdr;                            
281         char *cert;                               
282         FILE *system_map;                         
283         unsigned long *lsize;                     
284         int *used;                                
285         int opt;                                  
286         Elf_Shdr *symtab = NULL;                  
287         struct sym cert_sym, lsize_sym, used_s    
288                                                   
289         while ((opt = getopt(argc, argv, "b:c:    
290                 switch (opt) {                    
291                 case 's':                         
292                         system_map_file = opta    
293                         break;                    
294                 case 'b':                         
295                         vmlinux_file = optarg;    
296                         break;                    
297                 case 'c':                         
298                         cert_file = optarg;       
299                         break;                    
300                 default:                          
301                         break;                    
302                 }                                 
303         }                                         
304                                                   
305         if (!vmlinux_file || !cert_file) {        
306                 print_usage(argv[0]);             
307                 exit(EXIT_FAILURE);               
308         }                                         
309                                                   
310         cert = read_file(cert_file, &cert_size    
311         if (!cert)                                
312                 exit(EXIT_FAILURE);               
313                                                   
314         hdr = map_file(vmlinux_file, &vmlinux_    
315         if (!hdr)                                 
316                 exit(EXIT_FAILURE);               
317                                                   
318         if (vmlinux_size < sizeof(*hdr)) {        
319                 err("Invalid ELF file.\n");       
320                 exit(EXIT_FAILURE);               
321         }                                         
322                                                   
323         if ((hdr->e_ident[EI_MAG0] != ELFMAG0)    
324             (hdr->e_ident[EI_MAG1] != ELFMAG1)    
325             (hdr->e_ident[EI_MAG2] != ELFMAG2)    
326             (hdr->e_ident[EI_MAG3] != ELFMAG3)    
327                 err("Invalid ELF magic.\n");      
328                 exit(EXIT_FAILURE);               
329         }                                         
330                                                   
331         if (hdr->e_ident[EI_CLASS] != CURRENT_    
332                 err("ELF class mismatch.\n");     
333                 exit(EXIT_FAILURE);               
334         }                                         
335                                                   
336         if (hdr->e_ident[EI_DATA] != endiannes    
337                 err("ELF endian mismatch.\n");    
338                 exit(EXIT_FAILURE);               
339         }                                         
340                                                   
341         if (hdr->e_shoff > vmlinux_size) {        
342                 err("Could not find section he    
343                 exit(EXIT_FAILURE);               
344         }                                         
345                                                   
346         symtab = get_symbol_table(hdr);           
347         if (!symtab) {                            
348                 warn("Could not find the symbo    
349                 if (!system_map_file) {           
350                         err("Please provide a     
351                         print_usage(argv[0]);     
352                         exit(EXIT_FAILURE);       
353                 }                                 
354                                                   
355                 system_map = fopen(system_map_    
356                 if (!system_map) {                
357                         perror(system_map_file    
358                         exit(EXIT_FAILURE);       
359                 }                                 
360                 get_symbol_from_map(hdr, syste    
361                 get_symbol_from_map(hdr, syste    
362                 get_symbol_from_map(hdr, syste    
363                 cert_sym.size = used_sym.addre    
364         } else {                                  
365                 info("Symbol table found.\n");    
366                 if (system_map_file)              
367                         warn("System.map is ig    
368                 get_symbol_from_table(hdr, sym    
369                 get_symbol_from_table(hdr, sym    
370                 get_symbol_from_table(hdr, sym    
371         }                                         
372                                                   
373         if (!cert_sym.offset || !lsize_sym.off    
374                 exit(EXIT_FAILURE);               
375                                                   
376         print_sym(hdr, &cert_sym);                
377         print_sym(hdr, &used_sym);                
378         print_sym(hdr, &lsize_sym);               
379                                                   
380         lsize = (unsigned long *)lsize_sym.con    
381         used = (int *)used_sym.content;           
382                                                   
383         if (cert_sym.size < cert_size) {          
384                 err("Certificate is larger tha    
385                 exit(EXIT_FAILURE);               
386         }                                         
387                                                   
388         /* If the existing cert is the same, d    
389         if (cert_size == *used &&                 
390             strncmp(cert_sym.content, cert, ce    
391                 warn("Certificate was already     
392                 exit(EXIT_SUCCESS);               
393         }                                         
394                                                   
395         if (*used > 0)                            
396                 warn("Replacing previously ins    
397                                                   
398         memcpy(cert_sym.content, cert, cert_si    
399         if (cert_size < cert_sym.size)            
400                 memset(cert_sym.content + cert    
401                         0, cert_sym.size - cer    
402                                                   
403         *lsize = *lsize + cert_size - *used;      
404         *used = cert_size;                        
405         info("Inserted the contents of %s into    
406                                                   
407         info("Used %d bytes out of %d bytes re    
408                                                   
409         exit(EXIT_SUCCESS);                       
410 }                                                 
411                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php