Compare commits

...

16 Commits

Author SHA1 Message Date
Radoslav Kolev
25b7f6b934 blsuki: Error out if unexpected arguments are supplied
This can be especially helpful, as the Fedora version of the blscfg
actually made use of positional arguments, but current implementation
switched to parameters. For example what used to be "blscfg (hd0,gpt2)/..."
now should be "blscfg --path (hd0,gpt2)/...)". In case of old configs/scripts
still supplying positional arguments we will now error out instead of just
ignoring them and falling back to defaults silently.

Signed-off-by: Radoslav Kolev <radoslav.kolev@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:47 +01:00
Radoslav Kolev
cfeff5e071 blsuki: Fix default location in comment to /loader/entries
Signed-off-by: Radoslav Kolev <radoslav.kolev@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:47 +01:00
Radoslav Kolev
d19a74a17f blsuki: Use specified device in case of fallback
Currently if the fallback option is enabled and no files are found in
the specified directory it searches the default (loader/conf) directory
but always in the device set by the root environment variable. It makes
more sense and also the comment in the code implies, that the default
directory on the current device should be searched.

Signed-off-by: Radoslav Kolev <radoslav.kolev@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:46 +01:00
Radoslav Kolev
242816e93f blsuki: Fix position of DIR parameter in blscfg command summary
The DIR parameter in the example should be specified after the -p|--path option
instead of after -f|fallback.

Signed-off-by: Radoslav Kolev <radoslav.kolev@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:46 +01:00
Radoslav Kolev
b733d9d6dc blsuki: Fix typo in entry parameter description
Change "specificUKII entries" to "specific UKI entries".

Signed-off-by: Radoslav Kolev <radoslav.kolev@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:46 +01:00
Khalid Ali
0f0899c329 efi: Fix several memory leaks of UEFI handles
Fix possible and absolute memory leaks of "handles"
returned by grub_efi_locate_handle() using grub_malloc().

Signed-off-by: Khalid Ali <khaliidcaliy@gmail.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:46 +01:00
Andreas K. Hüttel
c477a95519 util/grub-install: Allow recursive copying of theme dirs
grub-install allows to pass a parameter to install a theme in the boot partition.
This works fine for the default starfield theme. However, in general themes can
contain subdirectories, as, e.g. "icons", and these are not copied by grub-install.
As a result, the icons are missing on the screen.

Fix this by simple recursive copying.

Signed-off-by: Andreas K. Hüttel <dilfridge@gentoo.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:46 +01:00
Heinrich Schuchardt
f551d3de24 commands/efi/lsefisystab: Recognize EFI_MEMORY_ATTRIBUTES_TABLE_GUID and EFI_TCG2_FINAL_EVENTS_TABLE_GUID
Let the lsefisystab command recognize the following table GUIDs:
  - EFI_MEMORY_ATTRIBUTES_TABLE_GUID,
  - EFI_TCG2_FINAL_EVENTS_TABLE_GUID.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:46 +01:00
Glenn Washburn
ee283b14ae tests/util/grub-fs-tester: Use CSMACINTOSH encoding instead of macroman
From Debian 12 to 13, recode had a major overhaul and now does not support
the macroman encoding. Its unclear if this is a bug or intentional.
Regardless, use the CSMACINTOSH encoding instead as MacRoman and it are
aliases and CSMACINTOSH is supported on both Debian 12 and 13.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:46 +01:00
Luca Boccassi
9b2c8ae5d2 commands/bli: Set UINT32_MAX in LoaderTpm2ActivePcrBanks if TPM2 present but no banks protocol
The implementation in sd-boot was changed to return UINT32_MAX when
the EFI environment detects a working TPM2, but with an older firmware
that doesn't implement the protocol to get the list of active banks.
This allows distinguishing with the case where there is no working TPM2,
in which case userspace just gives up, and instead lets userspace try to
figure it out later.

Fixes: f326c5c47 (commands/bli: Set LoaderTpm2ActivePcrBanks runtime variable)

Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:46 +01:00
Sridhar Markonda
c0669af6a8 script/execute: Add a NULL check after grub_calloc() call
... in gettext_append() to handle allocation errors. This prevents NULL
pointer dereference and stops crashes during string translation.

