Added
Link Here
|
1 |
--- grub-core/loader/i386/bsdXX.c.orig 2015-08-31 22:42:56 UTC |
2 |
+++ grub-core/loader/i386/bsdXX.c |
3 |
@@ -521,17 +521,68 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file, |
4 |
struct grub_openbsd_ramdisk_descriptor *desc) |
5 |
{ |
6 |
unsigned symoff, stroff, symsize, strsize, symentsize; |
7 |
+ Elf_Shdr *rodata; |
8 |
+ char *shdr = NULL; |
9 |
|
10 |
{ |
11 |
grub_err_t err; |
12 |
Elf_Ehdr e; |
13 |
- Elf_Shdr *s; |
14 |
- char *shdr = NULL; |
15 |
+ Elf_Shdr *s, *strtab; |
16 |
+ char *strarr; |
17 |
|
18 |
err = read_headers (file, filename, &e, &shdr); |
19 |
if (err) |
20 |
return err; |
21 |
|
22 |
+ for (s = (Elf_Shdr *) shdr; |
23 |
+ s < (Elf_Shdr *) (shdr + e.e_shnum * e.e_shentsize); |
24 |
+ s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) |
25 |
+ if (s->sh_type == SHT_STRTAB) |
26 |
+ break; |
27 |
+ if (s >= (Elf_Shdr *) ((char *) shdr + e.e_shnum * e.e_shentsize)) |
28 |
+ { |
29 |
+ grub_free (shdr); |
30 |
+ return GRUB_ERR_NONE; |
31 |
+ } |
32 |
+ strtab = s; |
33 |
+ |
34 |
+ strarr = grub_malloc (strtab->sh_size); |
35 |
+ if (!strarr) |
36 |
+ { |
37 |
+ grub_free (shdr); |
38 |
+ return grub_errno; |
39 |
+ } |
40 |
+ |
41 |
+ if (grub_file_seek (file, strtab->sh_offset) == (grub_off_t) -1) |
42 |
+ { |
43 |
+ grub_free (strarr); |
44 |
+ grub_free (shdr); |
45 |
+ return grub_errno; |
46 |
+ } |
47 |
+ if (grub_file_read (file, strarr, strtab->sh_size) != (grub_ssize_t) strtab->sh_size) |
48 |
+ { |
49 |
+ grub_free (strarr); |
50 |
+ grub_free (shdr); |
51 |
+ if (! grub_errno) |
52 |
+ return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), |
53 |
+ filename); |
54 |
+ return grub_errno; |
55 |
+ } |
56 |
+ |
57 |
+ for (s = (Elf_Shdr *) shdr; |
58 |
+ s < (Elf_Shdr *) (shdr + e.e_shnum * e.e_shentsize); |
59 |
+ s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) |
60 |
+ if (s->sh_type == SHT_PROGBITS && |
61 |
+ grub_strcmp(&strarr[s->sh_name], ".rodata") == 0) |
62 |
+ break; |
63 |
+ grub_free (strarr); |
64 |
+ if (s >= (Elf_Shdr *) ((char *) shdr + e.e_shnum * e.e_shentsize)) |
65 |
+ { |
66 |
+ grub_free (shdr); |
67 |
+ return GRUB_ERR_NONE; |
68 |
+ } |
69 |
+ rodata = s; |
70 |
+ |
71 |
for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr |
72 |
+ e.e_shnum * e.e_shentsize); |
73 |
s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) |
74 |
@@ -550,24 +601,26 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file, |
75 |
s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link); |
76 |
stroff = s->sh_offset; |
77 |
strsize = s->sh_size; |
78 |
- grub_free (shdr); |
79 |
} |
80 |
{ |
81 |
- Elf_Sym *syms, *sym, *imagesym = NULL, *sizesym = NULL; |
82 |
+ Elf_Sym *syms, *sym, *imagesym = NULL, *sizesym = NULL, *osrelsym = NULL; |
83 |
unsigned i; |
84 |
char *strs; |
85 |
|
86 |
syms = grub_malloc (symsize); |
87 |
- if (!syms) |
88 |
+ if (!syms) { |
89 |
+ grub_free (shdr); |
90 |
return grub_errno; |
91 |
- |
92 |
+ } |
93 |
if (grub_file_seek (file, symoff) == (grub_off_t) -1) |
94 |
{ |
95 |
+ grub_free (shdr); |
96 |
grub_free (syms); |
97 |
return grub_errno; |
98 |
} |
99 |
if (grub_file_read (file, syms, symsize) != (grub_ssize_t) symsize) |
100 |
{ |
101 |
+ grub_free (shdr); |
102 |
grub_free (syms); |
103 |
if (! grub_errno) |
104 |
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), |
105 |
@@ -578,6 +631,7 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file, |
106 |
strs = grub_malloc (strsize); |
107 |
if (!strs) |
108 |
{ |
109 |
+ grub_free (shdr); |
110 |
grub_free (syms); |
111 |
return grub_errno; |
112 |
} |
113 |
@@ -586,6 +640,7 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file, |
114 |
return grub_errno; |
115 |
if (grub_file_read (file, strs, strsize) != (grub_ssize_t) strsize) |
116 |
{ |
117 |
+ grub_free (shdr); |
118 |
grub_free (syms); |
119 |
grub_free (strs); |
120 |
if (! grub_errno) |
121 |
@@ -605,9 +660,48 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file, |
122 |
imagesym = sym; |
123 |
if (grub_strcmp (strs + sym->st_name, "rd_root_size") == 0) |
124 |
sizesym = sym; |
125 |
- if (imagesym && sizesym) |
126 |
+ if (grub_strcmp (strs + sym->st_name, "osrelease") == 0) |
127 |
+ osrelsym = sym; |
128 |
+ if (imagesym && sizesym && osrelsym) |
129 |
break; |
130 |
} |
131 |
+ if (osrelsym) { |
132 |
+ char *p; |
133 |
+ int major, minor; |
134 |
+ grub_size_t sz; |
135 |
+ char osrel[16]; |
136 |
+ stroff = ((osrelsym->st_value - rodata->sh_addr) + rodata->sh_offset); |
137 |
+ if (grub_file_seek (file, stroff) == (grub_off_t) -1) { |
138 |
+ grub_free (shdr); |
139 |
+ grub_free (syms); |
140 |
+ grub_free (strs); |
141 |
+ return grub_errno; |
142 |
+ } |
143 |
+ sz = sizeof(osrel) < osrelsym->st_size ? sizeof(osrel) : osrelsym->st_size; |
144 |
+ if (grub_file_read (file, osrel, sz) != (grub_ssize_t) sz) { |
145 |
+ grub_free (shdr); |
146 |
+ grub_free (syms); |
147 |
+ grub_free (strs); |
148 |
+ return grub_errno; |
149 |
+ } |
150 |
+ osrel[sz - 1] = '\0'; |
151 |
+ major = minor = 0; |
152 |
+ for (p = osrel; *p != '\0'; p++) |
153 |
+ if (*p >= '0' && *p <= '9') |
154 |
+ major = major * 10 + *p - '0'; |
155 |
+ else |
156 |
+ break; |
157 |
+ if (*p == '.') |
158 |
+ p++; |
159 |
+ for (; *p != '\0'; p++) |
160 |
+ if (*p >= '0' && *p <= '9') |
161 |
+ minor = minor * 10 + *p - '0'; |
162 |
+ else |
163 |
+ break; |
164 |
+ desc->osrelease = major * 1000 + minor; |
165 |
+ grub_free (shdr); |
166 |
+ } |
167 |
+ |
168 |
if (!imagesym || !sizesym) |
169 |
{ |
170 |
grub_free (syms); |