1 | /* |
---|
2 | * Binary translate privilege-sensitive ops to privileged |
---|
3 | * |
---|
4 | * Copyright (C) 2004 Hewlett-Packard Co. |
---|
5 | * Dan Magenheimer (dan.magenheimer@hp.com) |
---|
6 | * |
---|
7 | */ |
---|
8 | |
---|
9 | #include <fcntl.h> |
---|
10 | #include <stdio.h> |
---|
11 | #include <stdlib.h> |
---|
12 | #define ELFSIZE 64 |
---|
13 | #include <linux/elf.h> |
---|
14 | |
---|
15 | #define MAX_FILSIZ (32*1024*1024) |
---|
16 | unsigned long buf[MAX_FILSIZ/sizeof(unsigned long)]; |
---|
17 | |
---|
18 | static void |
---|
19 | usage (FILE *fp) |
---|
20 | { |
---|
21 | fprintf(fp, "Usage: privify elf64filein elf64fileout\n"); |
---|
22 | } |
---|
23 | |
---|
24 | static void |
---|
25 | panic (char *s) |
---|
26 | { |
---|
27 | fprintf(stderr, "panic: %s\n",s); |
---|
28 | exit(1); |
---|
29 | } |
---|
30 | |
---|
31 | static int |
---|
32 | read_file(const char *in_path, char *buf, int maxsize) |
---|
33 | { |
---|
34 | ssize_t nread, totread = 0, ssize_inc = 8192; |
---|
35 | int from; |
---|
36 | |
---|
37 | if ((from = open (in_path, O_RDONLY)) < 0) return -1; |
---|
38 | maxsize -= ssize_inc; // create safety zone |
---|
39 | if (maxsize < 0) panic("input file exceeds max size"); |
---|
40 | while ((nread = read(from, buf, ssize_inc)) > 0) { |
---|
41 | if (nread < 0) return -1; // problem |
---|
42 | totread += nread; |
---|
43 | if (nread < ssize_inc) return totread; // done |
---|
44 | buf += ssize_inc; |
---|
45 | if (totread > maxsize) // buffer too small |
---|
46 | panic("file exceeds max size\n"); |
---|
47 | } |
---|
48 | return totread; |
---|
49 | } |
---|
50 | |
---|
51 | static int |
---|
52 | write_file(const char *out_path, char *buf, int size) |
---|
53 | { |
---|
54 | int to; |
---|
55 | |
---|
56 | if ((to = open(out_path, O_WRONLY|O_CREAT|O_EXCL,0644)) < 0) |
---|
57 | return -1; |
---|
58 | |
---|
59 | if (write(to,buf,size) < 0) return -1; |
---|
60 | |
---|
61 | return 0; |
---|
62 | } |
---|
63 | |
---|
64 | #define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ |
---|
65 | (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ |
---|
66 | (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ |
---|
67 | (ehdr).e_ident[EI_MAG3] == ELFMAG3) |
---|
68 | |
---|
69 | |
---|
70 | static void |
---|
71 | privify_elf(char *elfbase) |
---|
72 | { |
---|
73 | Elf64_Ehdr *ehdr = (Elf64_Ehdr *)elfbase; |
---|
74 | Elf64_Phdr *phdr; |
---|
75 | Elf64_Shdr *shdr; |
---|
76 | char *elfaddr; |
---|
77 | unsigned long size; |
---|
78 | int h; |
---|
79 | |
---|
80 | if ( !IS_ELF(*ehdr) ) |
---|
81 | panic("Kernel image does not have an ELF header.\n"); |
---|
82 | for ( h = 0; h < ehdr->e_phnum; h++ ) { |
---|
83 | phdr = (Elf64_Phdr *)(elfbase + |
---|
84 | ehdr->e_phoff + (h*ehdr->e_phentsize)); |
---|
85 | printf("h=%d, phdr=%p,phdr->p_type=%lx",h,phdr,phdr->p_type); |
---|
86 | if ((phdr->p_type != PT_LOAD)) { |
---|
87 | printf("\n"); |
---|
88 | continue; |
---|
89 | } |
---|
90 | size = phdr->p_filesz; |
---|
91 | elfaddr = elfbase + phdr->p_offset; |
---|
92 | printf(",elfaddr=%p,size=%d,phdr->p_flags=%lx\n", |
---|
93 | elfaddr,size,phdr->p_flags); |
---|
94 | if (phdr->p_flags & PF_X) privify_memory(elfaddr,size); |
---|
95 | } |
---|
96 | } |
---|
97 | |
---|
98 | int |
---|
99 | main(int argc, char **argv) |
---|
100 | { |
---|
101 | char *in_path, *out_path; |
---|
102 | int fsize; |
---|
103 | |
---|
104 | if (argc != 3) { |
---|
105 | usage(stdout); |
---|
106 | exit(1); |
---|
107 | } |
---|
108 | in_path = argv[1]; |
---|
109 | out_path = argv[2]; |
---|
110 | if ((fsize = read_file(in_path,(char *)buf,MAX_FILSIZ)) < 0) { |
---|
111 | perror("read_file"); |
---|
112 | panic("failed"); |
---|
113 | } |
---|
114 | privify_elf((char *)buf); |
---|
115 | fflush(stdout); |
---|
116 | if (write_file(out_path,(char *)buf,fsize) < 0) { |
---|
117 | perror("write_file"); |
---|
118 | panic("failed"); |
---|
119 | } |
---|
120 | } |
---|