in lsvmutils/initrd.c [597:719]
int InitrdInjectFiles(
const void* initrdData,
UINTN initrdSize,
const void* bootkeyData,
UINTN bootkeySize,
const void* rootkeyData,
UINTN rootkeySize,
void** initrdDataOut,
UINTN* initrdSizeOut)
{
int rc = -1;
const void* subfilesData[CPIO_MAX_SUBFILES];
UINTN subfilesSize[CPIO_MAX_SUBFILES];
UINTN numSubfiles = 0;
void* subfileData = NULL;
UINTN subfileSize = 0;
Buf buf = BUF_INITIALIZER;
if (initrdDataOut)
*initrdDataOut = NULL;
if (initrdSizeOut)
*initrdSizeOut = 0;
/* Reject bad parameters */
if (!initrdData || !initrdSize || !bootkeyData || !bootkeySize ||
!rootkeyData || !rootkeySize || !initrdDataOut || !initrdSizeOut)
{
goto done;
}
/* Split initrd into subfiles */
if (CPIOSplitFile(
initrdData,
initrdSize,
subfilesData,
subfilesSize,
&numSubfiles) != 0)
{
goto done;
}
if (numSubfiles == 0)
goto done;
/* If first subfile is an uncompressed CPIO archive, update it.
* Else, prepend a new CPIO archive with the keys.
*/
if (subfilesSize[0] >= sizeof(CPIOHeader) &&
CPIOMatchMagicNumber(((const CPIOHeader*)subfilesData[0])->magic))
{
/* Inject the keys into this existing CPIO archive */
if (_InjectFiles(
subfilesData[0],
subfilesSize[0],
bootkeyData,
bootkeySize,
rootkeyData,
rootkeySize,
&subfileData,
&subfileSize) != 0)
{
goto done;
}
/* Create new initrd image */
{
UINTN i;
if (BufAppend(&buf, subfileData, subfileSize) != 0)
goto done;
for (i = 1; i < numSubfiles; i++)
{
if (BufAppend(&buf, subfilesData[i], subfilesSize[i]) != 0)
goto done;
}
}
}
else
{
/* Create a new CPIO archive that contains these keys */
if (InitrdMakeArchive(
bootkeyData,
bootkeySize,
rootkeyData,
rootkeySize,
&subfileData,
&subfileSize) != 0)
{
goto done;
}
/* Create new initrd image */
{
UINTN i;
if (BufAppend(&buf, subfileData, subfileSize) != 0)
goto done;
for (i = 0; i < numSubfiles; i++)
{
if (BufAppend(&buf, subfilesData[i], subfilesSize[i]) != 0)
goto done;
}
}
}
*initrdDataOut = buf.data;
*initrdSizeOut = buf.size;
rc = 0;
done:
if (rc != 0)
BufRelease(&buf);
if (subfileData)
Free(subfileData);
return rc;
}