Skip to content

Commit 025f3b2

Browse files
authored
refactor: enforce stuffer return check (#4399)
1 parent 74e66fd commit 025f3b2

11 files changed

+93
-90
lines changed

stuffer/s2n_stuffer.h

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -65,41 +65,41 @@ struct s2n_stuffer {
6565
S2N_RESULT s2n_stuffer_validate(const struct s2n_stuffer *stuffer);
6666

6767
/* Initialize and destroying stuffers */
68-
int s2n_stuffer_init(struct s2n_stuffer *stuffer, struct s2n_blob *in);
69-
int s2n_stuffer_init_written(struct s2n_stuffer *stuffer, struct s2n_blob *in);
70-
int s2n_stuffer_alloc(struct s2n_stuffer *stuffer, const uint32_t size);
71-
int s2n_stuffer_growable_alloc(struct s2n_stuffer *stuffer, const uint32_t size);
68+
int S2N_RESULT_MUST_USE s2n_stuffer_init(struct s2n_stuffer *stuffer, struct s2n_blob *in);
69+
int S2N_RESULT_MUST_USE s2n_stuffer_init_written(struct s2n_stuffer *stuffer, struct s2n_blob *in);
70+
int S2N_RESULT_MUST_USE s2n_stuffer_alloc(struct s2n_stuffer *stuffer, const uint32_t size);
71+
int S2N_RESULT_MUST_USE s2n_stuffer_growable_alloc(struct s2n_stuffer *stuffer, const uint32_t size);
7272
int s2n_stuffer_free(struct s2n_stuffer *stuffer);
7373
/**
7474
* Frees the stuffer without zeroizing the contained data.
7575
*
7676
* This should only be used in scenarios where the data is encrypted or has been
7777
* cleared with `s2n_stuffer_erase_and_read`. In most cases, prefer `s2n_stuffer_free`.
7878
*/
79-
int s2n_stuffer_free_without_wipe(struct s2n_stuffer *stuffer);
80-
int s2n_stuffer_resize(struct s2n_stuffer *stuffer, const uint32_t size);
81-
int s2n_stuffer_resize_if_empty(struct s2n_stuffer *stuffer, const uint32_t size);
82-
int s2n_stuffer_rewind_read(struct s2n_stuffer *stuffer, const uint32_t size);
83-
int s2n_stuffer_reread(struct s2n_stuffer *stuffer);
84-
int s2n_stuffer_rewrite(struct s2n_stuffer *stuffer);
79+
int S2N_RESULT_MUST_USE s2n_stuffer_free_without_wipe(struct s2n_stuffer *stuffer);
80+
int S2N_RESULT_MUST_USE s2n_stuffer_resize(struct s2n_stuffer *stuffer, const uint32_t size);
81+
int S2N_RESULT_MUST_USE s2n_stuffer_resize_if_empty(struct s2n_stuffer *stuffer, const uint32_t size);
82+
int S2N_RESULT_MUST_USE s2n_stuffer_rewind_read(struct s2n_stuffer *stuffer, const uint32_t size);
83+
int S2N_RESULT_MUST_USE s2n_stuffer_reread(struct s2n_stuffer *stuffer);
84+
int S2N_RESULT_MUST_USE s2n_stuffer_rewrite(struct s2n_stuffer *stuffer);
8585
int s2n_stuffer_wipe(struct s2n_stuffer *stuffer);
8686
int s2n_stuffer_wipe_n(struct s2n_stuffer *stuffer, const uint32_t n);
8787
bool s2n_stuffer_is_consumed(struct s2n_stuffer *stuffer);
8888

8989
/* Basic read and write */
90-
int s2n_stuffer_read(struct s2n_stuffer *stuffer, struct s2n_blob *out);
91-
int s2n_stuffer_erase_and_read(struct s2n_stuffer *stuffer, struct s2n_blob *out);
92-
int s2n_stuffer_write(struct s2n_stuffer *stuffer, const struct s2n_blob *in);
93-
int s2n_stuffer_read_bytes(struct s2n_stuffer *stuffer, uint8_t *out, uint32_t n);
94-
int s2n_stuffer_erase_and_read_bytes(struct s2n_stuffer *stuffer, uint8_t *data, uint32_t size);
95-
int s2n_stuffer_write_bytes(struct s2n_stuffer *stuffer, const uint8_t *in, const uint32_t n);
96-
int s2n_stuffer_writev_bytes(struct s2n_stuffer *stuffer, const struct iovec *iov, size_t iov_count,
90+
int S2N_RESULT_MUST_USE s2n_stuffer_read(struct s2n_stuffer *stuffer, struct s2n_blob *out);
91+
int S2N_RESULT_MUST_USE s2n_stuffer_erase_and_read(struct s2n_stuffer *stuffer, struct s2n_blob *out);
92+
int S2N_RESULT_MUST_USE s2n_stuffer_write(struct s2n_stuffer *stuffer, const struct s2n_blob *in);
93+
int S2N_RESULT_MUST_USE s2n_stuffer_read_bytes(struct s2n_stuffer *stuffer, uint8_t *out, uint32_t n);
94+
int S2N_RESULT_MUST_USE s2n_stuffer_erase_and_read_bytes(struct s2n_stuffer *stuffer, uint8_t *data, uint32_t size);
95+
int S2N_RESULT_MUST_USE s2n_stuffer_write_bytes(struct s2n_stuffer *stuffer, const uint8_t *in, const uint32_t n);
96+
int S2N_RESULT_MUST_USE s2n_stuffer_writev_bytes(struct s2n_stuffer *stuffer, const struct iovec *iov, size_t iov_count,
9797
uint32_t offs, uint32_t size);
98-
int s2n_stuffer_skip_read(struct s2n_stuffer *stuffer, uint32_t n);
99-
int s2n_stuffer_skip_write(struct s2n_stuffer *stuffer, const uint32_t n);
98+
int S2N_RESULT_MUST_USE s2n_stuffer_skip_read(struct s2n_stuffer *stuffer, uint32_t n);
99+
int S2N_RESULT_MUST_USE s2n_stuffer_skip_write(struct s2n_stuffer *stuffer, const uint32_t n);
100100

101101
/* Tries to reserve enough space to write n additional bytes into the stuffer.*/
102-
int s2n_stuffer_reserve_space(struct s2n_stuffer *stuffer, uint32_t n);
102+
int S2N_RESULT_MUST_USE s2n_stuffer_reserve_space(struct s2n_stuffer *stuffer, uint32_t n);
103103

104104
/* Raw read/write move the cursor along and give you a pointer you can
105105
* read/write data_len bytes from/to in-place.
@@ -113,17 +113,17 @@ int s2n_stuffer_recv_from_fd(struct s2n_stuffer *stuffer, const int rfd, const u
113113
int s2n_stuffer_send_to_fd(struct s2n_stuffer *stuffer, const int wfd, const uint32_t len, uint32_t *bytes_sent);
114114

115115
/* Read and write integers in network order */
116-
int s2n_stuffer_read_uint8(struct s2n_stuffer *stuffer, uint8_t *u);
117-
int s2n_stuffer_read_uint16(struct s2n_stuffer *stuffer, uint16_t *u);
118-
int s2n_stuffer_read_uint24(struct s2n_stuffer *stuffer, uint32_t *u);
119-
int s2n_stuffer_read_uint32(struct s2n_stuffer *stuffer, uint32_t *u);
120-
int s2n_stuffer_read_uint64(struct s2n_stuffer *stuffer, uint64_t *u);
121-
122-
int s2n_stuffer_write_uint8(struct s2n_stuffer *stuffer, const uint8_t u);
123-
int s2n_stuffer_write_uint16(struct s2n_stuffer *stuffer, const uint16_t u);
124-
int s2n_stuffer_write_uint24(struct s2n_stuffer *stuffer, const uint32_t u);
125-
int s2n_stuffer_write_uint32(struct s2n_stuffer *stuffer, const uint32_t u);
126-
int s2n_stuffer_write_uint64(struct s2n_stuffer *stuffer, const uint64_t u);
116+
int S2N_RESULT_MUST_USE s2n_stuffer_read_uint8(struct s2n_stuffer *stuffer, uint8_t *u);
117+
int S2N_RESULT_MUST_USE s2n_stuffer_read_uint16(struct s2n_stuffer *stuffer, uint16_t *u);
118+
int S2N_RESULT_MUST_USE s2n_stuffer_read_uint24(struct s2n_stuffer *stuffer, uint32_t *u);
119+
int S2N_RESULT_MUST_USE s2n_stuffer_read_uint32(struct s2n_stuffer *stuffer, uint32_t *u);
120+
int S2N_RESULT_MUST_USE s2n_stuffer_read_uint64(struct s2n_stuffer *stuffer, uint64_t *u);
121+
122+
int S2N_RESULT_MUST_USE s2n_stuffer_write_uint8(struct s2n_stuffer *stuffer, const uint8_t u);
123+
int S2N_RESULT_MUST_USE s2n_stuffer_write_uint16(struct s2n_stuffer *stuffer, const uint16_t u);
124+
int S2N_RESULT_MUST_USE s2n_stuffer_write_uint24(struct s2n_stuffer *stuffer, const uint32_t u);
125+
int S2N_RESULT_MUST_USE s2n_stuffer_write_uint32(struct s2n_stuffer *stuffer, const uint32_t u);
126+
int S2N_RESULT_MUST_USE s2n_stuffer_write_uint64(struct s2n_stuffer *stuffer, const uint64_t u);
127127

128128
/* Allocate space now for network order integers that will be written later.
129129
* These are primarily intended to handle the vector type defined in the RFC:
@@ -135,10 +135,10 @@ struct s2n_stuffer_reservation {
135135
};
136136
/* Check basic validity constraints on the s2n_stuffer_reservation: e.g. stuffer validity. */
137137
S2N_RESULT s2n_stuffer_reservation_validate(const struct s2n_stuffer_reservation *reservation);
138-
int s2n_stuffer_reserve_uint8(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation);
139-
int s2n_stuffer_reserve_uint16(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation);
140-
int s2n_stuffer_reserve_uint24(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation);
141-
int s2n_stuffer_write_vector_size(struct s2n_stuffer_reservation *reservation);
138+
int S2N_RESULT_MUST_USE s2n_stuffer_reserve_uint8(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation);
139+
int S2N_RESULT_MUST_USE s2n_stuffer_reserve_uint16(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation);
140+
int S2N_RESULT_MUST_USE s2n_stuffer_reserve_uint24(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation);
141+
int S2N_RESULT_MUST_USE s2n_stuffer_write_vector_size(struct s2n_stuffer_reservation *reservation);
142142

143143
/* Copy one stuffer to another */
144144
int s2n_stuffer_copy(struct s2n_stuffer *from, struct s2n_stuffer *to, uint32_t len);
@@ -153,18 +153,18 @@ int s2n_stuffer_write_base64(struct s2n_stuffer *stuffer, struct s2n_stuffer *in
153153
#define s2n_stuffer_write_str(stuffer, c) s2n_stuffer_write_bytes((stuffer), (const uint8_t *) (c), strlen((c)))
154154
#define s2n_stuffer_write_text(stuffer, c, n) s2n_stuffer_write_bytes((stuffer), (const uint8_t *) (c), (n))
155155
#define s2n_stuffer_read_text(stuffer, c, n) s2n_stuffer_read_bytes((stuffer), (uint8_t *) (c), (n))
156-
int s2n_stuffer_read_expected_str(struct s2n_stuffer *stuffer, const char *expected);
157-
int s2n_stuffer_peek_char(struct s2n_stuffer *stuffer, char *c);
158-
int s2n_stuffer_read_token(struct s2n_stuffer *stuffer, struct s2n_stuffer *token, char delim);
159-
int s2n_stuffer_read_line(struct s2n_stuffer *stuffer, struct s2n_stuffer *token);
160-
int s2n_stuffer_peek_check_for_str(struct s2n_stuffer *s2n_stuffer, const char *expected);
161-
int s2n_stuffer_skip_whitespace(struct s2n_stuffer *stuffer, uint32_t *skipped);
162-
int s2n_stuffer_skip_to_char(struct s2n_stuffer *stuffer, char target);
163-
int s2n_stuffer_skip_expected_char(struct s2n_stuffer *stuffer, const char expected, const uint32_t min,
156+
int S2N_RESULT_MUST_USE s2n_stuffer_read_expected_str(struct s2n_stuffer *stuffer, const char *expected);
157+
int S2N_RESULT_MUST_USE s2n_stuffer_peek_char(struct s2n_stuffer *stuffer, char *c);
158+
int S2N_RESULT_MUST_USE s2n_stuffer_read_token(struct s2n_stuffer *stuffer, struct s2n_stuffer *token, char delim);
159+
int S2N_RESULT_MUST_USE s2n_stuffer_read_line(struct s2n_stuffer *stuffer, struct s2n_stuffer *token);
160+
int S2N_RESULT_MUST_USE s2n_stuffer_peek_check_for_str(struct s2n_stuffer *s2n_stuffer, const char *expected);
161+
int S2N_RESULT_MUST_USE s2n_stuffer_skip_whitespace(struct s2n_stuffer *stuffer, uint32_t *skipped);
162+
int S2N_RESULT_MUST_USE s2n_stuffer_skip_to_char(struct s2n_stuffer *stuffer, char target);
163+
int S2N_RESULT_MUST_USE s2n_stuffer_skip_expected_char(struct s2n_stuffer *stuffer, const char expected, const uint32_t min,
164164
const uint32_t max, uint32_t *skipped);
165-
int s2n_stuffer_skip_read_until(struct s2n_stuffer *stuffer, const char *target);
166-
int s2n_stuffer_alloc_ro_from_string(struct s2n_stuffer *stuffer, const char *str);
167-
int s2n_stuffer_init_ro_from_string(struct s2n_stuffer *stuffer, uint8_t *data, uint32_t length);
165+
int S2N_RESULT_MUST_USE s2n_stuffer_skip_read_until(struct s2n_stuffer *stuffer, const char *target);
166+
int S2N_RESULT_MUST_USE s2n_stuffer_alloc_ro_from_string(struct s2n_stuffer *stuffer, const char *str);
167+
int S2N_RESULT_MUST_USE s2n_stuffer_init_ro_from_string(struct s2n_stuffer *stuffer, uint8_t *data, uint32_t length);
168168

169169
/* Stuffer versions of sprintf methods, except:
170170
* - They write bytes, not strings. They do not write a final '\0'. Unfortunately,
@@ -173,25 +173,25 @@ int s2n_stuffer_init_ro_from_string(struct s2n_stuffer *stuffer, uint8_t *data,
173173
* - vprintf does not consume the vargs. It calls va_copy before using
174174
* the varg argument, so can be called repeatedly with the same vargs.
175175
*/
176-
int s2n_stuffer_printf(struct s2n_stuffer *stuffer, const char *format, ...);
177-
int s2n_stuffer_vprintf(struct s2n_stuffer *stuffer, const char *format, va_list vargs);
176+
int S2N_RESULT_MUST_USE s2n_stuffer_printf(struct s2n_stuffer *stuffer, const char *format, ...);
177+
int S2N_RESULT_MUST_USE s2n_stuffer_vprintf(struct s2n_stuffer *stuffer, const char *format, va_list vargs);
178178

179179
/* Read a private key from a PEM encoded stuffer to an ASN1/DER encoded one */
180-
int s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1, int *type);
180+
int S2N_RESULT_MUST_USE s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1, int *type);
181181

182182
/* Read a certificate from a PEM encoded stuffer to an ASN1/DER encoded one */
183-
int s2n_stuffer_certificate_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1);
183+
int S2N_RESULT_MUST_USE s2n_stuffer_certificate_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1);
184184

185185
/* Read a CRL from a PEM encoded stuffer to an ASN1/DER encoded one */
186-
int s2n_stuffer_crl_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1);
186+
int S2N_RESULT_MUST_USE s2n_stuffer_crl_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1);
187187

