• Some minor fixes to some memory issues

    From KOLANICH@21:1/5 to All on Mon Jul 27 00:00:03 2020
    Hello, I have implemented some fixes for some issues found by clang 12 UBSan (or MemSan, os ASan, I don't remember now) and valgrind: https://github.com/guillemj/dpkg/pull/2.


    RnJvbSA2MmQyZDE1YjU3YWY1MTUwOTY1OTEzYzRmZDk4ZWRkMGMyZDk3ZGZlIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBLT0xBTklDSCA8a29sYW5fbkBtYWlsLnJ1PgpEYXRlOiBUaHUs IDIzIEp1bCAyMDIwIDE2OjM3OjA2ICswMzAwClN1YmplY3Q6IFtQQVRDSF0gRml4ZWQgc29tZSBt ZW1vcnkgbGVha3MgYW5kIFVCCgotLS0KIGxpYi9kcGtnL3RhcmZuLmMgICAgICAgIHwgNSArKysr KwogbGliL2Rwa2cvdHJpZ2RlZmVycmVkLmMgfCAzICsrKwogbGliL2Rwa2cvdmFyYnVmLmMgICAg ICAgfCA4ICsrKysrLS0tCiBzcmMvbWFpbi5jICAgICAgICAgICAgICB8IDQgKysrLQogc3JjL3Vu cGFjay5jICAgICAgICAgICAgfCA4ICsrKysrKy0tCiA1IGZpbGVzIGNoYW5nZWQsIDIyIGluc2Vy dGlvbnMoKyksIDYgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvbGliL2Rwa2cvdGFyZm4uYyBi L2xpYi9kcGtnL3RhcmZuLmMKaW5kZXggYTA4MjFmMjE3Li5jNzU5OTE4ZTggMTAwNjQ0Ci0tLSBh L2xpYi9kcGtnL3RhcmZuLmMKKysrIGIvbGliL2Rwa2cvdGFyZm4uYwpAQCAtNDU4LDEwICs0NTgs MTMgQEAgdGFyX2V4dHJhY3RvcihzdHJ1Y3QgdGFyX2FyY2hpdmUgKnRhcikKIAloLmxpbmtuYW1l ID0gTlVMTDsKIAloLnN0YXQudW5hbWUgPSBOVUxMOwogCWguc3RhdC5nbmFtZSA9IE5VTEw7CisJ dGFyLT5lcnIuc3RyID0gTlVMTDsKIAogCXdoaWxlICgoc3RhdHVzID0gdGFyLT5vcHMtPnJlYWQo dGFyLCBidWZmZXIsIFRBUkJMS1NaKSkgPT0gVEFSQkxLU1opIHsKIAkJaW50IG5hbWVfbGVuOwog CisJCWlmKHRhci0+ZXJyLnN0ciAhPSBOVUxMKQorCQkJZnJlZSh0YXItPmVyci5zdHIpOwogCQlp ZiAodGFyX2hlYWRlcl9kZWNvZGUoKHN0cnVjdCB0YXJfaGVhZGVyICopYnVmZmVyLCAmaCwgJnRh ci0+ZXJyKSA8IDApIHsKIAkJCWlmIChoLm5hbWVbMF0gPT0gJ1wwJykgewogCQkJCS8qIEVuZCBP ZiBUYXBlLiAqLwpAQCAtNDg1LDYgKzQ4OCw4IEBAIHRhcl9leHRyYWN0b3Ioc3RydWN0IHRhcl9h cmNoaXZlICp0YXIpCiAJCX0KIAogCQlpZiAoaC5uYW1lWzBdID09ICdcMCcpIHsKKwkJCWlmKHRh ci0+ZXJyLnN0ciAhPSBOVUxMKQorCQkJCWZyZWUodGFyLT5lcnIuc3RyKTsKIAkJCXN0YXR1cyA9 IGRwa2dfcHV0X2Vycm9yKCZ0YXItPmVyciwKIAkJCSAgICAgICAgICAgICAgICAgICAgICAgIF8o ImludmFsaWQgdGFyIGhlYWRlciB3aXRoIGVtcHR5IG5hbWUgZmllbGQiKSk7CiAJCQllcnJubyA9 IDA7CmRpZmYgLS1naXQgYS9saWIvZHBrZy90cmlnZGVmZXJyZWQuYyBiL2xpYi9kcGtnL3RyaWdk ZWZlcnJlZC5jCmluZGV4IGI5YjAyOGY3My4uNzFkMDUwMzE4IDEwMDY0NAotLS0gYS9saWIvZHBr Zy90cmlnZGVmZXJyZWQuYworKysgYi9saWIvZHBrZy90cmlnZGVmZXJyZWQuYwpAQCAtODUsNiAr ODUsNyBAQCB0cmlnZGVmX3VwZGF0ZV9zdGFydChlbnVtIHRyaWdkZWZfdXBkYXRlX2ZsYWdzIHVm KQogCQkJCQlvaHNoaXRlKF8oInVuYWJsZSB0byBvcGVuL2NyZWF0ZSAiCiAJCQkJCSAgICAgICAg ICAidHJpZ2dlcnMgbG9jayBmaWxlICclLjI1MHMnIiksCiAJCQkJCSAgICAgICAgZm4uYnVmKTsK KwkJCQlmcmVlKHRyaWdnZXJzZGlyKTsKIAkJCQlyZXR1cm4gVERVU19FUlJPUl9OT19ESVI7CiAJ CQl9CiAJCX0KQEAgLTEyMSw2ICsxMjIsNyBAQCB0cmlnZGVmX3VwZGF0ZV9zdGFydChlbnVtIHRy aWdkZWZfdXBkYXRlX2ZsYWdzIHVmKQogCQlpZiAoc3RhYi5zdF9zaXplID09IDAgJiYgISh1ZiAm IFREVUZfV1JJVEVfSUZfRU1QVFkpKSB7CiAJCQlpZiAodWYgJiBURFVGX1dSSVRFKQogCQkJCXBv cF9jbGVhbnVwKGVoZmxhZ19ub3JtYWx0aWR5KTsKKwkJCWZyZWUodHJpZ2dlcnNkaXIpOwogCQkJ cmV0dXJuIFREVVNfRVJST1JfRU1QVFlfREVGRVJSRUQ7CiAJCX0KIAl9CkBAIC0xMzYsNiArMTM4 LDcgQEAgdHJpZ2RlZl91cGRhdGVfc3RhcnQoZW51bSB0cmlnZGVmX3VwZGF0ZV9mbGFncyB1ZikK IAogCQlzZXRjbG9leGVjKGZpbGVubyh0cmlnX25ld19kZWZlcnJlZCksIG5ld2ZuLmJ1Zik7CiAJ fQorCWZyZWUodHJpZ2dlcnNkaXIpOwogCiAJaWYgKCFvbGRfZGVmZXJyZWQpCiAJCXJldHVybiBU RFVTX05PX0RFRkVSUkVEOwpkaWZmIC0tZ2l0IGEvbGliL2Rwa2cvdmFyYnVmLmMgYi9saWIvZHBr Zy92YXJidWYuYwppbmRleCBlZTc1N2JjYzcuLmNjZTYxZjYxMiAxMDA2NDQKLS0tIGEvbGliL2Rw a2cvdmFyYnVmLmMKKysrIGIvbGliL2Rwa2cvdmFyYnVmLmMKQEAgLTk1LDkgKzk1LDExIEBAIHZh cmJ1Zl92cHJpbnRmKHN0cnVjdCB2YXJidWYgKnYsIGNvbnN0IGNoYXIgKmZtdCwgdmFfbGlzdCBh cmdzKQogdm9pZAogdmFyYnVmX2FkZF9idWYoc3RydWN0IHZhcmJ1ZiAqdiwgY29uc3Qgdm9pZCAq cywgc2l6ZV90IHNpemUpCiB7Ci0gIHZhcmJ1Zl9ncm93KHYsIHNpemUpOwotICBtZW1jcHkodi0+ YnVmICsgdi0+dXNlZCwgcywgc2l6ZSk7Ci0gIHYtPnVzZWQgKz0gc2l6ZTsKKyAgaWYoc2l6ZSl7 CisgICAgdmFyYnVmX2dyb3codiwgc2l6ZSk7CisgICAgbWVtY3B5KHYtPmJ1ZiArIHYtPnVzZWQs IHMsIHNpemUpOworICAgIHYtPnVzZWQgKz0gc2l6ZTsKKyAgfQogfQogCiB2b2lkCmRpZmYgLS1n aXQgYS9zcmMvbWFpbi5jIGIvc3JjL21haW4uYwppbmRleCAzNDgyZWQxZTIuLjVkM2VhZjBlYSAx MDA2NDQKLS0tIGEvc3JjL21haW4uYworKysgYi9zcmMvbWFpbi5jCkBAIC03ODEsOCArNzgxLDEw IEBAIGludCBtYWluKGludCBhcmdjLCBjb25zdCBjaGFyICpjb25zdCAqYXJndikgewogICAgIG9o c2hpdGUoXygidW5hYmxlIHRvIHNldGVudiBmb3Igc3VicHJvY2Vzc2VzIikpOwogICBpZiAoc2V0 ZW52KCJEUEtHX1JPT1QiLCBpbnN0ZGlyLCAxKSA8IDApCiAgICAgb2hzaGl0ZShfKCJ1bmFibGUg dG8gc2V0ZW52IGZvciBzdWJwcm9jZXNzZXMiKSk7Ci0gIGlmIChzZXRlbnYoIkRQS0dfRk9SQ0Ui LCBnZXRfZm9yY2Vfc3RyaW5nKCksIDEpIDwgMCkKKyAgY2hhciAqZm9yY2Vfc3RyaW5nID0gZ2V0 X2ZvcmNlX3N0cmluZygpOworICBpZiAoc2V0ZW52KCJEUEtHX0ZPUkNFIiwgZm9yY2Vfc3RyaW5n LCAxKSA8IDApCiAgICAgb2hzaGl0ZShfKCJ1bmFibGUgdG8gc2V0ZW52IGZvciBzdWJwcm9jZXNz ZXMiKSk7CisgIGZyZWUoZm9yY2Vfc3RyaW5nKTsKIAogICBpZiAoIWZfdHJpZ2dlcnMpCiAgICAg Zl90cmlnZ2VycyA9IChjaXBhY3Rpb24tPmFyZ19pbnQgPT0gYWN0X3RyaWdnZXJzICYmICphcmd2 KSA/IC0xIDogMTsKZGlmZiAtLWdpdCBhL3NyYy91bnBhY2suYyBiL3NyYy91bnBhY2suYwppbmRl eCA0YTE0MzY2NmUuLmU3M2ZhM2UyZSAxMDA2NDQKLS0tIGEvc3JjL3VucGFjay5jCisrKyBiL3Ny Yy91bnBhY2suYwpAQCAtMTExNCw3ICsxMTE0LDcgQEAgdm9pZCBwcm9jZXNzX2FyY2hpdmUoY29u c3QgY2hhciAqZmlsZW5hbWUpIHsKICAgICBkZWJfdmVyaWZ5KGZpbGVuYW1lKTsKIAogICAvKiBH ZXQgdGhlIGNvbnRyb2wgaW5mb3JtYXRpb24gZGlyZWN0b3J5LiAqLwotICBjaWRpciA9IGdldF9j b250cm9sX2RpcihjaWRpcik7CisgIGNpZGlyID0gZ2V0X2NvbnRyb2xfZGlyKGNpZGlyKTsgIC8v IHRvZG86IE1lbW9yeSBsZWFrISEhIGNhbm5vdCBmcmVlIGJlY2F1c2UgaXQgaXMgdXNlZCBhZnRl ciBleGl0dGluZyB0aGlzIGZ1bmMuCiAgIGNpZGlycmVzdCA9IGNpZGlyICsgc3RybGVuKGNpZGly KTsKICAgcHVzaF9jbGVhbnVwKGN1X2NpZGlyLCB+MCwgMiwgKHZvaWQgKiljaWRpciwgKHZvaWQg KiljaWRpcnJlc3QpOwogCkBAIC0xNDQzLDkgKzE0NDMsMTMgQEAgdm9pZCBwcm9jZXNzX2FyY2hp dmUoY29uc3QgY2hhciAqZmlsZW5hbWUpIHsKICAgdGFyLm9wcyA9ICZ0ZjsKIAogICByYyA9IHRh cl9leHRyYWN0b3IoJnRhcik7Ci0gIGlmIChyYykKKyAgaWYgKHJjKXsKICAgICBkcGtnX2Vycm9y X3ByaW50KCZ0YXIuZXJyLAogICAgICAgICAgICAgICAgICAgICAgXygiY29ycnVwdGVkIGZpbGVz eXN0ZW0gdGFyZmlsZSBpbiBwYWNrYWdlIGFyY2hpdmUiKSk7CisgIH0KKyAgaWYodGFyLmVyci5z dHIpIC8vIHRvZG86IGR1cmluZyBub3JtYWwgb3BlcmF0aW9uIG5vIGVycm9yIHN0cmluZ3Mgc2hv dWxkIGJlIHNldCEKKyAgICBmcmVlKHRhci5lcnIuc3RyKTsKKwogICBpZiAoZmRfc2tpcChwMVsw XSwgLTEsICZlcnIpIDwgMCkKICAgICBvaHNoaXQoXygiY2Fubm90IHphcCBwb3NzaWJsZSB0cmFp bGluZyB6ZXJvcyBmcm9tIGRwa2ctZGViOiAlcyIpLCBlcnIuc3RyKTsKICAgY2xvc2UocDFbMF0p Owo=

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Guillem Jover@21:1/5 to KOLANICH on Sun Aug 2 00:30:01 2020
    Hi!

    On Sun, 2020-07-26 at 23:54:44 +0300, KOLANICH wrote:
    I have implemented some fixes for some issues found by clang 12
    UBSan (or MemSan, os ASan, I don't remember now) and valgrind: https://github.com/guillemj/dpkg/pull/2.

    Thanks for the patches/report. It would have been more helpful to send
    each different fix in a separate patch, but no worries. See below for
    a review.

    From 62d2d15b57af5150965913c4fd98edd0c2d97dfe Mon Sep 17 00:00:00 2001
    From: KOLANICH <kolan_n@mail.ru>
    Date: Thu, 23 Jul 2020 16:37:06 +0300
    Subject: [PATCH] Fixed some memory leaks and UB

    diff --git a/lib/dpkg/tarfn.c b/lib/dpkg/tarfn.c
    index a0821f217..c759918e8 100644
    --- a/lib/dpkg/tarfn.c
    +++ b/lib/dpkg/tarfn.c
    @@ -458,10 +458,13 @@ tar_extractor(struct tar_archive *tar)
    h.linkname = NULL;
    h.stat.uname = NULL;
    h.stat.gname = NULL;
    + tar->err.str = NULL;

    while ((status = tar->ops->read(tar, buffer, TARBLKSZ)) == TARBLKSZ) {
    int name_len;

    + if(tar->err.str != NULL)
    + free(tar->err.str);
    if (tar_header_decode((struct tar_header *)buffer, &h, &tar->err) < 0) {
    if (h.name[0] == '\0') {
    /* End Of Tape. */
    @@ -485,6 +488,8 @@ tar_extractor(struct tar_archive *tar)
    }

    if (h.name[0] == '\0') {
    + if(tar->err.str != NULL)
    + free(tar->err.str);
    status = dpkg_put_error(&tar->err,
    _("invalid tar header with empty name field"));
    errno = 0;

    These seem incorrect. tar->err is supposed to be initialized on the
    call site (with DPKG_ERROR_OBJECT), which it is. Then there's never a
    need to check for NULL before calling free(). And in this case freeing
    these is unnecessary as any code path here that sets tar->err is
    supposed to make the loop stop and the function return.

    diff --git a/lib/dpkg/trigdeferred.c b/lib/dpkg/trigdeferred.c
    index b9b028f73..71d050318 100644
    --- a/lib/dpkg/trigdeferred.c
    +++ b/lib/dpkg/trigdeferred.c
    @@ -85,6 +85,7 @@ trigdef_update_start(enum trigdef_update_flags uf)
    ohshite(_("unable to open/create "
    "triggers lock file '%.250s'"),
    fn.buf);
    + free(triggersdir);
    return TDUS_ERROR_NO_DIR;
    }
    }
    @@ -121,6 +122,7 @@ trigdef_update_start(enum trigdef_update_flags uf)
    if (stab.st_size == 0 && !(uf & TDUF_WRITE_IF_EMPTY)) {
    if (uf & TDUF_WRITE)
    pop_cleanup(ehflag_normaltidy);
    + free(triggersdir);
    return TDUS_ERROR_EMPTY_DEFERRED;
    }
    }
    @@ -136,6 +138,7 @@ trigdef_update_start(enum trigdef_update_flags uf)

    setcloexec(fileno(trig_new_deferred), newfn.buf);
    }
    + free(triggersdir);

    if (!old_deferred)
    return TDUS_NO_DEFERRED;

    These are not really correct either, as the variable needs to be set
    at least for the _done function to be able to work. I've instead added
    a free() just immediately before the assignment.

    diff --git a/lib/dpkg/varbuf.c b/lib/dpkg/varbuf.c
    index ee757bcc7..cce61f612 100644
    --- a/lib/dpkg/varbuf.c
    +++ b/lib/dpkg/varbuf.c
    @@ -95,9 +95,11 @@ varbuf_vprintf(struct varbuf *v, const char *fmt, va_list args)
    void
    varbuf_add_buf(struct varbuf *v, const void *s, size_t size)
    {
    - varbuf_grow(v, size);
    - memcpy(v->buf + v->used, s, size);
    - v->used += size;
    + if(size){
    + varbuf_grow(v, size);
    + memcpy(v->buf + v->used, s, size);
    + v->used += size;
    + }
    }

    I don't see why the old code was wrong? All these should handle size
    being 0 just fine.

    void
    diff --git a/src/main.c b/src/main.c
    index 3482ed1e2..5d3eaf0ea 100644
    --- a/src/main.c
    +++ b/src/main.c
    @@ -781,8 +781,10 @@ int main(int argc, const char *const *argv) {
    ohshite(_("unable to setenv for subprocesses"));
    if (setenv("DPKG_ROOT", instdir, 1) < 0)
    ohshite(_("unable to setenv for subprocesses"));
    - if (setenv("DPKG_FORCE", get_force_string(), 1) < 0)
    + char *force_string = get_force_string();
    + if (setenv("DPKG_FORCE", force_string, 1) < 0)
    ohshite(_("unable to setenv for subprocesses"));
    + free(force_string);

    if (!f_triggers)
    f_triggers = (cipaction->arg_int == act_triggers && *argv) ? -1 : 1;

    Thanks, fixed locally now.

    diff --git a/src/unpack.c b/src/unpack.c
    index 4a143666e..e73fa3e2e 100644
    --- a/src/unpack.c
    +++ b/src/unpack.c
    @@ -1114,7 +1114,7 @@ void process_archive(const char *filename) {
    deb_verify(filename);

    /* Get the control information directory. */
    - cidir = get_control_dir(cidir);
    + cidir = get_control_dir(cidir); // todo: Memory leak!!! cannot free because it is used after exitting this func.
    cidirrest = cidir + strlen(cidir);
    push_cleanup(cu_cidir, ~0, 2, (void *)cidir, (void *)cidirrest);

    Right, thanks, I've added a free() within cu_cidir().

    @@ -1443,9 +1443,13 @@ void process_archive(const char *filename) {
    tar.ops = &tf;

    rc = tar_extractor(&tar);
    - if (rc)
    + if (rc){
    dpkg_error_print(&tar.err,
    _("corrupted filesystem tarfile in package archive")); + }
    + if(tar.err.str) // todo: during normal operation no error strings should be set!
    + free(tar.err.str);
    +
    if (fd_skip(p1[0], -1, &err) < 0)
    ohshit(_("cannot zap possible trailing zeros from dpkg-deb: %s"), err.str);
    close(p1[0]);

    This seems incorrect. If there's an error, dpkg_error_print() will also
    error out (and there are no warnings being generated here). The function
    name is a bit unfortunate, and I think I've pondered renaming it to
    something like dpkg_error_emit() or similar, but given that it could
    warn or error out depending on the error variable, that's still a bit
    fuzzy.

    Thanks,
    Guillem

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)