@@ -198,10 +198,39 @@ int PKCS7_set_type(PKCS7 *p7, int type) {
198198 return 0 ;
199199 }
200200
201+ // Free any previously-installed content using the current |p7->type| so the
202+ // correct destructor runs on the existing union member, instead of the new
203+ // type's destructor running on type-confused memory.
204+ if (p7 -> d .ptr != NULL ) {
205+ switch (OBJ_obj2nid (p7 -> type )) {
206+ case NID_pkcs7_signed :
207+ PKCS7_SIGNED_free (p7 -> d .sign );
208+ break ;
209+ case NID_pkcs7_digest :
210+ PKCS7_DIGEST_free (p7 -> d .digest );
211+ break ;
212+ case NID_pkcs7_data :
213+ ASN1_OCTET_STRING_free (p7 -> d .data );
214+ break ;
215+ case NID_pkcs7_signedAndEnveloped :
216+ PKCS7_SIGN_ENVELOPE_free (p7 -> d .signed_and_enveloped );
217+ break ;
218+ case NID_pkcs7_enveloped :
219+ PKCS7_ENVELOPE_free (p7 -> d .enveloped );
220+ break ;
221+ case NID_pkcs7_encrypted :
222+ PKCS7_ENCRYPT_free (p7 -> d .encrypted );
223+ break ;
224+ default :
225+ ASN1_TYPE_free (p7 -> d .other );
226+ break ;
227+ }
228+ p7 -> d .ptr = NULL ;
229+ }
230+
201231 switch (type ) {
202232 case NID_pkcs7_signed :
203233 p7 -> type = obj ;
204- PKCS7_SIGNED_free (p7 -> d .sign );
205234 p7 -> d .sign = PKCS7_SIGNED_new ();
206235 if (p7 -> d .sign == NULL ) {
207236 return 0 ;
@@ -214,7 +243,6 @@ int PKCS7_set_type(PKCS7 *p7, int type) {
214243 break ;
215244 case NID_pkcs7_digest :
216245 p7 -> type = obj ;
217- PKCS7_DIGEST_free (p7 -> d .digest );
218246 p7 -> d .digest = PKCS7_DIGEST_new ();
219247 if (p7 -> d .digest == NULL ) {
220248 return 0 ;
@@ -227,15 +255,13 @@ int PKCS7_set_type(PKCS7 *p7, int type) {
227255 break ;
228256 case NID_pkcs7_data :
229257 p7 -> type = obj ;
230- ASN1_OCTET_STRING_free (p7 -> d .data );
231258 p7 -> d .data = ASN1_OCTET_STRING_new ();
232259 if (p7 -> d .data == NULL ) {
233260 return 0 ;
234261 }
235262 break ;
236263 case NID_pkcs7_signedAndEnveloped :
237264 p7 -> type = obj ;
238- PKCS7_SIGN_ENVELOPE_free (p7 -> d .signed_and_enveloped );
239265 p7 -> d .signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new ();
240266 if (p7 -> d .signed_and_enveloped == NULL ) {
241267 return 0 ;
@@ -250,7 +276,6 @@ int PKCS7_set_type(PKCS7 *p7, int type) {
250276 break ;
251277 case NID_pkcs7_enveloped :
252278 p7 -> type = obj ;
253- PKCS7_ENVELOPE_free (p7 -> d .enveloped );
254279 p7 -> d .enveloped = PKCS7_ENVELOPE_new ();
255280 if (p7 -> d .enveloped == NULL ) {
256281 return 0 ;
@@ -264,7 +289,6 @@ int PKCS7_set_type(PKCS7 *p7, int type) {
264289 break ;
265290 case NID_pkcs7_encrypted :
266291 p7 -> type = obj ;
267- PKCS7_ENCRYPT_free (p7 -> d .encrypted );
268292 p7 -> d .encrypted = PKCS7_ENCRYPT_new ();
269293 if (p7 -> d .encrypted == NULL ) {
270294 return 0 ;
0 commit comments