mirror of
https://github.com/systemd/systemd
synced 2026-03-10 15:14:58 +01:00
Compare commits
4 Commits
a267656b07
...
6d0e8271b4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d0e8271b4 | ||
|
|
4afa6cf07a | ||
|
|
ccbd324a3a | ||
|
|
fd7c6d1ac1 |
@ -382,11 +382,15 @@ All tools:
|
||||
|
||||
* `$SYSTEMD_KEYMAP_DIRECTORIES=` — takes a colon (`:`) separated list of keymap
|
||||
directories. The directories must be absolute and normalized. If unset, the
|
||||
default keymap directories (/usr/share/keymaps/, /usr/share/kbd/keymaps/, and
|
||||
/usr/lib/kbd/keymaps/) will be used.
|
||||
default keymap directories (`/usr/share/keymaps/`, `/usr/share/kbd/keymaps/`,
|
||||
and `/usr/lib/kbd/keymaps/`) will be used.
|
||||
|
||||
* `$SYSTEMD_XKB_DIRECTORY=` — The directory must be absolute and normalized.
|
||||
If unset, the default XKB directory (/usr/share/X11/xkb) will be used.
|
||||
* `$SYSTEMD_XKB_DIRECTORY=` — The directory must be absolute and normalized. If
|
||||
unset, the default XKB directory (`/usr/share/X11/xkb/`) will be used.
|
||||
|
||||
* `$SYSTEMD_LOCALE_DIRECTORY=` — The directory must be absolute and normalized.
|
||||
If unset, the default locale directory of the C library (`/usr/lib/locale/`
|
||||
for glibc and `/usr/share/i18n/locales/musl/` for musl) will be used.
|
||||
|
||||
`systemd-resolved`:
|
||||
|
||||
|
||||
@ -55,6 +55,15 @@ static char* normalize_locale(const char *name) {
|
||||
return strdup(name);
|
||||
}
|
||||
|
||||
static const char* get_locale_dir(void) {
|
||||
return secure_getenv("SYSTEMD_LOCALE_DIRECTORY") ?:
|
||||
#ifdef __GLIBC__
|
||||
"/usr/lib/locale/";
|
||||
#else
|
||||
"/usr/share/i18n/locales/musl/";
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __GLIBC__
|
||||
static int add_locales_from_archive(Set *locales) {
|
||||
/* Stolen from glibc... */
|
||||
@ -94,7 +103,11 @@ static int add_locales_from_archive(Set *locales) {
|
||||
|
||||
assert(locales);
|
||||
|
||||
_cleanup_close_ int fd = open("/usr/lib/locale/locale-archive", O_RDONLY|O_NOCTTY|O_CLOEXEC);
|
||||
_cleanup_free_ char *locale_archive_file = path_join(get_locale_dir(), "locale-archive");
|
||||
if (!locale_archive_file)
|
||||
return -ENOMEM;
|
||||
|
||||
_cleanup_close_ int fd = open(locale_archive_file, O_RDONLY|O_NOCTTY|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return errno == ENOENT ? 0 : -errno;
|
||||
|
||||
@ -162,7 +175,7 @@ static int add_locales_from_libdir(Set *locales) {
|
||||
|
||||
assert(locales);
|
||||
|
||||
dir = opendir("/usr/lib/locale");
|
||||
dir = opendir(get_locale_dir());
|
||||
if (!dir)
|
||||
return errno == ENOENT ? 0 : -errno;
|
||||
|
||||
@ -191,7 +204,7 @@ static int add_locales_for_musl(Set *locales) {
|
||||
|
||||
assert(locales);
|
||||
|
||||
_cleanup_closedir_ DIR *dir = opendir("/usr/share/i18n/locales/musl/");
|
||||
_cleanup_closedir_ DIR *dir = opendir(get_locale_dir());
|
||||
if (!dir)
|
||||
return errno == ENOENT ? 0 : -errno;
|
||||
|
||||
@ -313,7 +326,7 @@ int locale_is_installed(const char *name) {
|
||||
|
||||
/* musl's newlocale() always succeeds and provides a fake locale object even when the locale does
|
||||
* not exist. Hence, we need to explicitly check if the locale file exists. */
|
||||
_cleanup_free_ char *p = path_join("/usr/share/i18n/locales/musl/", name);
|
||||
_cleanup_free_ char *p = path_join(get_locale_dir(), name);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@ -2064,8 +2064,18 @@ static EFI_STATUS call_boot_windows_bitlocker(const BootEntry *entry, EFI_FILE *
|
||||
if (err != EFI_SUCCESS || block_io->Media->BlockSize < 512 || block_io->Media->BlockSize > 4096)
|
||||
continue;
|
||||
|
||||
char buf[4096];
|
||||
err = block_io->ReadBlocks(block_io, block_io->Media->MediaId, 0, sizeof(buf), buf);
|
||||
#define BLOCK_IO_BUFFER_SIZE 4096
|
||||
_cleanup_pages_ Pages buf_pages = xmalloc_aligned_pages(
|
||||
AllocateMaxAddress,
|
||||
EfiLoaderData,
|
||||
EFI_SIZE_TO_PAGES(BLOCK_IO_BUFFER_SIZE),
|
||||
block_io->Media->IoAlign,
|
||||
/* On 32-bit allocate below 4G boundary as we can't easily access anything above that.
|
||||
* 64-bit platforms don't suffer this limitation, so we can allocate from anywhere.
|
||||
* addr= */ UINTPTR_MAX);
|
||||
char *buf = PHYSICAL_ADDRESS_TO_POINTER(buf_pages.addr);
|
||||
|
||||
err = block_io->ReadBlocks(block_io, block_io->Media->MediaId, /* LBA= */ 0, BLOCK_IO_BUFFER_SIZE, buf);
|
||||
if (err != EFI_SUCCESS)
|
||||
continue;
|
||||
|
||||
|
||||
@ -77,52 +77,73 @@ static EFI_STATUS try_gpt(
|
||||
EFI_LBA *ret_backup_lba, /* May be changed even on error! */
|
||||
HARDDRIVE_DEVICE_PATH *ret_hd) {
|
||||
|
||||
_cleanup_free_ EFI_PARTITION_ENTRY *entries = NULL;
|
||||
GptHeader gpt;
|
||||
EFI_PARTITION_ENTRY *entries;
|
||||
_cleanup_pages_ Pages gpt_pages = {};
|
||||
_cleanup_pages_ Pages entries_pages = {};
|
||||
GptHeader *gpt;
|
||||
EFI_STATUS err;
|
||||
uint32_t crc32;
|
||||
size_t size;
|
||||
|
||||
assert(block_io);
|
||||
assert(block_io->Media);
|
||||
assert(ret_hd);
|
||||
|
||||
gpt_pages = xmalloc_aligned_pages(
|
||||
AllocateMaxAddress,
|
||||
EfiLoaderData,
|
||||
EFI_SIZE_TO_PAGES(sizeof(GptHeader)),
|
||||
block_io->Media->IoAlign,
|
||||
/* On 32-bit allocate below 4G boundary as we can't easily access anything above that.
|
||||
* 64-bit platforms don't suffer this limitation, so we can allocate from anywhere.
|
||||
* addr= */ UINTPTR_MAX);
|
||||
gpt = PHYSICAL_ADDRESS_TO_POINTER(gpt_pages.addr);
|
||||
|
||||
/* Read the GPT header */
|
||||
err = block_io->ReadBlocks(
|
||||
block_io,
|
||||
block_io->Media->MediaId,
|
||||
lba,
|
||||
sizeof(gpt), &gpt);
|
||||
sizeof(*gpt), gpt);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Indicate the location of backup LBA even if the rest of the header is corrupt. */
|
||||
if (ret_backup_lba)
|
||||
*ret_backup_lba = gpt.AlternateLBA;
|
||||
*ret_backup_lba = gpt->AlternateLBA;
|
||||
|
||||
if (!verify_gpt(&gpt, lba))
|
||||
if (!verify_gpt(gpt, lba))
|
||||
return EFI_NOT_FOUND;
|
||||
|
||||
/* Now load the GPT entry table */
|
||||
size = ALIGN_TO((size_t) gpt.SizeOfPartitionEntry * (size_t) gpt.NumberOfPartitionEntries, 512);
|
||||
entries = xmalloc(size);
|
||||
size = ALIGN_TO((size_t) gpt->SizeOfPartitionEntry * (size_t) gpt->NumberOfPartitionEntries, 512);
|
||||
entries_pages = xmalloc_aligned_pages(
|
||||
AllocateMaxAddress,
|
||||
EfiLoaderData,
|
||||
EFI_SIZE_TO_PAGES(size),
|
||||
block_io->Media->IoAlign,
|
||||
/* On 32-bit allocate below 4G boundary as we can't easily access anything above that.
|
||||
* 64-bit platforms don't suffer this limitation, so we can allocate from anywhere.
|
||||
* addr= */ UINTPTR_MAX);
|
||||
entries = PHYSICAL_ADDRESS_TO_POINTER(entries_pages.addr);
|
||||
|
||||
err = block_io->ReadBlocks(
|
||||
block_io,
|
||||
block_io->Media->MediaId,
|
||||
gpt.PartitionEntryLBA,
|
||||
gpt->PartitionEntryLBA,
|
||||
size, entries);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Calculate CRC of entries array, too */
|
||||
err = BS->CalculateCrc32(entries, size, &crc32);
|
||||
if (err != EFI_SUCCESS || crc32 != gpt.PartitionEntryArrayCRC32)
|
||||
if (err != EFI_SUCCESS || crc32 != gpt->PartitionEntryArrayCRC32)
|
||||
return EFI_CRC_ERROR;
|
||||
|
||||
/* Now we can finally look for xbootloader partitions. */
|
||||
for (size_t i = 0; i < gpt.NumberOfPartitionEntries; i++) {
|
||||
for (size_t i = 0; i < gpt->NumberOfPartitionEntries; i++) {
|
||||
EFI_PARTITION_ENTRY *entry =
|
||||
(EFI_PARTITION_ENTRY *) ((uint8_t *) entries + gpt.SizeOfPartitionEntry * i);
|
||||
(EFI_PARTITION_ENTRY *) ((uint8_t *) entries + gpt->SizeOfPartitionEntry * i);
|
||||
|
||||
if (!efi_guid_equal(&entry->PartitionTypeGUID, type))
|
||||
continue;
|
||||
|
||||
@ -517,6 +517,51 @@ void *xmalloc(size_t size) {
|
||||
return p;
|
||||
}
|
||||
|
||||
Pages xmalloc_aligned_pages(
|
||||
EFI_ALLOCATE_TYPE type,
|
||||
EFI_MEMORY_TYPE memory_type,
|
||||
size_t n_pages,
|
||||
size_t alignment,
|
||||
EFI_PHYSICAL_ADDRESS addr) {
|
||||
|
||||
EFI_PHYSICAL_ADDRESS aligned = addr;
|
||||
|
||||
/* Allow to pass block_io->Media->IoAlign to this function directly.
|
||||
* alignment <= 1 means no alignment is required, in that case just
|
||||
* allocate pages directly.
|
||||
*/
|
||||
if (alignment <= 1)
|
||||
alignment = EFI_PAGE_SIZE;
|
||||
|
||||
assert(ISPOWEROF2(alignment));
|
||||
|
||||
if (alignment <= EFI_PAGE_SIZE) {
|
||||
assert_se(BS->AllocatePages(type, memory_type, n_pages, &aligned) == EFI_SUCCESS);
|
||||
return (Pages) {
|
||||
.addr = aligned,
|
||||
.n_pages = n_pages,
|
||||
};
|
||||
}
|
||||
|
||||
size_t total_pages = n_pages + EFI_SIZE_TO_PAGES(alignment);
|
||||
assert_se(BS->AllocatePages(type, memory_type, total_pages, &addr) == EFI_SUCCESS);
|
||||
|
||||
aligned = ALIGN_TO(addr, alignment);
|
||||
size_t unaligned_pages = EFI_SIZE_TO_PAGES(aligned - addr);
|
||||
if (unaligned_pages > 0)
|
||||
assert_se(BS->FreePages(addr, unaligned_pages) == EFI_SUCCESS);
|
||||
|
||||
addr = aligned + n_pages * EFI_PAGE_SIZE;
|
||||
unaligned_pages = total_pages - n_pages - unaligned_pages;
|
||||
if (unaligned_pages > 0)
|
||||
assert_se(BS->FreePages(addr, unaligned_pages) == EFI_SUCCESS);
|
||||
|
||||
return (Pages) {
|
||||
.addr = aligned,
|
||||
.n_pages = n_pages,
|
||||
};
|
||||
}
|
||||
|
||||
bool free_and_xstrdup16(char16_t **p, const char16_t *s) {
|
||||
char16_t *t;
|
||||
|
||||
|
||||
@ -96,6 +96,13 @@ static inline Pages xmalloc_pages(
|
||||
};
|
||||
}
|
||||
|
||||
Pages xmalloc_aligned_pages(
|
||||
EFI_ALLOCATE_TYPE type,
|
||||
EFI_MEMORY_TYPE memory_type,
|
||||
size_t n_pages,
|
||||
size_t alignment,
|
||||
EFI_PHYSICAL_ADDRESS addr);
|
||||
|
||||
static inline Pages xmalloc_initrd_pages(size_t n_pages) {
|
||||
/* The original native x86 boot protocol of the Linux kernel was not 64bit safe, hence we try to
|
||||
* allocate memory for the initrds below the 4G boundary on x86, since we don't know early enough
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user