From aabbe4fe034c2dd69b372e4cf4394c7fb4367dd3 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Thu, 7 Aug 2008 00:13:58 +0000 Subject: [PATCH] Rewrite tagnum-checking code to streamline normal path and push refined error code selection into error path. Don't expand asn1buf_insert_octet inline or define asn1buf_ensure_space macro if CONFIG_SMALL. Remove some null-before-free checks. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20626 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/asn.1/asn1_k_decode.c | 15 +++++++++++---- src/lib/krb5/asn.1/asn1buf.c | 6 +++--- src/lib/krb5/asn.1/asn1buf.h | 4 +++- src/lib/krb5/asn.1/krb5_decode.c | 25 +++++++++++++++---------- src/lib/krb5/asn.1/ldap_key_seq.c | 23 ++++++++--------------- 5 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c index bad4b005f..ad4539eb9 100644 --- a/src/lib/krb5/asn.1/asn1_k_decode.c +++ b/src/lib/krb5/asn.1/asn1_k_decode.c @@ -102,6 +102,15 @@ if (!taglen && indef) { get_eoc(); } \ next_tag() +/* + * error_if_bad_tag + * + * Checks that the next tag is the expected one; returns with an error + * if not. + */ +#define error_if_bad_tag(tagexpect) \ + if (tagnum != (tagexpect)) { return (tagnum < (tagexpect)) ? ASN1_MISPLACED_FIELD : ASN1_MISSING_FIELD; } + /* * get_field * @@ -110,8 +119,7 @@ * verification of tag numbers. */ #define get_field(var, tagexpect, decoder) \ - if (tagnum > (tagexpect)) return ASN1_MISSING_FIELD; \ - if (tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD; \ + error_if_bad_tag(tagexpect); \ if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ && (tagnum || taglen || asn1class != UNIVERSAL)) \ return ASN1_BAD_ID; \ @@ -146,8 +154,7 @@ /* similar to get_field_body */ #define get_lenfield(len, var, tagexpect, decoder) \ - if (tagnum > (tagexpect)) return ASN1_MISSING_FIELD; \ - if (tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD; \ + error_if_bad_tag(tagexpect); \ if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ && (tagnum || taglen || asn1class != UNIVERSAL)) \ return ASN1_BAD_ID; \ diff --git a/src/lib/krb5/asn.1/asn1buf.c b/src/lib/krb5/asn.1/asn1buf.c index 8baac2424..c78f4b966 100644 --- a/src/lib/krb5/asn.1/asn1buf.c +++ b/src/lib/krb5/asn.1/asn1buf.c @@ -143,7 +143,7 @@ asn1_error_code asn1buf_skiptail(asn1buf *buf, const unsigned int length, const asn1_error_code asn1buf_destroy(asn1buf **buf) { if (*buf != NULL) { - if ((*buf)->base != NULL) free((*buf)->base); + free((*buf)->base); free(*buf); *buf = NULL; } @@ -273,7 +273,7 @@ asn1_error_code asn12krb5_buf(const asn1buf *buf, krb5_data **code) asn1_error_code asn1buf_unparse(const asn1buf *buf, char **s) { - if(*s != NULL) free(*s); + free(*s); if(buf == NULL){ *s = malloc(sizeof("")); if(*s == NULL) return ENOMEM; @@ -301,7 +301,7 @@ asn1_error_code asn1buf_hex_unparse(const asn1buf *buf, char **s) ((d)<=15 ? ('A'+(d)-10) :\ 'X')) - if(*s != NULL) free(*s); + free(*s); if(buf == NULL){ *s = malloc(sizeof("")); diff --git a/src/lib/krb5/asn.1/asn1buf.h b/src/lib/krb5/asn.1/asn1buf.h index c9c956adf..4936ed670 100644 --- a/src/lib/krb5/asn.1/asn1buf.h +++ b/src/lib/krb5/asn.1/asn1buf.h @@ -39,10 +39,12 @@ asn1_error_code asn1buf_ensure_space effects If buf has less than amount octets of free space, then it is expanded to have at least amount octets of free space. Returns ENOMEM memory is exhausted. */ +#ifndef CONFIG_SMALL #define asn1buf_ensure_space(buf,amount) \ ((asn1buf_free(buf) < (amount)) \ ? (asn1buf_expand((buf), (amount)-asn1buf_free(buf))) \ : 0) +#endif asn1_error_code asn1buf_expand @@ -146,7 +148,7 @@ asn1_error_code asn1buf_insert_octet /* requires *buf is allocated effects Inserts o into the buffer *buf, expanding the buffer if necessary. Returns ENOMEM memory is exhausted. */ -#if ((__GNUC__ >= 2) && !defined(ASN1BUF_OMIT_INLINE_FUNCS)) +#if ((__GNUC__ >= 2) && !defined(ASN1BUF_OMIT_INLINE_FUNCS)) && !defined(CONFIG_SMALL) extern __inline__ asn1_error_code asn1buf_insert_octet(asn1buf *buf, const int o) { asn1_error_code retval; diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c index cbd6a1294..ea21f7e49 100644 --- a/src/lib/krb5/asn.1/krb5_decode.c +++ b/src/lib/krb5/asn.1/krb5_decode.c @@ -1,7 +1,7 @@ /* * src/lib/krb5/asn.1/krb5_decode.c * - * Copyright 1994 by the Massachusetts Institute of Technology. + * Copyright 1994, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -130,13 +130,21 @@ if(retval) clean_return(retval);\ if (indef) { get_eoc(); }\ next_tag() +/* + * error_if_bad_tag + * + * Checks that the next tag is the expected one; returns with an error + * if not. + */ +#define error_if_bad_tag(tagexpect) \ + if (tagnum != (tagexpect)) { clean_return ((tagnum < (tagexpect)) ? ASN1_MISPLACED_FIELD : ASN1_MISSING_FIELD); } + /* decode a field (<[UNIVERSAL id]> ) check that the id number == tagexpect then decode into var get the next tag */ #define get_field(var,tagexpect,decoder)\ -if(tagnum > (tagexpect)) clean_return(ASN1_MISSING_FIELD);\ -if(tagnum < (tagexpect)) clean_return(ASN1_MISPLACED_FIELD);\ +error_if_bad_tag(tagexpect);\ if(asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\ clean_return(ASN1_BAD_ID);\ get_field_body(var,decoder) @@ -160,8 +168,7 @@ next_tag() /* decode a field w/ its length (for string types) */ #define get_lenfield(len,var,tagexpect,decoder)\ -if(tagnum > (tagexpect)) clean_return(ASN1_MISSING_FIELD);\ -if(tagnum < (tagexpect)) clean_return(ASN1_MISPLACED_FIELD);\ +error_if_bad_tag(tagexpect);\ if(asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\ clean_return(ASN1_BAD_ID);\ get_lenfield_body(len,var,decoder) @@ -197,7 +204,7 @@ error_out: \ #define cleanup_manual()\ return 0; -#define free_field(rep,f) if ((rep)->f) free((rep)->f) +#define free_field(rep,f) free((rep)->f) #define clear_field(rep,f) (*(rep))->f = 0 krb5_error_code decode_krb5_authenticator(const krb5_data *code, krb5_authenticator **rep) @@ -1034,10 +1041,8 @@ krb5_error_code decode_krb5_reply_key_pack(const krb5_data *code, krb5_reply_key cleanup_manual(); error_out: if (rep && *rep) { - if ((*rep)->replyKey.contents) - free((*rep)->replyKey.contents); - if ((*rep)->asChecksum.contents) - free((*rep)->asChecksum.contents); + free((*rep)->replyKey.contents); + free((*rep)->asChecksum.contents); free(*rep); *rep = NULL; } diff --git a/src/lib/krb5/asn.1/ldap_key_seq.c b/src/lib/krb5/asn.1/ldap_key_seq.c index b910e721d..6d0ef1a63 100644 --- a/src/lib/krb5/asn.1/ldap_key_seq.c +++ b/src/lib/krb5/asn.1/ldap_key_seq.c @@ -206,8 +206,7 @@ last: asn1buf_destroy (&buf); if (ret != 0 && *code != NULL) { - if ((*code)->data != NULL) - free ((*code)->data); + free ((*code)->data); free (*code); } @@ -301,7 +300,7 @@ decode_tagged_octetstring (asn1buf *buf, asn1_tagnum expectedtag, int *len, *buf = tmp; last: - if (ret != 0 && *val != NULL) + if (ret != 0) free (*val); return ret; } @@ -379,14 +378,10 @@ static asn1_error_code asn1_decode_key(asn1buf *buf, krb5_key_data *key) last: if (ret != 0) { - if (key->key_data_contents[0] != NULL) { - free (key->key_data_contents[0]); - key->key_data_contents[0] = NULL; - } - if (key->key_data_contents[1] != NULL) { - free (key->key_data_contents[1]); - key->key_data_contents[1] = NULL; - } + free (key->key_data_contents[0]); + key->key_data_contents[0] = NULL; + free (key->key_data_contents[1]); + key->key_data_contents[1] = NULL; } return ret; } @@ -467,10 +462,8 @@ last: if (ret != 0) { int i; for (i = 0; i < *n_key_data; i++) { - if ((*out)[i].key_data_contents[0] != NULL) - free ((*out)[i].key_data_contents[0]); - if ((*out)[i].key_data_contents[1] != NULL) - free ((*out)[i].key_data_contents[1]); + free ((*out)[i].key_data_contents[0]); + free ((*out)[i].key_data_contents[1]); } free (*out); *out = NULL; -- 2.26.2