vlm / asn1c

The ASN.1 Compiler
http://lionet.info/asn1c/
BSD 2-Clause "Simplified" License
1.04k stars 555 forks source link

Error on asn_check_constraint function #359

Open edbunet opened 4 years ago

edbunet commented 4 years ago

Hello, I'm working with ETSI ITS messages for security (ETSI TS 103 097 V1.3.1). In the specific, I have some problem about the code generated for checking the constraints based on the EtsiTs103097Module.asn that can be download from this link https://forge.etsi.org/rep/ITS/ITS_ASN1/tree/master/SEC_TS103097

My problem is about the EtsiTs103097Data component whose definition is the following:

EtsiTs103097Data::=Ieee1609Dot2Data (WITH COMPONENTS {..., 
  content (WITH COMPONENTS {...,
    signedData (WITH COMPONENTS {..., -- constraints on signed data headers
      tbsData (WITH COMPONENTS {              
        headerInfo (WITH COMPONENTS {...,
          generationTime PRESENT,
          p2pcdLearningRequest ABSENT,
          missingCrlIdentifier ABSENT
        })
      }),
      signer (WITH COMPONENTS {...,  --constraints on the certificate
        certificate (SIZE(1))
      })
    }),
    encryptedData (WITH COMPONENTS {..., -- constraints on encrypted data headers
      recipients  (WITH COMPONENT (
        (WITH COMPONENTS {..., 
          pskRecipInfo ABSENT,
          symmRecipInfo ABSENT,
          rekRecipInfo ABSENT
        })
      ))
    }),
    signedCertificateRequest ABSENT
  })
})

The problem is that when I checks the constraints of this module using the asn_check_constraints function, the code enters in an infinite loop that ends with a core dump. The issue seems to be in the following function that is in the generated EtsiTs103097Data.c file:

int
EtsiTs103097Data_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
            asn_app_constraint_failed_f *ctfailcb, void *app_key) { 
    if(!sptr) {
        ASN__CTFAIL(app_key, td, sptr,
            "%s: value not given (%s:%d)",
            td->name, __FILE__, __LINE__);
        return -1;
    }

    if(1 /* No applicable constraints whatsoever */) {
        /* Nothing is here. See below */
    }

    return td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key);
}

The variable asn_TYPE_descriptor_t *td seems to me that has not the encoding_constraints field, but in the code it tried to access it the same.

Does anyone else encounter the same problem? Is it a problem of the definition of ASN.1 module or of the compiler?

I thank you in advance for any explanation and suggestion for solving the issue.

velichkov commented 4 years ago

Hi @edbunet,

I'm working with ETSI ITS messages for security (ETSI TS 103 097 V1.3.1). In the specific, I have some problem about the code generated for checking the constraints based on the EtsiTs103097Module.asn that can be download from this link https://forge.etsi.org/rep/ITS/ITS_ASN1/tree/master/SEC_TS103097

Can you provide all the commands you've used to compile these ASN.1 files?

My problem is about the EtsiTs103097Data component whose definition is the following:

EtsiTs103097Data::=Ieee1609Dot2Data (WITH COMPONENTS {..., 
  content (WITH COMPONENTS {...,
    signedData (WITH COMPONENTS {..., -- constraints on signed data headers
      tbsData (WITH COMPONENTS {              
        headerInfo (WITH COMPONENTS {...,
          generationTime PRESENT,
          p2pcdLearningRequest ABSENT,
          missingCrlIdentifier ABSENT
        })
      }),
      signer (WITH COMPONENTS {...,  --constraints on the certificate
        certificate (SIZE(1))
      })
    }),
    encryptedData (WITH COMPONENTS {..., -- constraints on encrypted data headers
      recipients  (WITH COMPONENT (
        (WITH COMPONENTS {..., 
          pskRecipInfo ABSENT,
          symmRecipInfo ABSENT,
          rekRecipInfo ABSENT
        })
      ))
    }),
    signedCertificateRequest ABSENT
  })
})

The problem is that when I checks the constraints of this module using the asn_check_constraints function, the code enters in an infinite loop that ends with a core dump.

Can you provide an example binary and commands/code with which this problem can be reproduced?

The issue seems to be in the following function that is in the generated EtsiTs103097Data.c file:

int
EtsiTs103097Data_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
          asn_app_constraint_failed_f *ctfailcb, void *app_key) { 
  if(!sptr) {
      ASN__CTFAIL(app_key, td, sptr,
          "%s: value not given (%s:%d)",
          td->name, __FILE__, __LINE__);
      return -1;
  }

  if(1 /* No applicable constraints whatsoever */) {
      /* Nothing is here. See below */
  }

  return td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key);
}

The variable asn_TYPE_descriptor_t *td seems to me that has not the encoding_constraints field,

Why do you think that? Can you check with gdb what's the value?

but in the code it tried to access it the same.

Does anyone else encounter the same problem? Is it a problem of the definition of ASN.1 module or of the compiler?

I thank you in advance for any explanation and suggestion for solving the issue.

Rebuild with -DASN_EMIT_DEBUG=1 in CFLAGS to get some more debug output.

edbunet commented 4 years ago

Hello @velichkov,

please find in line the answers to your questions.

Hi @edbunet,

I'm working with ETSI ITS messages for security (ETSI TS 103 097 V1.3.1). In the specific, I have some problem about the code generated for checking the constraints based on the EtsiTs103097Module.asn that can be download from this link https://forge.etsi.org/rep/ITS/ITS_ASN1/tree/master/SEC_TS103097

Can you provide all the commands you've used to compile these ASN.1 files?

