106
106
* ([email protected] ). This product includes software written by Tim
107
107
108
108
109
+ // Ensure we can't call OPENSSL_malloc circularly.
110
+ #define _BORINGSSL_PROHIBIT_OPENSSL_MALLOC
109
111
#include <openssl/err.h>
110
112
111
113
#include <assert.h>
115
117
#define __STDC_FORMAT_MACROS
116
118
#endif
117
119
#include <inttypes.h>
118
-
120
+ #include <limits.h>
121
+ #include <stdarg.h>
119
122
#include <string.h>
120
123
121
124
#if defined(OPENSSL_WINDOWS )
@@ -134,8 +137,8 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
134
137
struct err_error_st {
135
138
// file contains the filename where the error occurred.
136
139
const char * file ;
137
- // data contains a NUL-terminated string with optional data. It must be freed
138
- // with | OPENSSL_free|.
140
+ // data contains a NUL-terminated string with optional data. It is allocated
141
+ // with system |malloc| and must be freed with |free| (not | OPENSSL_free|)
139
142
char * data ;
140
143
// packed contains the error library and reason, as packed by ERR_PACK.
141
144
uint32_t packed ;
@@ -167,20 +170,27 @@ extern const char kOpenSSLReasonStringData[];
167
170
168
171
// err_clear clears the given queued error.
169
172
static void err_clear (struct err_error_st * error ) {
170
- OPENSSL_free (error -> data );
173
+ free (error -> data );
171
174
OPENSSL_memset (error , 0 , sizeof (struct err_error_st ));
172
175
}
173
176
174
177
static void err_copy (struct err_error_st * dst , const struct err_error_st * src ) {
175
178
err_clear (dst );
176
179
dst -> file = src -> file ;
177
180
if (src -> data != NULL ) {
178
- dst -> data = OPENSSL_strdup (src -> data );
181
+ // Disable deprecated functions on msvc so it doesn't complain about strdup.
182
+ OPENSSL_MSVC_PRAGMA (warning (push ))
183
+ OPENSSL_MSVC_PRAGMA (warning (disable : 4996 ))
184
+ // We can't use OPENSSL_strdup because we don't want to call OPENSSL_malloc,
185
+ // which can affect the error stack.
186
+ dst -> data = strdup (src -> data );
187
+ OPENSSL_MSVC_PRAGMA (warning (pop ))
179
188
}
180
189
dst -> packed = src -> packed ;
181
190
dst -> line = src -> line ;
182
191
}
183
192
193
+
184
194
// global_next_library contains the next custom library value to return.
185
195
static int global_next_library = ERR_NUM_LIBS ;
186
196
@@ -199,15 +209,15 @@ static void err_state_free(void *statep) {
199
209
for (unsigned i = 0 ; i < ERR_NUM_ERRORS ; i ++ ) {
200
210
err_clear (& state -> errors [i ]);
201
211
}
202
- OPENSSL_free (state -> to_free );
203
- OPENSSL_free (state );
212
+ free (state -> to_free );
213
+ free (state );
204
214
}
205
215
206
216
// err_get_state gets the ERR_STATE object for the current thread.
207
217
static ERR_STATE * err_get_state (void ) {
208
218
ERR_STATE * state = CRYPTO_get_thread_local (OPENSSL_THREAD_LOCAL_ERR );
209
219
if (state == NULL ) {
210
- state = OPENSSL_malloc (sizeof (ERR_STATE ));
220
+ state = malloc (sizeof (ERR_STATE ));
211
221
if (state == NULL ) {
212
222
return NULL ;
213
223
}
@@ -263,7 +273,10 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line,
263
273
} else {
264
274
* data = error -> data ;
265
275
if (flags != NULL ) {
266
- * flags = ERR_FLAG_STRING ;
276
+ // Without |ERR_FLAG_MALLOCED|, rust-openssl assumes the string has a
277
+ // static lifetime. In both cases, we retain ownership of the string,
278
+ // and the caller is not expected to free it.
279
+ * flags = ERR_FLAG_STRING | ERR_FLAG_MALLOCED ;
267
280
}
268
281
// If this error is being removed, take ownership of data from
269
282
// the error. The semantics are such that the caller doesn't
@@ -272,7 +285,7 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line,
272
285
// error queue.
273
286
if (inc ) {
274
287
if (error -> data != NULL ) {
275
- OPENSSL_free (state -> to_free );
288
+ free (state -> to_free );
276
289
state -> to_free = error -> data ;
277
290
}
278
291
error -> data = NULL ;
@@ -340,7 +353,7 @@ void ERR_clear_error(void) {
340
353
for (i = 0 ; i < ERR_NUM_ERRORS ; i ++ ) {
341
354
err_clear (& state -> errors [i ]);
342
355
}
343
- OPENSSL_free (state -> to_free );
356
+ free (state -> to_free );
344
357
state -> to_free = NULL ;
345
358
346
359
state -> top = state -> bottom = 0 ;
@@ -634,13 +647,13 @@ static void err_set_error_data(char *data) {
634
647
struct err_error_st * error ;
635
648
636
649
if (state == NULL || state -> top == state -> bottom ) {
637
- OPENSSL_free (data );
650
+ free (data );
638
651
return ;
639
652
}
640
653
641
654
error = & state -> errors [state -> top ];
642
655
643
- OPENSSL_free (error -> data );
656
+ free (error -> data );
644
657
error -> data = data ;
645
658
}
646
659
@@ -677,48 +690,42 @@ void ERR_put_error(int library, int unused, int reason, const char *file,
677
690
// concatenates them and sets the result as the data on the most recent
678
691
// error.
679
692
static void err_add_error_vdata (unsigned num , va_list args ) {
680
- size_t alloced , new_len , len = 0 , substr_len ;
681
- char * buf ;
693
+ size_t total_size = 0 ;
682
694
const char * substr ;
683
- unsigned i ;
695
+ char * buf ;
684
696
685
- alloced = 80 ;
686
- buf = OPENSSL_malloc (alloced + 1 );
687
- if (buf == NULL ) {
697
+ va_list args_copy ;
698
+ va_copy (args_copy , args );
699
+ for (size_t i = 0 ; i < num ; i ++ ) {
700
+ substr = va_arg (args_copy , const char * );
701
+ if (substr == NULL ) {
702
+ continue ;
703
+ }
704
+ size_t substr_len = strlen (substr );
705
+ if (SIZE_MAX - total_size < substr_len ) {
706
+ return ; // Would overflow.
707
+ }
708
+ total_size += substr_len ;
709
+ }
710
+ va_end (args_copy );
711
+ if (total_size == SIZE_MAX ) {
712
+ return ; // Would overflow.
713
+ }
714
+ total_size += 1 ; // NUL terminator.
715
+ if ((buf = malloc (total_size )) == NULL ) {
688
716
return ;
689
717
}
690
-
691
- for (i = 0 ; i < num ; i ++ ) {
718
+ buf [ 0 ] = '\0' ;
719
+ for (size_t i = 0 ; i < num ; i ++ ) {
692
720
substr = va_arg (args , const char * );
693
721
if (substr == NULL ) {
694
722
continue ;
695
723
}
696
-
697
- substr_len = strlen (substr );
698
- new_len = len + substr_len ;
699
- if (new_len > alloced ) {
700
- char * new_buf ;
701
-
702
- if (alloced + 20 + 1 < alloced ) {
703
- // overflow.
704
- OPENSSL_free (buf );
705
- return ;
706
- }
707
-
708
- alloced = new_len + 20 ;
709
- new_buf = OPENSSL_realloc (buf , alloced + 1 );
710
- if (new_buf == NULL ) {
711
- OPENSSL_free (buf );
712
- return ;
713
- }
714
- buf = new_buf ;
724
+ if (OPENSSL_strlcat (buf , substr , total_size ) >= total_size ) {
725
+ assert (0 ); // should not be possible.
715
726
}
716
-
717
- OPENSSL_memcpy (buf + len , substr , substr_len );
718
- len = new_len ;
719
727
}
720
-
721
- buf [len ] = 0 ;
728
+ va_end (args );
722
729
err_set_error_data (buf );
723
730
}
724
731
@@ -730,21 +737,13 @@ void ERR_add_error_data(unsigned count, ...) {
730
737
}
731
738
732
739
void ERR_add_error_dataf (const char * format , ...) {
740
+ char * buf = NULL ;
733
741
va_list ap ;
734
- char * buf ;
735
- static const unsigned buf_len = 256 ;
736
742
737
- // A fixed-size buffer is used because va_copy (which would be needed in
738
- // order to call vsnprintf twice and measure the buffer) wasn't defined until
739
- // C99.
740
- buf = OPENSSL_malloc (buf_len + 1 );
741
- if (buf == NULL ) {
743
+ va_start (ap , format );
744
+ if (OPENSSL_vasprintf_internal (& buf , format , ap , /*system_malloc=*/ 1 ) == -1 ) {
742
745
return ;
743
746
}
744
-
745
- va_start (ap , format );
746
- BIO_vsnprintf (buf , buf_len , format , ap );
747
- buf [buf_len ] = 0 ;
748
747
va_end (ap );
749
748
750
749
err_set_error_data (buf );
@@ -756,13 +755,20 @@ void ERR_set_error_data(char *data, int flags) {
756
755
assert (0 );
757
756
return ;
758
757
}
758
+ // Disable deprecated functions on msvc so it doesn't complain about strdup.
759
+ OPENSSL_MSVC_PRAGMA (warning (push ))
760
+ OPENSSL_MSVC_PRAGMA (warning (disable : 4996 ))
761
+ // We can not use OPENSSL_strdup because we don't want to call OPENSSL_malloc,
762
+ // which can affect the error stack.
763
+ char * copy = strdup (data );
764
+ OPENSSL_MSVC_PRAGMA (warning (pop ))
765
+ if (copy != NULL) {
766
+ err_set_error_data (copy );
767
+ }
759
768
if (flags & ERR_FLAG_MALLOCED ) {
760
- err_set_error_data (data );
761
- } else {
762
- char * copy = OPENSSL_strdup (data );
763
- if (copy != NULL ) {
764
- err_set_error_data (copy );
765
- }
769
+ // We can not take ownership of |data| directly because it is allocated with
770
+ // |OPENSSL_malloc| and we will free it with system |free| later.
771
+ OPENSSL_free (data );
766
772
}
767
773
}
768
774
@@ -824,8 +830,8 @@ void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state) {
824
830
for (size_t i = 0 ; i < state -> num_errors ; i ++ ) {
825
831
err_clear (& state -> errors [i ]);
826
832
}
827
- OPENSSL_free (state -> errors );
828
- OPENSSL_free (state );
833
+ free (state -> errors );
834
+ free (state );
829
835
}
830
836
831
837
ERR_SAVE_STATE * ERR_save_state (void ) {
@@ -834,7 +840,7 @@ ERR_SAVE_STATE *ERR_save_state(void) {
834
840
return NULL ;
835
841
}
836
842
837
- ERR_SAVE_STATE * ret = OPENSSL_malloc (sizeof (ERR_SAVE_STATE ));
843
+ ERR_SAVE_STATE * ret = malloc (sizeof (ERR_SAVE_STATE ));
838
844
if (ret == NULL ) {
839
845
return NULL ;
840
846
}
@@ -844,9 +850,9 @@ ERR_SAVE_STATE *ERR_save_state(void) {
844
850
? state -> top - state -> bottom
845
851
: ERR_NUM_ERRORS + state -> top - state -> bottom ;
846
852
assert (num_errors < ERR_NUM_ERRORS );
847
- ret -> errors = OPENSSL_malloc (num_errors * sizeof (struct err_error_st ));
853
+ ret -> errors = malloc (num_errors * sizeof (struct err_error_st ));
848
854
if (ret -> errors == NULL ) {
849
- OPENSSL_free (ret );
855
+ free (ret );
850
856
return NULL ;
851
857
}
852
858
OPENSSL_memset (ret -> errors , 0 , num_errors * sizeof (struct err_error_st ));
0 commit comments