From 4f37820334fadd8c5036ea6c42f3dc242665c4a9 Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Fri, 21 Aug 2015 10:38:41 +0200 Subject: [PATCH] common: Don't assume on-disk layout matches in-memory layout. * g10/packet.h (PKT_signature): Change revkey's type from a struct revocation_key ** to a struct revocation_key *. Update users. -- revkey was a pointer into the raw data. But, C doesn't guarantee that there is no padding. Thus, we copy the data. Signed-off-by: Neal H. Walfield . --- g10/export.c | 2 +- g10/getkey.c | 4 ++-- g10/import.c | 8 ++++---- g10/packet.h | 2 +- g10/parse-packet.c | 24 +++++++++++++++--------- g10/revoke.c | 6 +++--- 6 files changed, 26 insertions(+), 20 deletions(-) diff --git a/g10/export.c b/g10/export.c index 505012856..62802d394 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1011,7 +1011,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, int i; for (i=0;ipkt->pkt.signature->numrevkeys;i++) - if ( (node->pkt->pkt.signature->revkey[i]->class & 0x40)) + if ( (node->pkt->pkt.signature->revkey[i].class & 0x40)) break; if (i < node->pkt->pkt.signature->numrevkeys) diff --git a/g10/getkey.c b/g10/getkey.c index 3a6016113..6e8583496 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -720,7 +720,7 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk, ANYLOCALFIRST is set if the search order has the local method before any other or if "local" is used first by default. This - makes sure that if a RETCTX is used it gets only set if a local + makes sure that if a RETCTX is used it is only set if a local search has precedence over the other search methods and only then a followup call to get_pubkey_next shall succeed. */ if (!no_akl) @@ -1606,7 +1606,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked, for (i = 0; i < sig->numrevkeys; i++) memcpy (&pk->revkey[pk->numrevkeys++], - sig->revkey[i], + &sig->revkey[i], sizeof (struct revocation_key)); } diff --git a/g10/import.c b/g10/import.c index e92769dc8..60a037bdf 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2397,7 +2397,7 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock) { u32 keyid[2]; - keyid_from_fingerprint(sig->revkey[idx]->fpr, + keyid_from_fingerprint(sig->revkey[idx].fpr, MAX_FINGERPRINT_LEN,keyid); for(inode=keyblock->next;inode;inode=inode->next) @@ -2416,7 +2416,7 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock) itself? */ int rc; - rc=get_pubkey_byfprint_fast (NULL,sig->revkey[idx]->fpr, + rc=get_pubkey_byfprint_fast (NULL,sig->revkey[idx].fpr, MAX_FINGERPRINT_LEN); if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY || gpg_err_code (rc) == GPG_ERR_UNUSABLE_PUBKEY) @@ -2432,13 +2432,13 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock) " fetching revocation key %s\n"), tempkeystr,keystr(keyid)); keyserver_import_fprint (ctrl, - sig->revkey[idx]->fpr, + sig->revkey[idx].fpr, MAX_FINGERPRINT_LEN, opt.keyserver); /* Do we have it now? */ rc=get_pubkey_byfprint_fast (NULL, - sig->revkey[idx]->fpr, + sig->revkey[idx].fpr, MAX_FINGERPRINT_LEN); } diff --git a/g10/packet.h b/g10/packet.h index 8bd5fc458..826963e40 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -167,7 +167,7 @@ typedef struct byte trust_depth; byte trust_value; const byte *trust_regexp; - struct revocation_key **revkey; + struct revocation_key *revkey; int numrevkeys; pka_info_t *pka_info; /* Malloced PKA data or NULL if not available. See also flags.pka_tried. */ diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 1467dc32a..bc9965331 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1711,25 +1711,31 @@ parse_sig_subpkt2 (PKT_signature * sig, sigsubpkttype_t reqtype) void parse_revkeys (PKT_signature * sig) { - struct revocation_key *revkey; + const byte *revkey; int seq = 0; size_t len; if (sig->sig_class != 0x1F) return; - while ((revkey = - (struct revocation_key *) enum_sig_subpkt (sig->hashed, - SIGSUBPKT_REV_KEY, - &len, &seq, NULL))) + while ((revkey = enum_sig_subpkt (sig->hashed, SIGSUBPKT_REV_KEY, + &len, &seq, NULL))) { - if (len == sizeof (struct revocation_key) - && (revkey->class & 0x80)) /* 0x80 bit must be set. */ + if (/* The only valid length is 22 bytes. See RFC 4880 + 5.2.3.15. */ + len == 22 + /* 0x80 bit must be set on the class. */ + && (revkey[0] & 0x80)) { sig->revkey = xrealloc (sig->revkey, - sizeof (struct revocation_key *) * + sizeof (struct revocation_key) * (sig->numrevkeys + 1)); - sig->revkey[sig->numrevkeys] = revkey; + + /* Copy the individual fields. */ + sig->revkey[sig->numrevkeys].class = revkey[0]; + sig->revkey[sig->numrevkeys].algid = revkey[1]; + memcpy (sig->revkey[sig->numrevkeys].fpr, &revkey[2], 20); + sig->numrevkeys++; } } diff --git a/g10/revoke.c b/g10/revoke.c index 6e82187fc..eb3a989c0 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -383,11 +383,11 @@ gen_desig_revoke( const char *uname, strlist_t locusr ) for(j=0;jpkt->pkt.signature->numrevkeys;j++) { if(pk->revkey[i].class== - signode->pkt->pkt.signature->revkey[j]->class && + signode->pkt->pkt.signature->revkey[j].class && pk->revkey[i].algid== - signode->pkt->pkt.signature->revkey[j]->algid && + signode->pkt->pkt.signature->revkey[j].algid && memcmp(pk->revkey[i].fpr, - signode->pkt->pkt.signature->revkey[j]->fpr, + signode->pkt->pkt.signature->revkey[j].fpr, MAX_FINGERPRINT_LEN)==0) { revkey=signode->pkt->pkt.signature;