common/hsm_secret: remove grab_file_contents now it has inspired grab_file_raw!
What changed, and why it matters
This is a routine code cleanup commit. It removes a small helper function called grab_file_contents and replaces its uses with a newer, equivalent helper called grab_file_raw. The behavior is intended to be the same: reading a file's bytes without including a trailing NUL terminator. There is no indication of a security bug being fixed.
No security action required. Treat as normal refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit deletes grab_file_contents() from common/hsm_secret.c/h and updates call sites in hsmd/hsmd.c and tools/hsmtool.c to use grab_file_raw() directly, computing lengths with tal_bytelen() instead of an out-parameter. The commit message frames this as a refactoring (‘remove … now it has inspired grab_file_raw!’). No functional change is claimed, and no security relevance is stated.
Changed components
common/hsm_secret.ccommon/hsm_secret.hhsmd/hsmd.ctools/hsmtool.cInspect captured patch +12 / −37
diff --git a/common/hsm_secret.c b/common/hsm_secret.c
index 93c03752..b24b1f9a 100644
--- a/common/hsm_secret.c
+++ b/common/hsm_secret.c
@@ -497,15 +497,6 @@ const char *format_type_name(enum hsm_secret_type type)
return "unknown";
}
-u8 *grab_file_contents(const tal_t *ctx, const char *filename, size_t *len)
-{
- u8 *contents = grab_file_raw(ctx, filename);
- if (len)
- *len = tal_bytelen(contents);
-
- return contents;
-}
-
bool is_mnemonic_secret(size_t secret_len)
{
return secret_len == HSM_SECRET_MNEMONIC_SIZE;
diff --git a/common/hsm_secret.h b/common/hsm_secret.h
index 74a11a32..4ec44c9a 100644
--- a/common/hsm_secret.h
+++ b/common/hsm_secret.h
@@ -166,17 +166,6 @@ int is_legacy_hsm_secret_encrypted(const char *path);
*/
const char *format_type_name(enum hsm_secret_type type);
-/**
- * Wrapper around grab_file that removes the NUL terminator.
- * @ctx - tal context for allocation
- * @filename - path to the file to read
- * @len - output parameter for the file length (excluding NUL terminator)
- *
- * Returns file contents with NUL terminator removed, or NULL on error.
- * Unlike grab_file, the returned data does not include the NUL terminator.
- */
-u8 *grab_file_contents(const tal_t *ctx, const char *filename, size_t *len);
-
/**
* Derive encryption key from passphrase using Argon2.
* @ctx - tal context for allocation
diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c
index 78750908..957e5e84 100644
--- a/hsmd/hsmd.c
+++ b/hsmd/hsmd.c
@@ -432,8 +432,7 @@ static void load_hsm(const char *passphrase)
enum hsm_secret_error err;
/* Read the hsm_secret file */
- size_t hsm_secret_len;
- hsm_secret_contents = grab_file_contents(tmpctx, "hsm_secret", &hsm_secret_len);
+ hsm_secret_contents = grab_file_raw(tmpctx, "hsm_secret");
if (!hsm_secret_contents) {
hsmd_send_init_reply_failure(HSM_SECRET_ERR_INVALID_FORMAT, STATUS_FAIL_INTERNAL_ERROR,
"Could not read hsm_secret: %s", strerror(errno));
@@ -441,8 +440,8 @@ static void load_hsm(const char *passphrase)
/* Extract the secret using the new hsm_secret module */
hsms = extract_hsm_secret(tmpctx, hsm_secret_contents,
- hsm_secret_len,
- passphrase, &err);
+ tal_bytelen(hsm_secret_contents),
+ passphrase, &err);
if (!hsms) {
hsmd_send_init_reply_failure(err, STATUS_FAIL_INTERNAL_ERROR,
"Failed to load hsm_secret: %s", hsm_secret_error_str(err));
diff --git a/tools/hsmtool.c b/tools/hsmtool.c
index 5d93b740..a3f487a1 100644
--- a/tools/hsmtool.c
+++ b/tools/hsmtool.c
@@ -87,8 +87,7 @@ static bool ensure_hsm_secret_exists(int fd, const char *path)
/* Load hsm_secret using the unified interface */
static struct hsm_secret *load_hsm_secret(const tal_t *ctx, const char *hsm_secret_path)
{
- size_t contents_len;
- u8 *contents = grab_file_contents(tmpctx, hsm_secret_path, &contents_len);
+ u8 *contents = grab_file_raw(tmpctx, hsm_secret_path);
const char *passphrase = NULL;
struct hsm_secret *hsms;
enum hsm_secret_error error;
@@ -97,7 +96,7 @@ static struct hsm_secret *load_hsm_secret(const tal_t *ctx, const char *hsm_secr
err(EXITCODE_ERROR_HSM_FILE, "Reading hsm_secret");
/* Get passphrase if needed */
- if (hsm_secret_needs_passphrase(contents, contents_len)) {
+ if (hsm_secret_needs_passphrase(contents, tal_bytelen(contents))) {
printf("Enter hsm_secret password:\n");
fflush(stdout);
passphrase = read_stdin_pass(tmpctx, &error);
@@ -105,7 +104,7 @@ static struct hsm_secret *load_hsm_secret(const tal_t *ctx, const char *hsm_secr
errx(EXITCODE_ERROR_HSM_FILE, "Could not read password: %s", hsm_secret_error_str(error));
}
- hsms = extract_hsm_secret(ctx, contents, contents_len, passphrase, &error);
+ hsms = extract_hsm_secret(ctx, contents, tal_bytelen(contents), passphrase, &error);
if (!hsms) {
err(EXITCODE_ERROR_HSM_FILE, "%s", hsm_secret_error_str(error));
}
@@ -120,12 +119,11 @@ static void decrypt_hsm(const char *hsm_secret_path)
const char *dir, *backup;
/* Check if it's a format we can decrypt */
- size_t contents_len;
- u8 *contents = grab_file_contents(tmpctx, hsm_secret_path, &contents_len);
+ u8 *contents = grab_file_raw(tmpctx, hsm_secret_path);
if (!contents)
err(EXITCODE_ERROR_HSM_FILE, "Reading hsm_secret");
- enum hsm_secret_type type = detect_hsm_secret_type(contents, contents_len);
+ enum hsm_secret_type type = detect_hsm_secret_type(contents, tal_bytelen(contents));
if (type != HSM_SECRET_ENCRYPTED) {
errx(ERROR_USAGE, "decrypt command only works on legacy encrypted binary format (73 bytes).\n"
@@ -178,12 +176,11 @@ static void encrypt_hsm(const char *hsm_secret_path)
enum hsm_secret_error pass_err;
/* Check if it's a format we can encrypt */
- size_t contents_len;
- u8 *contents = grab_file_contents(tmpctx, hsm_secret_path, &contents_len);
+ u8 *contents = grab_file_raw(tmpctx, hsm_secret_path);
if (!contents)
err(EXITCODE_ERROR_HSM_FILE, "Reading hsm_secret");
- enum hsm_secret_type type = detect_hsm_secret_type(contents, contents_len);
+ enum hsm_secret_type type = detect_hsm_secret_type(contents, tal_bytelen(contents));
if (type != HSM_SECRET_PLAIN) {
errx(ERROR_USAGE, "encrypt command only works on legacy plain binary format (32 bytes).\n"
@@ -290,15 +287,14 @@ static void print_codexsecret(const char *hsm_secret_path, const char *id)
static void print_emergencyrecover(const char *emer_rec_path)
{
- size_t scb_len;
- u8 *scb = grab_file_contents(tmpctx, emer_rec_path, &scb_len);
+ u8 *scb = grab_file_raw(tmpctx, emer_rec_path);
char *output, *hrp = "clnemerg";
if (!scb) {
err(EXITCODE_ERROR_HSM_FILE, "Reading emergency.recover");
}
u5 *data = tal_arr(tmpctx, u5, 0);
- bech32_push_bits(&data, scb, scb_len * 8);
+ bech32_push_bits(&data, scb, tal_bytelen(scb) * 8);
output = tal_arr(tmpctx, char, strlen(hrp) + tal_count(data) + 8);
bech32_encode(output, hrp, data, tal_count(data), (size_t)-1,
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.