summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McDermott <patrick.mcdermott@libiquity.com>2023-05-03 02:49:43 (EDT)
committer Patrick McDermott <patrick.mcdermott@libiquity.com>2023-05-03 02:49:43 (EDT)
commita1abbf884676ebbdf6f85947b7f0fc5c6915782e (patch)
treee3589c7c32265b1cb9e6fd126105b454fc1955b5
parentb416b15eb246444a30ed5fdea79f45dfe8cc4eab (diff)
ustar: Document assumptions and improve safety
-rw-r--r--src/ustar.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/ustar.c b/src/ustar.c
index b5b0310..e4d9aca 100644
--- a/src/ustar.c
+++ b/src/ustar.c
@@ -112,6 +112,8 @@ _opkg_opk_ustar_next(struct opkg_opk_ustar *ustar)
}
/* Verify checksum. */
+ /* Assumes chksum is NUL-terminated. Not required by POSIX, but done by
+ * GNU and BB tar and opkg_opk_ustar_write_header(). */
chksum_got = strtol(ustar->header.chksum, &end,
OPKG_OPK_USTAR_NUM_BASE_);
chksum_exp = 0;
@@ -133,6 +135,9 @@ _opkg_opk_ustar_next(struct opkg_opk_ustar *ustar)
switch (*ustar->header.typeflag) {
case '0': /* Regular file */
case '7': /* High-performance or regular file */
+ /* Assumes size is NUL-terminated. Not required by
+ * POSIX, but done by GNU and BB tar and
+ * opkg_opk_ustar_write_header(). */
ustar->data_size_remaining = strtol(
ustar->header.size, &end,
OPKG_OPK_USTAR_NUM_BASE_);
@@ -184,6 +189,8 @@ opkg_opk_ustar_list(struct opkg_opk_ustar *ustar,
sizeof(ustar->header.name));
(*member)->name[sizeof(ustar->header.name)] = '\0';
}
+ /* Assumes mode and mtime are NUL-terminated. Not required by POSIX,
+ * but done by GNU and BB tar and opkg_opk_ustar_write_header(). */
(*member)->mode = strtol(ustar->header.mode, &end,
OPKG_OPK_USTAR_NUM_BASE_);
if (*end != '\0') {
@@ -226,8 +233,10 @@ opkg_opk_ustar_list(struct opkg_opk_ustar *ustar,
free(*member);
return OPKG_OPK_ERROR; /* Unsupported */
}
- strcpy((*member)->uname, ustar->header.uname);
- strcpy((*member)->gname, ustar->header.gname);
+ strncpy((*member)->uname, ustar->header.uname,
+ sizeof((*member)->uname));
+ strncpy((*member)->gname, ustar->header.gname,
+ sizeof((*member)->gname));
return OPKG_OPK_OK; /* Possibly more members in archive */
}
@@ -290,7 +299,9 @@ opkg_opk_ustar_write_header(struct opkg_opk_ustar *ustar,
* GNU and BB tar accept values that aren't (but generate values that
* ARE) NUL-terminated. But more importantly, opkg-lede (see file
* libbb/unarchive.c) parses these with simple strtol() calls, without
- * even checking endptr, so we have to NUL-terminate these fields. */
+ * even checking endptr, so we have to NUL-terminate these fields. Also
+ * parsing these fields with strtol() are our very own
+ * _opkg_opk_ustar_next() and opkg_opk_ustar_list() above. */
sprintf(ustar->header.mode, "%07o", mode);
sprintf(ustar->header.uid, "%07o", uid);
sprintf(ustar->header.gid, "%07o", gid);