Skip to content

Commit

Permalink
fix(1346): fix control frames flood
Browse files Browse the repository at this point in the history
part of #1346
  • Loading branch information
kingluo committed May 6, 2024
1 parent 6b29d18 commit 8cb3d77
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
16 changes: 16 additions & 0 deletions fw/http_frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,17 @@ __tfw_h2_send_frame(TfwH2Ctx *ctx, TfwFrameHdr *hdr, TfwStr *data,
unsigned char buf[FRAME_HEADER_SIZE];
TfwStr *hdr_str = TFW_STR_CHUNK(data, 0);
TfwH2Conn *conn = container_of(ctx, TfwH2Conn, h2);
bool is_control_frame = !hdr->stream_id || hdr->type == HTTP2_RST_STREAM;

// If the peer is causing us to generate a lot of control frames,
// but not reading them from us, assume they are trying to make us
// run out of memory.
if (is_control_frame &&
atomic_read(&ctx->queued_control_frames) > MAX_QUEUED_CONTROL_FRAMES) {
T_ERR("Too many control frames in send queue, closing connection");
r = SS_BLOCK_WITH_RST;
goto err;
}

BUG_ON(hdr_str->data);
hdr_str->data = buf;
Expand Down Expand Up @@ -318,6 +329,11 @@ __tfw_h2_send_frame(TfwH2Ctx *ctx, TfwFrameHdr *hdr, TfwStr *data,
ctx->new_settings.flags &= ~SS_F_HTTP2_ACK_FOR_HPACK_TBL_RESIZING;
}

if (is_control_frame) {
skb_set_tfw_flags(it.skb, SS_F_HTTT2_FRAME_CONTROL);
atomic_inc(&ctx->queued_control_frames);
}

if ((r = tfw_connection_send((TfwConn *)conn, &msg)))
goto err;
/*
Expand Down
13 changes: 13 additions & 0 deletions fw/http_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@
#define FRAME_MAX_LENGTH ((1U << 24) - 1)
#define FRAME_DEF_LENGTH (16384)

/**
* MAX_QUEUED_CONTROL_FRAMES is the maximum number of control frames like
* SETTINGS, PING and RST_STREAM that will be queued for writing before
* the connection is closed to prevent memory exhaustion attacks.
*/
#define MAX_QUEUED_CONTROL_FRAMES 10000

enum {
/* This skb contains control frame. */
SS_F_HTTT2_FRAME_CONTROL = 0x80,
};

/**
* HTTP/2 frame types (RFC 7540 section 6).
*/
Expand Down Expand Up @@ -209,6 +221,7 @@ typedef struct {
*/
typedef struct tfw_h2_ctx_t {
spinlock_t lock;
atomic_t queued_control_frames;
TfwSettings lsettings;
TfwSettings rsettings;
unsigned long streams_num;
Expand Down
3 changes: 3 additions & 0 deletions fw/sock_clnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,9 @@ tfw_sk_write_xmit(struct sock *sk, struct sk_buff *skb, unsigned int mss_now,
if (h2_mode) {
h2 = tfw_h2_context(conn);
tbl = &h2->hpack.enc_tbl;
if (flags & SS_F_HTTT2_FRAME_CONTROL) {
atomic_dec(&h2->queued_control_frames);
}
}

r = tfw_tls_encrypt(sk, skb, mss_now, limit, nskbs);
Expand Down

0 comments on commit 8cb3d77

Please sign in to comment.