mirror of
https://git.proxmox.com/git/efi-boot-shim
synced 2025-06-30 16:01:05 +00:00

Currently, all three invocations of the translate_slashes() function may lead to writes to the string literal that is #defined with the DEFAULT_LOADER_CHAR macro. According to ISO C99 6.4.5p6, this is undefined behavior ("If the program attempts to modify such an array, the behavior is undefined"). This bug crashes shim on e.g. the 64-bit ArmVirtQemu platform ("Data abort: Permission fault"), where the platform firmware maps the .text section (which contains the string literal) read-only. Modify translate_slashes() so that it copies and translates characters from an input array of "char" to an output array of "CHAR8". While at it, fix another bug. Before this patch, if translate_slashes() ever encountered a double backslash (translating it to a single forward slash), then the output would end up shorter than the input. However, the output was not NUL-terminated in-place, therefore the original string length (and according trailing garbage) would be preserved. After this patch, the NUL-termination on contraction is automatic, as the output array's contents are indeterminate when entering the function, and so we must NUL-terminate it anyway. Fixes:8e9124227d
Fixes:e62b69a5b0
Fixes:3d79bcb265
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1795654 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Upstream-commit-id: 9813e8bc8b3
68 lines
1.1 KiB
C
68 lines
1.1 KiB
C
#ifndef SHIM_STR_H
|
|
#define SHIM_STR_H
|
|
|
|
static inline
|
|
__attribute__((unused))
|
|
unsigned long strnlena(const CHAR8 *s, unsigned long n)
|
|
{
|
|
unsigned long i;
|
|
for (i = 0; i <= n; i++)
|
|
if (s[i] == '\0')
|
|
break;
|
|
return i;
|
|
}
|
|
|
|
static inline
|
|
__attribute__((unused))
|
|
CHAR8 *
|
|
strncpya(CHAR8 *dest, const CHAR8 *src, unsigned long n)
|
|
{
|
|
unsigned long i;
|
|
|
|
for (i = 0; i < n && src[i] != '\0'; i++)
|
|
dest[i] = src[i];
|
|
for (; i < n; i++)
|
|
dest[i] = '\0';
|
|
|
|
return dest;
|
|
}
|
|
|
|
static inline
|
|
__attribute__((unused))
|
|
CHAR8 *
|
|
strcata(CHAR8 *dest, const CHAR8 *src)
|
|
{
|
|
unsigned long dest_len = strlena(dest);
|
|
unsigned long i;
|
|
|
|
for (i = 0; src[i] != '\0'; i++)
|
|
dest[dest_len + i] = src[i];
|
|
dest[dest_len + i] = '\0';
|
|
|
|
return dest;
|
|
}
|
|
|
|
static inline
|
|
__attribute__((unused))
|
|
CHAR8 *
|
|
translate_slashes(CHAR8 *out, const char *str)
|
|
{
|
|
int i;
|
|
int j;
|
|
if (str == NULL || out == NULL)
|
|
return NULL;
|
|
|
|
for (i = 0, j = 0; str[i] != '\0'; i++, j++) {
|
|
if (str[i] == '\\') {
|
|
out[j] = '/';
|
|
if (str[i+1] == '\\')
|
|
i++;
|
|
} else
|
|
out[j] = str[i];
|
|
}
|
|
out[j] = '\0';
|
|
return out;
|
|
}
|
|
|
|
#endif /* SHIM_STR_H */
|