Signed-off-by: Sridhar Markonda <sridharm@linux.ibm.com>
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:46 +01:00
Avnish Chouhan
02cae1a357 disk/ieee1275/ofdisk: Fix memory leaks
In case of an overflow "p" and "p->grub_devpath" will not be freed.
Fix both issues.

Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
2025-12-21 16:41:46 +01:00
Avnish Chouhan
09c512b8fa efiemu/loadcore: Add grub_calloc() failure check
Add a failure check after grub_calloc() call. If grub_calloc()
fails, e.g., due to memory allocation failure, it returns NULL.
Then using grub_efiemu_elfsyms, which will be NULL, later will
result in a NULL pointer dereference.

Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:46 +01:00
George Hu
641646376b lib/x86_64/setjmp: Use 32-bit zero idiom for shorter encoding
Switch from "xorq %rax, %rax" to "xorl %eax, %eax". In 64-bit mode
zeroing EAX implicitly clears RAX and the 32-bit form encodes are one
byte smaller while keeping identical semantics.

Signed-off-by: George Hu <integral@archlinux.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:46 +01:00
Glenn Washburn
d07ebd11d6 tests: Fix nonnative tests labeled as native
The tests asn1_test and tpm2_key_protector_test should be labelled as
nonnative tests because they run tests on the target. A clue that
indicates a nonnative test is the usage of the grub-shell script.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:45 +01:00
Glenn Washburn
a90ccbac67 INSTALL: Add note that the GNU Autoconf Archive may be needed
As of 1a5417f39a (configure: Check linker for --image-base support),
the GNU Autoconf Archive is now required to bootstrap GRUB.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-12-21 16:41:45 +01:00
15 changed files with 77 additions and 55 deletions

View File

