diff options
author | Reid Rankin <reidrankin@gmail.com> | 2020-01-23 17:07:21 +0000 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2020-01-24 09:28:48 +0200 |
commit | d25e5e3879f1a1c1cf6a5bcd82f6cc2eb7288c72 (patch) | |
tree | 051719fc5de3c64ee8350a7bb7e16f250bb7bfda | |
parent | 093c4b80777ccaff95789ec9cafd630a321fcc36 (diff) | |
download | apk-tools-d25e5e3879f1a1c1cf6a5bcd82f6cc2eb7288c72.tar.gz apk-tools-d25e5e3879f1a1c1cf6a5bcd82f6cc2eb7288c72.tar.bz2 apk-tools-d25e5e3879f1a1c1cf6a5bcd82f6cc2eb7288c72.tar.xz apk-tools-d25e5e3879f1a1c1cf6a5bcd82f6cc2eb7288c72.zip |
Harden signature verification process
This mostly boils down to making sure control_started and
data_started are consistently used to gate actions, instead of
relying whether on file names start with a '.'.
None of the weaknesses this fixes are exploitable, but they
might have become so after changes to seemingly-unrelated code,
so it's good to clean them up.
-rw-r--r-- | src/database.c | 28 | ||||
-rw-r--r-- | src/package.c | 33 |
2 files changed, 32 insertions, 29 deletions
diff --git a/src/database.c b/src/database.c index 713e57b..d7abcca 100644 --- a/src/database.c +++ b/src/database.c @@ -2388,7 +2388,19 @@ static int apk_db_install_archive_entry(void *_ctx, if (r <= 0) return r; - r = 0; + /* Package metainfo and script processing */ + if (ctx->sctx.control_started && !ctx->sctx.data_started) { + if (strcmp(ae->name, ".PKGINFO") == 0) { + apk_blob_t l, token = APK_BLOB_STR("\n"); + while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token))) + read_info_line(ctx, l); + return 0; + } + if (ae->name[0] == '.') + type = apk_script_type(&ae->name[1]); + if (type == APK_SCRIPT_INVALID) + return 0; + } /* Sanity check the file name */ if (ae->name[0] == '/' || @@ -2402,20 +2414,6 @@ static int apk_db_install_archive_entry(void *_ctx, return 0; } - /* Package metainfo and script processing */ - if (ae->name[0] == '.') { - /* APK 2.0 format */ - if (strcmp(ae->name, ".PKGINFO") == 0) { - apk_blob_t l, token = APK_BLOB_STR("\n"); - while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token))) - read_info_line(ctx, l); - return 0; - } - type = apk_script_type(&ae->name[1]); - if (type == APK_SCRIPT_INVALID) - return 0; - } - /* Handle script */ if (type != APK_SCRIPT_INVALID) { apk_ipkg_add_script(ipkg, is, type, ae->size); diff --git a/src/package.c b/src/package.c index 01ae3aa..6cfb8d4 100644 --- a/src/package.c +++ b/src/package.c @@ -613,14 +613,16 @@ int apk_sign_ctx_parse_pkginfo_line(void *ctx, apk_blob_t line) struct apk_sign_ctx *sctx = (struct apk_sign_ctx *) ctx; apk_blob_t l, r; + if (!sctx->control_started || sctx->data_started) + return 0; + if (line.ptr == NULL || line.len < 1 || line.ptr[0] == '#') return 0; if (!apk_blob_split(line, APK_BLOB_STR(" = "), &l, &r)) return 0; - if (sctx->data_started == 0 && - apk_blob_compare(APK_BLOB_STR("datahash"), l) == 0) { + if (apk_blob_compare(APK_BLOB_STR("datahash"), l) == 0) { sctx->has_data_checksum = 1; sctx->md = EVP_sha256(); apk_blob_pull_hexdump( @@ -641,6 +643,9 @@ int apk_sign_ctx_verify_tar(void *sctx, const struct apk_file_info *fi, if (r <= 0) return r; + if (!ctx->control_started || ctx->data_started) + return 0; + if (strcmp(fi->name, ".PKGINFO") == 0) { apk_blob_t l, token = APK_BLOB_STR("\n"); while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token))) @@ -891,21 +896,21 @@ static int read_info_entry(void *ctx, const struct apk_file_info *ae, struct apk_package *pkg = ri->pkg; int r; - /* Meta info and scripts */ r = apk_sign_ctx_process_file(ri->sctx, ae, is); - if (r <= 0) return r; + if (r <= 0) + return r; - if (ae->name[0] == '.') { - /* APK 2.0 format */ - if (strcmp(ae->name, ".PKGINFO") == 0) { - apk_blob_t l, token = APK_BLOB_STR("\n"); - while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token))) - read_info_line(ctx, l); - } else if (strcmp(ae->name, ".INSTALL") == 0) { - apk_warning("Package '%s-%s' contains deprecated .INSTALL", - pkg->name->name, pkg->version); - } + if (!ri->sctx->control_started || ri->sctx->data_started) return 0; + + if (strcmp(ae->name, ".PKGINFO") == 0) { + /* APK 2.0 format */ + apk_blob_t l, token = APK_BLOB_STR("\n"); + while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token))) + read_info_line(ctx, l); + } else if (strcmp(ae->name, ".INSTALL") == 0) { + apk_warning("Package '%s-%s' contains deprecated .INSTALL", + pkg->name->name, pkg->version); } return 0; |