diff --git a/fw/http.c b/fw/http.c index 65dfeba904..f06515237d 100644 --- a/fw/http.c +++ b/fw/http.c @@ -1648,6 +1648,12 @@ tfw_http_marks_cmp(const void *l, const void *r) return (m1 < m2) ? -1 : (m1 > m2); } +bool tfw_http_mark_is_in_whitlist(unsigned int mark) +{ + return !!bsearch(&mark, tfw_wl_marks.mrks, tfw_wl_marks.sz, + sizeof(tfw_wl_marks.mrks[0]), tfw_http_marks_cmp); +} + static inline void tfw_http_mark_wl_new_msg(TfwConn *conn, TfwHttpMsg *msg, const struct sk_buff *skb) @@ -1655,14 +1661,10 @@ tfw_http_mark_wl_new_msg(TfwConn *conn, TfwHttpMsg *msg, if (!tfw_wl_marks.mrks || !(TFW_CONN_TYPE(conn) & Conn_Clnt)) return; - if (bsearch(&skb->mark, tfw_wl_marks.mrks, tfw_wl_marks.sz, - sizeof(tfw_wl_marks.mrks[0]), tfw_http_marks_cmp)) - { + if (tfw_http_mark_is_in_whitlist(skb->mark)) __set_bit(TFW_HTTP_B_WHITELIST, msg->flags); - } } - /* * Forwarding of requests to a back end server is run under a lock * on the server connection's forwarding queue. It's performed as diff --git a/fw/http.h b/fw/http.h index d155a2d206..0473a5e397 100644 --- a/fw/http.h +++ b/fw/http.h @@ -825,5 +825,6 @@ int tfw_h2_frame_local_resp(TfwHttpResp *resp, unsigned int stream_id, int tfw_http_resp_copy_encodings(TfwHttpResp *resp, TfwStr* dst, size_t max_len); void tfw_http_extract_request_authority(TfwHttpReq *req); +bool tfw_http_mark_is_in_whitlist(unsigned int mark); #endif /* __TFW_HTTP_H__ */ diff --git a/fw/http_limits.c b/fw/http_limits.c index 62a7b824aa..9749226c26 100644 --- a/fw/http_limits.c +++ b/fw/http_limits.c @@ -183,22 +183,26 @@ __frang_init_acc(void *data) } static int -frang_conn_new(struct sock *sk) +frang_conn_new(struct sock *sk, struct sk_buff *skb) { int r = T_BLOCK; FrangAcc *ra; TfwClient *cli; TfwAddr addr; - TfwVhost *dflt_vh = tfw_vhost_lookup_default(); + TfwVhost *dflt_vh; /* The new socket is allocated by inet_csk_clone_lock(). */ assert_spin_locked(&sk->sk_lock.slock); + if (tfw_http_mark_is_in_whitlist(skb->mark)) + return T_OK; + /* * Default vhost configuration stores global frang settings, it's always * available even on reload under heavy load. But the pointer comes * from other module, take care of probable null-dereferences. */ + dflt_vh = tfw_vhost_lookup_default(); if (WARN_ON_ONCE(!dflt_vh)) return T_BLOCK; @@ -1522,10 +1526,10 @@ tfw_classifier_cleanup_inport(void) } static int -tfw_classify_conn_estab(struct sock *sk) +tfw_classify_conn_estab(struct sock *sk, struct sk_buff *skb) { if (test_bit(tfw_addr_get_sk_sport(sk), tfw_inports)) - return frang_conn_new(sk); + return frang_conn_new(sk, skb); return T_OK; } diff --git a/linux-5.10.35.patch b/linux-5.10.35.patch index 51378274d2..a293349d4f 100644 --- a/linux-5.10.35.patch +++ b/linux-5.10.35.patch @@ -732,7 +732,7 @@ index a828cf99c..59ebed976 100644 * @skb: buffer to check diff --git a/include/linux/tempesta.h b/include/linux/tempesta.h new file mode 100644 -index 000000000..8e9b6af75 +index 000000000..08350e4ad --- /dev/null +++ b/include/linux/tempesta.h @@ -0,0 +1,54 @@ @@ -764,7 +764,7 @@ index 000000000..8e9b6af75 +typedef void (*TempestaTxAction)(void); + +typedef struct { -+ int (*sk_alloc)(struct sock *sk); ++ int (*sk_alloc)(struct sock *sk, struct sk_buff *skb); + void (*sk_free)(struct sock *sk); + int (*sock_tcp_rcv)(struct sock *sk, struct sk_buff *skb); +} TempestaOps; @@ -775,7 +775,7 @@ index 000000000..8e9b6af75 +} TempestaMapping; + +/* Security hooks. */ -+int tempesta_new_clntsk(struct sock *newsk); ++int tempesta_new_clntsk(struct sock *newsk, struct sk_buff *skb); +void tempesta_register_ops(TempestaOps *tops); +void tempesta_unregister_ops(TempestaOps *tops); + @@ -2368,7 +2368,7 @@ index fac5c1469..f9f8000bf 100644 memcpy(nskb->cb, skb->cb, sizeof(skb->cb)); #ifdef CONFIG_TLS_DEVICE diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index ab8ed0fc4..a7c57cda4 100644 +index ab8ed0fc4..1a5c62ab7 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -57,6 +57,7 @@ @@ -2408,7 +2408,7 @@ index ab8ed0fc4..a7c57cda4 100644 + * We need already initialized socket addresses, + * so there is no appropriate security hook. + */ -+ if (tempesta_new_clntsk(newsk)) { ++ if (tempesta_new_clntsk(newsk, skb)) { + tcp_v4_send_reset(newsk, skb); + goto put_and_exit; + } @@ -2789,7 +2789,7 @@ index f99494637..d3c0ba7cd 100644 if (!err) tcp_event_new_data_sent(sk, skb); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c -index 3f9bb6dd1..08c6fd687 100644 +index 3f9bb6dd1..af725b233 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -65,6 +65,7 @@ @@ -2810,7 +2810,7 @@ index 3f9bb6dd1..08c6fd687 100644 + * We need already initialized socket addresses, + * so there is no appropriate security hook. + */ -+ if (tempesta_new_clntsk(newsk)) { ++ if (tempesta_new_clntsk(newsk, skb)) { + tcp_v6_send_reset(newsk, skb); + inet_csk_prepare_forced_close(newsk); + tcp_done(newsk); @@ -2948,7 +2948,7 @@ index 000000000..4c439ac0c +tempesta-y := tempesta_lsm.o diff --git a/security/tempesta/tempesta_lsm.c b/security/tempesta/tempesta_lsm.c new file mode 100644 -index 000000000..b8e8d67dc +index 000000000..c25f0a8ac --- /dev/null +++ b/security/tempesta/tempesta_lsm.c @@ -0,0 +1,138 @@ @@ -3015,7 +3015,7 @@ index 000000000..b8e8d67dc +EXPORT_SYMBOL(tempesta_unregister_ops); + +int -+tempesta_new_clntsk(struct sock *newsk) ++tempesta_new_clntsk(struct sock *newsk, struct sk_buff *skb) +{ + int r = 0; + @@ -3027,7 +3027,7 @@ index 000000000..b8e8d67dc + + tops = rcu_dereference(tempesta_ops); + if (likely(tops)) -+ r = tops->sk_alloc(newsk); ++ r = tops->sk_alloc(newsk, skb); + + rcu_read_unlock(); +