I've been able to diagnose a SIGSEGV, and I have a workaround that
satisfies me.  I'm unsure how to fix it, so I'll describe the problem
and leave it at that.

Repro:

% notmuch --version
notmuch 0.25+22~g0967e46 (a recent git @HEAD)
% notmuch show --format=sexp --decrypt thread:000000000002ad2c
-> SIGSEGV

Workaround:

Don't pass --decrypt.  In Emacs, configure notmuch-crypto-process-mime
to shut off crypto processing, or C-u before in notmuch-show before
viewing a problematic thread.

Diagnosis:

mime-node.c's _mime_node_create() can return NULL in various scenarios
yet few to none of its callers appear to handle it properly.  In this
particular case, the NULL is returned here:

#if (GMIME_MAJOR_VERSION < 3)
    if ((GMIME_IS_MULTIPART_ENCRYPTED (part) && node->ctx->crypto->decrypt)
        || (GMIME_IS_MULTIPART_SIGNED (part) && node->ctx->crypto->verify)) {
        GMimeContentType *content_type = g_mime_object_get_content_type (part);
        const char *protocol = g_mime_content_type_get_parameter (content_type, 
"protocol");
        cryptoctx = notmuch_crypto_get_context (node->ctx->crypto, protocol);
        if (!cryptoctx) {
            return NULL;
        }
    }
#endif

Note above a missing call to talloc_free(node) before the return, which
suggests a kind of bit-rot has set in for the GMIME_MAJOR_VERSION<3
case?  Anyway...

mime_node_child() calls _mime_node_create() and will SIGSEGV:

    node = _mime_node_create (parent, sub);

    if (child == parent->next_child && parent->next_part_num != -1) {
        /* We're traversing in depth-first order.  Record the child's
         * depth-first numbering. */
        node->part_num = parent->next_part_num;
        node->next_part_num = node->part_num + 1;


If I address that by returning NULL from mime_node_child() when
_mime_node_create() does, then the problem cascades to callers.  None of
the callers of mime_node_child() explicitly handle the NULL return case:

mime-node.c:            mime_node_t *child = mime_node_child (node, i);
notmuch-show.c:571:     format_part_text (ctx, sp, mime_node_child (node, i), 
indent, params);
notmuch-show.c:622:         format_part_sprinter (ctx, sp, mime_node_child 
(node, 0), first, TRUE, include_html);
notmuch-show.c:724:     format_part_sprinter (ctx, sp, mime_node_child (node, 
i), i == 0, TRUE, include_html);

..._mime_node_seek_dfs_walk will proceed to SIGSEGV, and so will
format_part_...().
_______________________________________________
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch

Reply via email to