@@ -56,6 +56,7 @@ need the following.
* Python 3 (NOTE: python 2.6 should still work, but it's not tested)
* Autoconf 2.64 or later
* Automake 1.14 or later
* GNU Autoconf Archive (autoconf-archive on Debian)
Your distro may package cross-compiling toolchains such as the following
incomplete list on Debian: gcc-aarch64-linux-gnu, gcc-arm-linux-gnueabihf,

View File

@@ -1294,13 +1294,13 @@ script = {
};
script = {
testcase = native;
testcase = nonnative;
name = asn1_test;
common = tests/asn1_test.in;
};
script = {
testcase = native;
testcase = nonnative;
name = tpm2_key_protector_test;
common = tests/tpm2_key_protector_test.in;
};

View File

@@ -88,7 +88,7 @@ static const struct grub_arg_option uki_opt[] =
{"enable-fallback", 'f', 0, "Fallback to the default BLS path if --path fails to find UKI entries.", 0, ARG_TYPE_NONE},
{"show-default", 'd', 0, N_("Allow the default UKI entry to be added to the GRUB menu."), 0, ARG_TYPE_NONE},
{"show-non-default", 'n', 0, N_("Allow the non-default UKI entries to be added to the GRUB menu."), 0, ARG_TYPE_NONE},
{"entry", 'e', 0, N_("Allow specificUKII entries to be added to the GRUB menu."), N_("FILE"), ARG_TYPE_FILE},
{"entry", 'e', 0, N_("Allow specific UKI entries to be added to the GRUB menu."), N_("FILE"), ARG_TYPE_FILE},
{0, 0, 0, 0, 0, 0}
};
#endif
@@ -1210,7 +1210,7 @@ blsuki_find_entry (struct find_entry_info *info, bool enable_fallback, enum blsu
/*
* If we aren't able to find BLS entries in the directory given by info->dirname,
* we can fallback to the default location "/boot/loader/entries/" and see if we
* we can fallback to the default location of "/loader/entries/" and see if we
* can find the files there. If we can't find UKI entries, fallback to
* "/EFI/Linux" on the EFI system partition.
*/
@@ -1231,7 +1231,7 @@ blsuki_find_entry (struct find_entry_info *info, bool enable_fallback, enum blsu
tmp = blsuki_update_boot_device (default_dir);
tmp = grub_stpcpy (tmp, cmd_dir);
blsuki_set_find_entry_info (info, default_dir, NULL, cmd_type);
blsuki_set_find_entry_info (info, default_dir, info->devid, cmd_type);
grub_dprintf ("blsuki", "Entries weren't found in %s, fallback to %s\n",
read_entry_info.dirname, info->dirname);
fallback = true;
@@ -1458,9 +1458,11 @@ blsuki_cmd (grub_extcmd_context_t ctxt, enum blsuki_cmd_type cmd_type)
}
static grub_err_t
grub_cmd_blscfg (grub_extcmd_context_t ctxt, int argc __attribute__ ((unused)),
grub_cmd_blscfg (grub_extcmd_context_t ctxt, int argc,
char **args __attribute__ ((unused)))
{
if (argc != 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected argument(s) found, see --help"));
return blsuki_cmd (ctxt, BLSUKI_BLS_CMD);
}
@@ -1468,9 +1470,11 @@ static grub_extcmd_t bls_cmd;
#ifdef GRUB_MACHINE_EFI
static grub_err_t
grub_cmd_uki (grub_extcmd_context_t ctxt, int argc __attribute__ ((unused)),
grub_cmd_uki (grub_extcmd_context_t ctxt, int argc,
char **args __attribute__ ((unused)))
{
if (argc != 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected argument(s) found, see --help"));
return blsuki_cmd (ctxt, BLSUKI_UKI_CMD);
}
@@ -1480,7 +1484,7 @@ static grub_extcmd_t uki_cmd;
GRUB_MOD_INIT(blsuki)
{
bls_cmd = grub_register_extcmd ("blscfg", grub_cmd_blscfg, 0,
N_("[-p|--path] [-f|--enable-fallback] DIR [-d|--show-default] [-n|--show-non-default] [-e|--entry] FILE"),
N_("[-p|--path] DIR [-f|--enable-fallback] [-d|--show-default] [-n|--show-non-default] [-e|--entry] FILE"),
N_("Import Boot Loader Specification snippets."),
bls_opt);
#ifdef GRUB_MACHINE_EFI

View File

@@ -129,6 +129,7 @@ grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)),
}
grub_free (handles);
return 0;
}

View File

@@ -47,6 +47,7 @@ static const struct guid_mapping guid_mappings[] =
{ GRUB_EFI_HOB_LIST_GUID, "HOB LIST"},
{ GRUB_EFI_IMAGE_SECURITY_DATABASE_GUID, "IMAGE EXECUTION INFORMATION"},
{ GRUB_EFI_LZMA_CUSTOM_DECOMPRESS_GUID, "LZMA CUSTOM DECOMPRESS"},
{ GRUB_EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMORY ATTRIBUTES TABLE"},
{ GRUB_EFI_MEMORY_TYPE_INFORMATION_GUID, "MEMORY TYPE INFO"},
{ GRUB_EFI_MPS_TABLE_GUID, "MPS"},
{ GRUB_EFI_RT_PROPERTIES_TABLE_GUID, "RT PROPERTIES"},
@@ -54,6 +55,7 @@ static const struct guid_mapping guid_mappings[] =
{ GRUB_EFI_SMBIOS_TABLE_GUID, "SMBIOS"},
{ GRUB_EFI_SMBIOS3_TABLE_GUID, "SMBIOS3"},
{ GRUB_EFI_SYSTEM_RESOURCE_TABLE_GUID, "SYSTEM RESOURCE TABLE"},
{ GRUB_EFI_TCG2_FINAL_EVENTS_TABLE_GUID, "TCG2 FINAL EVENTS TABLE"},
{ GRUB_EFI_TIANO_CUSTOM_DECOMPRESS_GUID, "TIANO CUSTOM DECOMPRESS"},
{ GRUB_EFI_TSC_FREQUENCY_GUID, "TSC FREQUENCY"},
};

View File

@@ -39,7 +39,7 @@ static grub_uint8_t grub_tpm_version;
static grub_int8_t tpm1_present = -1;
static grub_int8_t tpm2_present = -1;
static grub_int8_t tpm2_pcr_banks_reporting_present = -1;
static grub_efi_int64_t tpm2_active_pcr_banks = -1;
static grub_efi_boolean_t
grub_tpm1_present (grub_efi_tpm_protocol_t *tpm)
@@ -90,34 +90,6 @@ grub_tpm2_present (grub_efi_tpm2_protocol_t *tpm)
return (grub_efi_boolean_t) tpm2_present;
}
static grub_efi_boolean_t
grub_tpm2_pcr_banks_reporting_present (grub_efi_tpm2_protocol_t *tpm)
{
grub_efi_status_t status;
EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
caps.Size = (grub_uint8_t) sizeof (caps);
if (tpm2_pcr_banks_reporting_present != -1)
return (grub_efi_boolean_t) tpm2_pcr_banks_reporting_present;
if (!grub_tpm2_present (tpm))
return (grub_efi_boolean_t) (tpm2_pcr_banks_reporting_present = 0);
status = tpm->get_capability (tpm, &caps);
if (status != GRUB_EFI_SUCCESS || caps.StructureVersion.Major < 1
|| (caps.StructureVersion.Major == 1 && caps.StructureVersion.Minor < 1))
tpm2_pcr_banks_reporting_present = 0;
else
tpm2_pcr_banks_reporting_present = 1;
grub_dprintf ("tpm", "tpm2 PCR banks reporting%s present\n",
tpm2_pcr_banks_reporting_present ? "" : " NOT");
return (grub_efi_boolean_t) tpm2_pcr_banks_reporting_present;
}
static grub_efi_boolean_t
grub_tpm_handle_find (grub_efi_handle_t *tpm_handle,
grub_efi_uint8_t *protocol_version)
@@ -141,6 +113,7 @@ grub_tpm_handle_find (grub_efi_handle_t *tpm_handle,
grub_tpm_version = 1;
*protocol_version = 1;
grub_dprintf ("tpm", "TPM handle Found, version: 1\n");
grub_free (handles);
return 1;
}
@@ -153,6 +126,7 @@ grub_tpm_handle_find (grub_efi_handle_t *tpm_handle,
grub_tpm_version = 2;
*protocol_version = 2;
grub_dprintf ("tpm", "TPM handle Found, version: 2\n");
grub_free (handles);
return 1;
}
@@ -365,32 +339,45 @@ grub_tpm_present (void)
grub_uint32_t
grub_tpm2_active_pcr_banks (void)
{
EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
grub_efi_handle_t tpm_handle;
grub_efi_uint8_t protocol_version;
grub_efi_tpm2_protocol_t *tpm;
grub_efi_uint32_t active_pcr_banks = 0;
grub_efi_uint32_t active_pcr_banks;
grub_efi_status_t status;
if (tpm2_active_pcr_banks >= 0)
return (grub_uint32_t) tpm2_active_pcr_banks;
if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
return 0;
return (grub_uint32_t) (tpm2_active_pcr_banks = 0);
if (protocol_version == 1)
return 0; /* We report TPM2 status */
return (grub_uint32_t) (tpm2_active_pcr_banks = 0); /* We report TPM2 status. */
tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (tpm == NULL)
{
grub_dprintf ("tpm", "Cannot open TPM2 protocol\n");
return 0;
return (grub_uint32_t) (tpm2_active_pcr_banks = 0);
}
if (grub_tpm2_pcr_banks_reporting_present (tpm))
{
grub_efi_status_t status = tpm->get_active_pcr_banks (tpm, &active_pcr_banks);
if (!grub_tpm2_present (tpm))
return (grub_uint32_t) (tpm2_active_pcr_banks = 0);
if (status != GRUB_EFI_SUCCESS)
return 0; /* Assume none available if the call fails. */
}
caps.Size = (grub_uint8_t) sizeof (caps);
status = tpm->get_capability (tpm, &caps);
if (status != GRUB_EFI_SUCCESS)
return (grub_uint32_t) (tpm2_active_pcr_banks = 0);
if (caps.StructureVersion.Major < 1 ||
(caps.StructureVersion.Major == 1 && caps.StructureVersion.Minor < 1))
/* There's a working TPM2 but without querying protocol, let userspace figure it out. */
return (grub_uint32_t) (tpm2_active_pcr_banks = GRUB_UINT_MAX);
return active_pcr_banks;
status = tpm->get_active_pcr_banks (tpm, &active_pcr_banks);
if (status != GRUB_EFI_SUCCESS)
return (grub_uint32_t) (tpm2_active_pcr_banks = 0); /* Assume none available if the call fails. */
return (grub_uint32_t) (tpm2_active_pcr_banks = active_pcr_banks);
}

View File

@@ -93,6 +93,7 @@ ofdisk_hash_add_real (char *devpath)
grub_add (sz, sizeof ("ieee1275/"), &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of device path"));
grub_free (p);
return NULL;
}
@@ -109,6 +110,8 @@ ofdisk_hash_add_real (char *devpath)
if (grub_add (grub_strlen (p->devpath), 3, &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of an open path"));
grub_free (p->grub_devpath);
grub_free (p);
return NULL;
}

View File

@@ -203,6 +203,9 @@ grub_efiemu_count_symbols (const Elf_Ehdr *e)
grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
grub_calloc (grub_efiemu_nelfsyms, sizeof (struct grub_efiemu_elf_sym));
if (grub_efiemu_elfsyms == NULL)
return grub_errno;
/* Relocators */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;

View File

@@ -36,7 +36,7 @@ GRUB_MOD_LICENSE "GPLv3+"
*/
FUNCTION(grub_setjmp)
pop %rsi /* Return address, and adjust the stack */
xorq %rax, %rax
xorl %eax, %eax
movq %rbx, 0(%rdi) /* RBX */
movq %rsp, 8(%rdi) /* RSP */
push %rsi

View File

@@ -562,6 +562,8 @@ gettext_append (struct grub_script_argv *result, const char *orig_str)
if (*iptr == '$')
dollar_cnt++;
ctx.allowed_strings = grub_calloc (dollar_cnt, sizeof (ctx.allowed_strings[0]));
if (ctx.allowed_strings == NULL)
goto fail;
if (parse_string (orig_str, gettext_save_allow, &ctx, 0))
goto fail;

View File

@@ -169,13 +169,13 @@ grub_efiserial_init (void)
port = grub_zalloc (sizeof (*port));
if (!port)
return;
break;
port->name = grub_malloc (sizeof ("efiXXXXXXXXXXXXXXXXXXXX"));
if (!port->name)
{
grub_free (port);
return;
break;
}
grub_snprintf (port->name, sizeof ("efiXXXXXXXXXXXXXXXXXXXX"),
"efi%d", num_serial++);

View File

@@ -94,7 +94,7 @@ check_protocol (void)
gop_handle = 0;
grub_dprintf ("video", "GOP: no usable mode\n");
grub_free (handles);
return 0;
}

View File

@@ -389,6 +389,16 @@
{ 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 } \
}
#define GRUB_EFI_MEMORY_ATTRIBUTES_TABLE_GUID \
{ 0xdcfa911d, 0x26eb, 0x469f, \
{ 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20 } \
}
#define GRUB_EFI_TCG2_FINAL_EVENTS_TABLE_GUID \
{ 0x1e2ed096, 0x30e2, 0x4254, \
{ 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25 } \
}
struct grub_efi_sal_system_table
{
grub_uint32_t signature;

View File

@@ -743,7 +743,9 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do
dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((0x468)) conv=notrunc count=8
MOUNTFS="hfsplus";;
x"hfs")
"mkfs.hfs" -b $BLKSIZE -v "`echo $FSLABEL |recode utf8..macroman`" -h "${MOUNTDEVICE}"
# CSMACINTOSH is an alias for MacRoman which is the
# encoding used on HFS.
"mkfs.hfs" -b $BLKSIZE -v "`echo $FSLABEL | recode utf8..CSMACINTOSH`" -h "${MOUNTDEVICE}"
dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((0x474)) conv=notrunc count=8
MOUNTOPTS="iocharset=utf8,codepage=macroman,"
;;

View File

@@ -803,13 +803,20 @@ copy_all (const char *srcd,
|| strcmp (de->d_name, "..") == 0)
continue;
srcf = grub_util_path_concat (2, srcd, de->d_name);
if (grub_util_is_special_file (srcf)
|| grub_util_is_directory (srcf))
if (grub_util_is_special_file (srcf))
{
free (srcf);
continue;
}
dstf = grub_util_path_concat (2, dstd, de->d_name);
if (grub_util_is_directory (srcf))
{
grub_install_mkdir_p (dstf);
copy_all (srcf, dstf);
free (srcf);
free (dstf);
continue;
}
grub_install_compress_file (srcf, dstf, 1);
free (srcf);
free (dstf);