From: Qingshuang Fu <[email protected]>

The ovpn_socket() function creates a socket but fails to close it on
several error paths, leading to a file descriptor leak:

1. When the address family is neither AF_INET nor AF_INET6, the socket
   is leaked in the switch default case.
2. When setsockopt() for SO_REUSEADDR, SO_REUSEPORT, or SO_MARK fails,
   the socket is leaked.
3. When setsockopt() for IPV6_V6ONLY fails, the socket is leaked.

The existing err_socket label already handles closing the socket for
the bind() failure path. Fix all other error paths to use goto
err_socket instead of returning directly, ensuring the socket is
properly closed on every error path.

Fixes: 959bc330a439 ("testing/selftests: add test tool and scripts for ovpn 
module")
Signed-off-by: Qingshuang Fu <[email protected]>
---
 tools/testing/selftests/net/ovpn/ovpn-cli.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/net/ovpn/ovpn-cli.c 
b/tools/testing/selftests/net/ovpn/ovpn-cli.c
index f4effa7580c0..81b81d5fc162 100644
--- a/tools/testing/selftests/net/ovpn/ovpn-cli.c
+++ b/tools/testing/selftests/net/ovpn/ovpn-cli.c
@@ -507,7 +507,8 @@ static int ovpn_socket(struct ovpn_ctx *ctx, sa_family_t 
family, int proto)
                sock_len = sizeof(*in6);
                break;
        default:
-               return -1;
+               ret = -EINVAL;
+               goto err_socket;
        }
 
        int opt = 1;
@@ -516,13 +517,13 @@ static int ovpn_socket(struct ovpn_ctx *ctx, sa_family_t 
family, int proto)
 
        if (ret < 0) {
                perror("setsockopt for SO_REUSEADDR");
-               return ret;
+               goto err_socket;
        }
 
        ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
        if (ret < 0) {
                perror("setsockopt for SO_REUSEPORT");
-               return ret;
+               goto err_socket;
        }
 
        if (ctx->mark != 0) {
@@ -530,16 +531,16 @@ static int ovpn_socket(struct ovpn_ctx *ctx, sa_family_t 
family, int proto)
                                 sizeof(ctx->mark));
                if (ret < 0) {
                        perror("setsockopt for SO_MARK");
-                       return ret;
+                       goto err_socket;
                }
        }
 
        if (family == AF_INET6) {
                opt = 0;
-               if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &opt,
-                              sizeof(opt))) {
+               ret = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &opt, 
sizeof(opt));
+               if (ret < 0) {
                        perror("failed to set IPV6_V6ONLY");
-                       return -1;
+                       goto err_socket;
                }
        }
 

base-commit: f9a2394a23482bfd330911e9c8295b71724feacd
-- 
2.25.1


Reply via email to