• Eric Biggers's avatar
    X.509: reject invalid BIT STRING for subjectPublicKey · 0f30cbea
    Eric Biggers authored
    Adding a specially crafted X.509 certificate whose subjectPublicKey
    ASN.1 value is zero-length caused x509_extract_key_data() to set the
    public key size to SIZE_MAX, as it subtracted the nonexistent BIT STRING
    metadata byte.  Then, x509_cert_parse() called kmemdup() with that bogus
    size, triggering the WARN_ON_ONCE() in kmalloc_slab().
    
    This appears to be harmless, but it still must be fixed since WARNs are
    never supposed to be user-triggerable.
    
    Fix it by updating x509_cert_parse() to validate that the value has a
    BIT STRING metadata byte, and that the byte is 0 which indicates that
    the number of bits in the bitstring is a multiple of 8.
    
    It would be nice to handle the metadata byte in asn1_ber_decoder()
    instead.  But that would be tricky because in the general case a BIT
    STRING could be implicitly tagged, and/or could legitimately have a
    length that is not a whole number of bytes.
    
    Here was the WARN (cleaned up slightly):
    
        WARNING: CPU: 1 PID: 202 at mm/slab_common.c:971 kmalloc_slab+0x5d/0x70 mm/slab_common.c:971
        Modules linked in:
        CPU: 1 PID: 202 Comm: keyctl Tainted: G    B            4.14.0-09238-g1d3b78bb #26
        Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-20171110_100015-anatol 04/01/2014
        task: ffff880033014180 task.stack: ffff8800305c8000
        Call Trace:
         __do_kmalloc mm/slab.c:3706 [inline]
         __kmalloc_track_caller+0x22/0x2e0 mm/slab.c:3726
         kmemdup+0x17/0x40 mm/util.c:118
         kmemdup include/linux/string.h:414 [inline]
         x509_cert_parse+0x2cb/0x620 crypto/asymmetric_keys/x509_cert_parser.c:106
         x509_key_preparse+0x61/0x750 crypto/asymmetric_keys/x509_public_key.c:174
         asymmetric_key_preparse+0xa4/0x150 crypto/asymmetric_keys/asymmetric_type.c:388
         key_create_or_update+0x4d4/0x10a0 security/keys/key.c:850
         SYSC_add_key security/keys/keyctl.c:122 [inline]
         SyS_add_key+0xe8/0x290 security/keys/keyctl.c:62
         entry_SYSCALL_64_fastpath+0x1f/0x96
    
    Fixes: 42d5ec27 ("X.509: Add an ASN.1 decoder")
    Cc: <stable@vger.kernel.org> # v3.7+
    Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    Reviewed-by: default avatarJames Morris <james.l.morris@oracle.com>
    0f30cbea
x509_cert_parser.c 15.9 KB