I used the following command ./asn1c -gen-PER -fnative-types -fcompound-names -pdu=all EtsiTs103097Module.asn IEEE1609dot2.asn IEEE1609dot2BaseTypes.asn

All the ASN.1 files can be downloaded from the link that I provided in the previous post

My problem is about the EtsiTs103097Data component whose definition is the following:

EtsiTs103097Data::=Ieee1609Dot2Data (WITH COMPONENTS {..., 
  content (WITH COMPONENTS {...,
    signedData (WITH COMPONENTS {..., -- constraints on signed data headers
      tbsData (WITH COMPONENTS {              
        headerInfo (WITH COMPONENTS {...,
          generationTime PRESENT,
          p2pcdLearningRequest ABSENT,
          missingCrlIdentifier ABSENT
        })
      }),
      signer (WITH COMPONENTS {...,  --constraints on the certificate
        certificate (SIZE(1))
      })
    }),
    encryptedData (WITH COMPONENTS {..., -- constraints on encrypted data headers
      recipients  (WITH COMPONENT (
        (WITH COMPONENTS {..., 
          pskRecipInfo ABSENT,
          symmRecipInfo ABSENT,
          rekRecipInfo ABSENT
        })
      ))
    }),
    signedCertificateRequest ABSENT
  })
})

The problem is that when I checks the constraints of this module using the asn_check_constraints function, the code enters in an infinite loop that ends with a core dump.

Can you provide an example binary and commands/code with which this problem can be reproduced?

The problem can be reproduced with the following code. It is very minimal code but the problem can be reproduced.

char errbuf[255];
size_t errlen = sizeof(errbuf);
EtsiTs103097Data_t msg;
int result = asn_check_constraints(&asn_DEF_EtsiTs103097Data, &msg, errbuf, &errlen);

The issue seems to be in the following function that is in the generated EtsiTs103097Data.c file:

int
EtsiTs103097Data_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
            asn_app_constraint_failed_f *ctfailcb, void *app_key) { 
    if(!sptr) {
        ASN__CTFAIL(app_key, td, sptr,
            "%s: value not given (%s:%d)",
            td->name, __FILE__, __LINE__);
        return -1;
    }

    if(1 /* No applicable constraints whatsoever */) {
        /* Nothing is here. See below */
    }

    return td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key);
}

The variable asn_TYPE_descriptor_t *td seems to me that has not the encoding_constraints field,

Why do you think that? Can you check with gdb what's the value?

I checked the definition of the structure asn_TYPE_descriptor and the encoding_constraints field is not present. I insert in the following the definition of the structure as_TYPE_descriptor_t that I have in my generated code.

typedef struct asn_TYPE_descriptor_s {
char *name; /* A name of the ASN.1 type. "" in some cases. */
char *xml_tag; /* Name used in XML tag */

/*
* Generalized functions for dealing with the specific type.
* May be directly invoked by applications.
*/
asn_struct_free_f  *free_struct; /* Free the structure */
asn_struct_print_f *print_struct; /* Human readable output */
asn_constr_check_f *check_constraints; /* Constraints validator */
ber_type_decoder_f *ber_decoder; /* Generic BER decoder */
der_type_encoder_f *der_encoder; /* Canonical DER encoder */
xer_type_decoder_f *xer_decoder; /* Generic XER decoder */
xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */
per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */

/***********************************************************************
* Internally useful members. Not to be used by applications directly. *
**********************************************************************/

/*
* Tags that are expected to occur.
*/
asn_outmost_tag_f  *outmost_tag; /* <optional, internal> */
ber_tlv_tag_t *tags; /* Effective tags sequence for this type */
int tags_count; /* Number of tags which are expected */
ber_tlv_tag_t *all_tags;/* Every tag for BER/containment */
int all_tags_count; /* Number of tags */

asn_per_constraints_t *per_constraints; /* PER compiled constraints */

/*
* An ASN.1 production type members (members of SEQUENCE, SET, CHOICE).
*/
struct asn_TYPE_member_s *elements;
int elements_count;

/*
* Additional information describing the type, used by appropriate
* functions above.
*/
void *specifics;
} asn_TYPE_descriptor_t;

Concerning gdb I provide following lines, basically it seems that it call recursively the EtsiTs103097Data_constraint() function until there is the core dump.

#0  0x000000000041ec0d in EtsiTs103097Data_constraint ()
#1  0x000000000041ec0f in EtsiTs103097Data_constraint ()
...
#174647 0x000000000041ec0f in EtsiTs103097Data_constraint ()
#174648 0x000000000041ec0f in EtsiTs103097Data_constraint ()
#174649 0x000000000041e76d in asn_check_constraints ()

I rebuilt with debug information enabled and no debug output is provided using the command lines that I provided. I checked and the debug is really enabled since with other code, the debug information is displayed.

I modified the EtsiTs103097Data_constraint() function to avoid that it performs the line return td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key);in such a way that it just returns a fixed value (return 1;) and the error is solved.

I also tried to print the value returned by td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key)in the following way

printf("before encoding_constraints\n");
int ret = td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key);
printf("ret value is %d\n", ret);

no value is never printed, it just prints "before encoding_constraints" for several times, like that the EtsiTs103097Data_constraint() function is recursively called by the line of code td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key)

but in the code it tried to access it the same. Does anyone else encounter the same problem? Is it a problem of the definition of ASN.1 module or of the compiler? I thank you in advance for any explanation and suggestion for solving the issue.

Rebuild with -DASN_EMIT_DEBUG=1 in CFLAGS to get some more debug output.