Signed overflow in cbor_value_get_int64() / cbor_value_get_int() for out-of-range negative integers

Ouverte Adaptée aux débutants
#347 2 commentaires 0 réactions 1 personne assignée Voir sur GitHub

@thiagomacieira y travaille déjà.

Depuis le 26/10/2026.

  • #349 par @thiagomacieira — ouverte

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
78/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
c
Domaine
backend

Piste de recherche

Les fonctions concernées sont cbor_value_get_int64() et cbor_value_get_int() dans src/cbor.h ; commencez par lire leur traitement des entiers négatifs et la documentation sur la conversion sans vérification. Reproduisez les cas limites signalés avec UndefinedBehaviorSanitizer, puis ajoutez des tests pour les deux entrées. Le travail est terminé lorsque les deux fonctions évitent le débordement d’entiers signés et que les tests passent avec le sanitizer.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

cbor_value_get_int64() and cbor_value_get_int() in src/cbor.h do

*result = -*result - 1;

for negative integers. If the encoded magnitude is 2^63 (or 2^31 for the int version), *result is already INT64_MIN / INT_MIN at that point, so the negation overflows. That's UB, and it's reachable from untrusted input through the public API. The only precondition is cbor_value_is_integer(), which these inputs satisfy.

Inputs:

  • 3b 80 00 00 00 00 00 00 00, i.e. -2^63 - 1, hits cbor_value_get_int64()
  • 3a 80 00 00 00, i.e. -2^31 - 1, hits cbor_value_get_int()

With clang -fsanitize=undefined on current main (da6421f):

src/cbor.h:437:19: runtime error: negation of -9223372036854775808 cannot be represented in type 'int64_t' (aka 'long')
src/cbor.h:446:19: runtime error: negation of -2147483648 cannot be represented in type 'int'

Minimal repro:

#include <stdio.h>
#include <stdint.h>
#include "cbor.h"

int main(void)
{
    static const uint8_t data[] = { 0x3b, 0x80, 0, 0, 0, 0, 0, 0, 0 };
    CborParser parser;
    CborValue it;
    int64_t v;
    if (cbor_parser_init(data, sizeof(data), 0, &parser, &it) || !cbor_value_is_integer(&it))
        return 1;
    cbor_value_get_int64(&it, &v);
    printf("%lld\n", (long long)v);
    return 0;
}

I know the docs say to use the _checked variants if the value might not fit, and those are fine. But the unchecked ones are documented as returning a truncated value in that case, not as UB, and in practice a sanitizer build aborts. An optimising compiler is also free to assume the overflow can't happen.

I ran into this while writing CBMC harnesses and fuzzing tinycbor. Happy to open a PR with a fix (~*result instead of -*result - 1, same value, no overflow) and a test if that sounds good.

Langage dominant
C++
Étoiles
641
Forks
225
Merge moyen
2 j 3 h
PR mergées (30 j)
4

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de intel/tinycbor

Toutes les issues de intel/tinycbor

Issues similaires

Plus d'issues C++

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.