Fix bug where freed OIDs could be accessed in EVP_cleanup() by
[openssl.git] / crypto / objects / obj_dat.c
index 9c61829c77dfefde057dd42eef9cc1b9b60983ab..aca492d1df87f430ef8e4d91a641d99bdd149c67 100644 (file)
@@ -208,8 +208,26 @@ static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ *)
 static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ *)
 static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ *)
 
+/* The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting
+ * to use freed up OIDs. If neccessary the actual freeing up of OIDs is
+ * delayed.
+ */
+
+int obj_cleanup_defer = 0;
+
+void check_defer(int nid)
+       {
+       if (obj_cleanup_defer && nid >= NUM_NID)
+                       obj_cleanup_defer = 1;
+       }
+
 void OBJ_cleanup(void)
        {
+       if (obj_cleanup_defer)
+               {
+               obj_cleanup_defer = 2;
+               return ;
+               }
        if (added == NULL) return;
        added->down_load=0;
        lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */
@@ -546,11 +564,19 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
                                        buf_len--;
                                        }
                                BUF_strlcpy(buf,bndec,buf_len);
-                               buf += i;
+                               if (i > buf_len)
+                                       {
+                                       buf += buf_len;
+                                       buf_len = 0;
+                                       }
+                               else
+                                       {
+                                       buf+=i;
+                                       buf_len-=i;
+                                       }
                                }
                        n++;
                        n += i;
-                       buf_len -= i;
                        OPENSSL_free(bndec);
                        }
                else
@@ -560,9 +586,17 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
                        if (buf && (buf_len > 0))
                                {
                                BUF_strlcpy(buf,tbuf,buf_len);
-                               buf+=i;
+                               if (i > buf_len)
+                                       {
+                                       buf += buf_len;
+                                       buf_len = 0;
+                                       }
+                               else
+                                       {
+                                       buf+=i;
+                                       buf_len-=i;
+                                       }
                                }
-                       buf_len-=i;
                        n+=i;
                        l=0;
                        }