@@ -113,34 +113,40 @@ static bool find_efi_binary(const char *const *candidates, size_t candidate_coun
113113
114114#define EFI_GLOBAL_VAR_GUID "8be4df61-93ca-11d2-aa0d-00e098032b8c"
115115
116- /* resolve the shim the firmware actually boots via BootCurrent, not a readdir guess */
117- static bool find_booted_shim (char * path_out , size_t path_out_size ) {
116+ typedef enum {
117+ SHIM_RESOLUTION_FOUND = 0 ,
118+ SHIM_RESOLUTION_FALLBACK_ALLOWED ,
119+ SHIM_RESOLUTION_BOOTED_NON_SHIM ,
120+ SHIM_RESOLUTION_BOOTCURRENT_UNRESOLVED ,
121+ } shim_resolution_t ;
122+
123+ static shim_resolution_t find_booted_shim (char * path_out , size_t path_out_size ) {
118124 unsigned char cur [8 ];
119125 size_t cur_len = 0 ;
120126 if (!bythos_read_file_binary (
121127 "/sys/firmware/efi/efivars/BootCurrent-" EFI_GLOBAL_VAR_GUID ,
122128 cur , sizeof (cur ), & cur_len ) || cur_len < 6 ) {
123- return false ;
129+ return SHIM_RESOLUTION_FALLBACK_ALLOWED ;
124130 }
125131 unsigned int num = (unsigned int )cur [4 ] | ((unsigned int )cur [5 ] << 8 );
126132
127133 char var_path [PATH_MAX ];
128134 if (snprintf (var_path , sizeof (var_path ),
129135 "/sys/firmware/efi/efivars/Boot%04X-" EFI_GLOBAL_VAR_GUID , num )
130136 >= (int )sizeof (var_path )) {
131- return false ;
137+ return SHIM_RESOLUTION_BOOTCURRENT_UNRESOLVED ;
132138 }
133139
134140 unsigned char buf [4096 ];
135141 size_t buf_len = 0 ;
136142 if (!bythos_read_file_binary (var_path , buf , sizeof (buf ), & buf_len )) {
137- return false ;
143+ return SHIM_RESOLUTION_BOOTCURRENT_UNRESOLVED ;
138144 }
139145
140146 bythos_efi_boot_entry_t entry ;
141147 if (!bythos_parse_efi_boot_entry (buf , buf_len , (uint16_t )num , & entry ) ||
142148 entry .filepath [0 ] == '\0' ) {
143- return false ;
149+ return SHIM_RESOLUTION_BOOTCURRENT_UNRESOLVED ;
144150 }
145151
146152 char norm [256 ];
@@ -155,33 +161,50 @@ static bool find_booted_shim(char *path_out, size_t path_out_size) {
155161
156162 if (strstr (norm_lower , "shimx64.efi" ) == NULL &&
157163 strstr (norm_lower , "shimaa64.efi" ) == NULL ) {
158- return false ;
164+ return SHIM_RESOLUTION_BOOTED_NON_SHIM ;
159165 }
160166
161167 const char * efi = strstr (norm_lower , "/efi/" );
162168 if (efi == NULL ) {
163- return false ;
169+ return SHIM_RESOLUTION_BOOTCURRENT_UNRESOLVED ;
164170 }
165171 size_t rel_off = (size_t )(efi - norm_lower ) + 5 ;
166172 if (rel_off >= k ) {
167- return false ;
173+ return SHIM_RESOLUTION_BOOTCURRENT_UNRESOLVED ;
168174 }
169175
170176 if (snprintf (path_out , path_out_size , "%s/%s" ,
171177 bythos_esp_efi_base (), norm + rel_off ) >= (int )path_out_size ) {
172- return false ;
178+ return SHIM_RESOLUTION_BOOTCURRENT_UNRESOLVED ;
173179 }
174- return bythos_file_exists (path_out );
180+ return bythos_file_exists (path_out ) ? SHIM_RESOLUTION_FOUND :
181+ SHIM_RESOLUTION_BOOTCURRENT_UNRESOLVED ;
175182}
176183
177- static bool find_shim (char * path_out , size_t path_out_size ) {
178- if (find_booted_shim (path_out , path_out_size )) {
184+ static bool find_shim (char * path_out , size_t path_out_size ,
185+ shim_resolution_t * resolution_out ) {
186+ shim_resolution_t resolution = find_booted_shim (path_out , path_out_size );
187+ if (resolution == SHIM_RESOLUTION_FOUND ) {
188+ if (resolution_out != NULL ) {
189+ * resolution_out = resolution ;
190+ }
179191 return true;
180192 }
193+ if (resolution != SHIM_RESOLUTION_FALLBACK_ALLOWED ) {
194+ if (resolution_out != NULL ) {
195+ * resolution_out = resolution ;
196+ }
197+ return false;
198+ }
181199 static const char * const candidates [] = {"shimx64.efi" , "shimaa64.efi" };
182- return find_efi_binary (candidates ,
183- sizeof (candidates ) / sizeof (candidates [0 ]),
184- path_out , path_out_size );
200+ bool found = find_efi_binary (candidates ,
201+ sizeof (candidates ) / sizeof (candidates [0 ]),
202+ path_out , path_out_size );
203+ if (resolution_out != NULL ) {
204+ * resolution_out = found ? SHIM_RESOLUTION_FOUND :
205+ SHIM_RESOLUTION_FALLBACK_ALLOWED ;
206+ }
207+ return found ;
185208}
186209
187210static bool find_grub (char * path_out , size_t path_out_size ) {
@@ -198,8 +221,15 @@ static size_t check_shim_signature(check_result_t *results, size_t max_results)
198221 }
199222
200223 char shim_path [PATH_MAX ] = {0 };
201- if (!find_shim (shim_path , sizeof (shim_path ))) {
202- EMIT_SKIP_SUBJECT ("shim signature" , "shim" );
224+ shim_resolution_t shim_resolution = SHIM_RESOLUTION_FALLBACK_ALLOWED ;
225+ if (!find_shim (shim_path , sizeof (shim_path ), & shim_resolution )) {
226+ if (shim_resolution == SHIM_RESOLUTION_BOOTED_NON_SHIM ) {
227+ EMIT_SKIP ("shim signature" , SKIP_SUBJECT_ABSENT , "booted via non-shim path" );
228+ } else if (shim_resolution == SHIM_RESOLUTION_BOOTCURRENT_UNRESOLVED ) {
229+ EMIT_SKIP ("shim signature" , SKIP_OUTPUT_UNPARSEABLE , "BootCurrent path unresolved" );
230+ } else {
231+ EMIT_SKIP_SUBJECT ("shim signature" , "shim" );
232+ }
203233 return used ;
204234 }
205235
@@ -249,7 +279,7 @@ static void scan_initramfs_dir(const char *dir_path, int max_depth,
249279 }
250280
251281 struct stat st ;
252- if (stat (path , & st ) != 0 ) continue ;
282+ if (lstat (path , & st ) != 0 ) continue ;
253283
254284 if (S_ISREG (st .st_mode )) {
255285 if (strncmp (name , "initrd" , 6 ) != 0 && strncmp (name , "initramfs" , 9 ) != 0 ) {
@@ -353,7 +383,7 @@ static size_t check_bootloader_sbat(check_result_t *results, size_t max_results)
353383
354384 char shim_path [PATH_MAX ] = {0 };
355385 char grub_path [PATH_MAX ] = {0 };
356- bool have_shim = find_shim (shim_path , sizeof (shim_path ));
386+ bool have_shim = find_shim (shim_path , sizeof (shim_path ), NULL );
357387 bool have_grub = find_grub (grub_path , sizeof (grub_path ));
358388
359389 if (!have_shim && !have_grub ) {
0 commit comments