tls_push_record can return -EAGAIN because of tcp layer. In that
case open_rec is already in the tx_record list and should not be
freed.
Also the record size can be more than the size requested to write
in tls_sw_do_sendpage(). That leads to overflow of copied variable
and wrong return code.

Fixes: d10523d0b3d7 ("net/tls: free the record on encryption error")
Signed-off-by: Vadim Fedorenko <vfedore...@novek.ru>
---
 net/tls/tls_sw.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index e23f94a..d4acbd1 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -796,7 +796,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct 
sock *sk,
        psock = sk_psock_get(sk);
        if (!psock || !policy) {
                err = tls_push_record(sk, flags, record_type);
-               if (err && err != -EINPROGRESS) {
+               if (err && err != -EINPROGRESS && err != -EAGAIN) {
                        *copied -= sk_msg_free(sk, msg);
                        tls_free_open_rec(sk);
                }
@@ -824,7 +824,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct 
sock *sk,
        switch (psock->eval) {
        case __SK_PASS:
                err = tls_push_record(sk, flags, record_type);
-               if (err && err != -EINPROGRESS) {
+               if (err && err != -EINPROGRESS && err != -EAGAIN) {
                        *copied -= sk_msg_free(sk, msg);
                        tls_free_open_rec(sk);
                        goto out_err;
@@ -1132,7 +1132,7 @@ static int tls_sw_do_sendpage(struct sock *sk, struct 
page *page,
        struct sk_msg *msg_pl;
        struct tls_rec *rec;
        int num_async = 0;
-       size_t copied = 0;
+       ssize_t copied = 0;
        bool full_record;
        int record_room;
        int ret = 0;
@@ -1234,7 +1234,7 @@ static int tls_sw_do_sendpage(struct sock *sk, struct 
page *page,
        }
 sendpage_end:
        ret = sk_stream_error(sk, flags, ret);
-       return copied ? copied : ret;
+       return (copied > 0) ? copied : ret;
 }
 
 int tls_sw_sendpage_locked(struct sock *sk, struct page *page,
-- 
1.8.3.1

Reply via email to