188188
/* Read DH parameters om a PEM encoded stuffer to a PKCS3 encoded one */
189-
int s2n_stuffer_dhparams_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *pkcs3);
189+
int S2N_RESULT_MUST_USE s2n_stuffer_dhparams_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *pkcs3);
190190

191191
bool s2n_is_base64_char(unsigned char c);
192192

193193
/* Copies all valid data from "stuffer" into "out".
194194
* The old blob "out" pointed to is freed.
195195
* It is the responsibility of the caller to free the free "out".
196196
*/
197-
int s2n_stuffer_extract_blob(struct s2n_stuffer *stuffer, struct s2n_blob *out);
197+
int S2N_RESULT_MUST_USE s2n_stuffer_extract_blob(struct s2n_stuffer *stuffer, struct s2n_blob *out);

stuffer/s2n_stuffer_pem.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,27 +139,27 @@ int s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer
139139
return S2N_SUCCESS;
140140
}
141141

142-
s2n_stuffer_reread(pem);
143-
s2n_stuffer_reread(asn1);
142+
POSIX_GUARD(s2n_stuffer_reread(pem));
143+
POSIX_GUARD(s2n_stuffer_reread(asn1));
144144

145145
/* By default, OpenSSL tools always generate both "EC PARAMETERS" and "EC PRIVATE
146146
* KEY" PEM objects in the keyfile. Skip the first "EC PARAMETERS" object so that we're
147147
* compatible with OpenSSL's default output, and since "EC PARAMETERS" is
148148
* only needed for non-standard curves that aren't currently supported.
149149
*/
150150
if (s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_EC_PARAMETERS) != S2N_SUCCESS) {
151-
s2n_stuffer_reread(pem);
151+
POSIX_GUARD(s2n_stuffer_reread(pem));
152152
}
153-
s2n_stuffer_wipe(asn1);
153+
POSIX_GUARD(s2n_stuffer_wipe(asn1));
154154

