From a1abbf884676ebbdf6f85947b7f0fc5c6915782e Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Wed, 03 May 2023 02:49:43 -0400 Subject: ustar: Document assumptions and improve safety --- 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); -- cgit v0.9.1