Skip to content

Commit 72db146

Browse files
committed
[tls] Split received records over multiple I/O buffers
TLS servers are not obliged to implement the RFC3546 maximum fragment length extension, and many common servers (including OpenSSL, as used in Apache's mod_ssl) do not do so. iPXE may therefore have to cope with TLS records of up to 16kB. Allocations for 16kB have a non-negligible chance of failing, causing the TLS connection to abort. Fix by maintaining the received record as a linked list of I/O buffers, rather than a single contiguous buffer. To reduce memory pressure, we also decrypt in situ, and deliver the decrypted data via xfer_deliver_iob() rather than xfer_deliver_raw(). Signed-off-by: Michael Brown <mcb30@ipxe.org>
1 parent 09d45ff commit 72db146

File tree

2 files changed

+304
-168
lines changed

2 files changed

+304
-168
lines changed

src/include/ipxe/tls.h

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
1919
#include <ipxe/sha256.h>
2020
#include <ipxe/x509.h>
2121
#include <ipxe/pending.h>
22+
#include <ipxe/iobuf.h>
2223

2324
/** A TLS header */
2425
struct tls_header {
@@ -264,14 +265,35 @@ struct tls_session {
264265
uint64_t rx_seq;
265266
/** RX state */
266267
enum tls_rx_state rx_state;
267-
/** Offset within current RX state */
268-
size_t rx_rcvd;
269268
/** Current received record header */
270269
struct tls_header rx_header;
271-
/** Current received raw data buffer */
272-
void *rx_data;
270+
/** Current received record header (static I/O buffer) */
271+
struct io_buffer rx_header_iobuf;
272+
/** List of received data buffers */
273+
struct list_head rx_data;
273274
};
274275

276+
/** RX I/O buffer size
277+
*
278+
* The maximum fragment length extension is optional, and many common
279+
* implementations (including OpenSSL) do not support it. We must
280+
* therefore be prepared to receive records of up to 16kB in length.
281+
* The chance of an allocation of this size failing is non-negligible,
282+
* so we must split received data into smaller allocations.
283+
*/
284+
#define TLS_RX_BUFSIZE 4096
285+
286+
/** Minimum RX I/O buffer size
287+
*
288+
* To simplify manipulations, we ensure that no RX I/O buffer is
289+
* smaller than this size. This allows us to assume that the MAC and
290+
* padding are entirely contained within the final I/O buffer.
291+
*/
292+
#define TLS_RX_MIN_BUFSIZE 512
293+
294+
/** RX I/O buffer alignment */
295+
#define TLS_RX_ALIGN 16
296+
275297
extern int add_tls ( struct interface *xfer, const char *name,
276298
struct interface **next );
277299

0 commit comments

Comments
 (0)