155155
if (s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_PKCS1_EC_PRIVATE_KEY) == S2N_SUCCESS) {
156156
*type = EVP_PKEY_EC;
157157
return S2N_SUCCESS;
158158
}
159159

160160
/* If it does not match either format, try PKCS#8 */
161-
s2n_stuffer_reread(pem);
162-
s2n_stuffer_reread(asn1);
161+
POSIX_GUARD(s2n_stuffer_reread(pem));
162+
POSIX_GUARD(s2n_stuffer_reread(asn1));
163163
if (s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_PKCS8_PRIVATE_KEY) == S2N_SUCCESS) {
164164
*type = EVP_PKEY_RSA;
165165
return S2N_SUCCESS;

tests/fuzz/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ include ../../s2n.mk
3939

4040
CRUFT += $(wildcard *_test) $(wildcard fuzz-*.log) $(wildcard *_test_output.txt) $(wildcard *_test_results.txt) $(wildcard LD_PRELOAD/*.so) $(wildcard *.prof*)
4141

42-
CFLAGS += -Wno-unreachable-code -O0 -I$(LIBCRYPTO_ROOT)/include/ -I../
42+
# We do not warn on unused results (-Wno-unused-result) because we expect that
43+
# many of the fuzz test inputs will not be valid and operations will not succeed.
44+
CFLAGS += -Wno-unreachable-code -Wno-unused-result -O0 -I$(LIBCRYPTO_ROOT)/include/ -I../
4345
LIBS += -L../testlib/ -ltests2n -L../../lib/ -ls2n
4446
LDFLAGS += $(LIBFUZZER_ROOT)/lib/libFuzzer.a -lstdc++
4547
LDFLAGS += ${CRYPTO_LDFLAGS} ${LIBS} ${CRYPTO_LIBS} -lm -ldl -lrt -pthread

tests/testlib/s2n_connection_test_utils.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ static int buffer_read(void *io_context, uint8_t *buf, uint32_t len)
3838
{
3939
struct s2n_stuffer *in_buf;
4040
int n_read, n_avail;
41+
errno = EIO;
4142

4243
if (buf == NULL) {
4344
return 0;
@@ -58,7 +59,7 @@ static int buffer_read(void *io_context, uint8_t *buf, uint32_t len)
5859
return -1;
5960
}
6061

61-
s2n_stuffer_read_bytes(in_buf, buf, n_read);
62+
POSIX_GUARD(s2n_stuffer_read_bytes(in_buf, buf, n_read));
6263
return n_read;
6364
}
6465

tests/unit/s2n_client_signature_algorithms_extension_test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ int main(int argc, char **argv)
5858
struct s2n_connection *server_conn = s2n_connection_new(S2N_SERVER);
5959

6060
struct s2n_stuffer io = { 0 };
61-
s2n_stuffer_growable_alloc(&io, 0);
61+
EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&io, 0));
6262

6363
EXPECT_SUCCESS(s2n_client_signature_algorithms_extension.send(client_conn, &io));
6464
EXPECT_SUCCESS(s2n_client_signature_algorithms_extension.recv(server_conn, &io));

0 commit comments

Comments
 (0)