Mon Aug 31 20:34:43 2020 UTC ()
wg: Avoid memory leak if socreate fails.


(riastradh)
diff -r1.50 -r1.51 src/sys/net/if_wg.c

cvs diff -r1.50 -r1.51 src/sys/net/if_wg.c (expand / switch to unified diff)

--- src/sys/net/if_wg.c 2020/08/31 20:34:18 1.50
+++ src/sys/net/if_wg.c 2020/08/31 20:34:43 1.51
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_wg.c,v 1.50 2020/08/31 20:34:18 riastradh Exp $ */ 1/* $NetBSD: if_wg.c,v 1.51 2020/08/31 20:34:43 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (C) Ryota Ozaki <ozaki.ryota@gmail.com> 4 * Copyright (C) Ryota Ozaki <ozaki.ryota@gmail.com>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -31,27 +31,27 @@ @@ -31,27 +31,27 @@
31 31
32/* 32/*
33 * This network interface aims to implement the WireGuard protocol. 33 * This network interface aims to implement the WireGuard protocol.
34 * The implementation is based on the paper of WireGuard as of 34 * The implementation is based on the paper of WireGuard as of
35 * 2018-06-30 [1]. The paper is referred in the source code with label 35 * 2018-06-30 [1]. The paper is referred in the source code with label
36 * [W]. Also the specification of the Noise protocol framework as of 36 * [W]. Also the specification of the Noise protocol framework as of
37 * 2018-07-11 [2] is referred with label [N]. 37 * 2018-07-11 [2] is referred with label [N].
38 * 38 *
39 * [1] https://www.wireguard.com/papers/wireguard.pdf 39 * [1] https://www.wireguard.com/papers/wireguard.pdf
40 * [2] http://noiseprotocol.org/noise.pdf 40 * [2] http://noiseprotocol.org/noise.pdf
41 */ 41 */
42 42
43#include <sys/cdefs.h> 43#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.50 2020/08/31 20:34:18 riastradh Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.51 2020/08/31 20:34:43 riastradh Exp $");
45 45
46#ifdef _KERNEL_OPT 46#ifdef _KERNEL_OPT
47#include "opt_inet.h" 47#include "opt_inet.h"
48#endif 48#endif
49 49
50#include <sys/param.h> 50#include <sys/param.h>
51#include <sys/types.h> 51#include <sys/types.h>
52 52
53#include <sys/atomic.h> 53#include <sys/atomic.h>
54#include <sys/callout.h> 54#include <sys/callout.h>
55#include <sys/cprng.h> 55#include <sys/cprng.h>
56#include <sys/cpu.h> 56#include <sys/cpu.h>
57#include <sys/device.h> 57#include <sys/device.h>
@@ -3167,27 +3167,27 @@ wg_worker_socreate(struct wg_softc *wg,  @@ -3167,27 +3167,27 @@ wg_worker_socreate(struct wg_softc *wg,
3167 *sop = so; 3167 *sop = so;
3168 3168
3169 return 0; 3169 return 0;
3170} 3170}
3171 3171
3172static int 3172static int
3173wg_worker_init(struct wg_softc *wg) 3173wg_worker_init(struct wg_softc *wg)
3174{ 3174{
3175 int error; 3175 int error;
3176 struct wg_worker *wgw; 3176 struct wg_worker *wgw;
3177 const char *ifname = wg->wg_if.if_xname; 3177 const char *ifname = wg->wg_if.if_xname;
3178 struct socket *so; 3178 struct socket *so;
3179 3179
3180 wgw = kmem_zalloc(sizeof(struct wg_worker), KM_SLEEP); 3180 wgw = kmem_zalloc(sizeof(*wgw), KM_SLEEP);
3181 3181
3182 mutex_init(&wgw->wgw_lock, MUTEX_DEFAULT, IPL_SOFTNET); 3182 mutex_init(&wgw->wgw_lock, MUTEX_DEFAULT, IPL_SOFTNET);
3183 cv_init(&wgw->wgw_cv, ifname); 3183 cv_init(&wgw->wgw_cv, ifname);
3184 wgw->wgw_todie = false; 3184 wgw->wgw_todie = false;
3185 wgw->wgw_wakeup_reasons = 0; 3185 wgw->wgw_wakeup_reasons = 0;
3186 3186
3187 error = wg_worker_socreate(wg, wgw, AF_INET, &so); 3187 error = wg_worker_socreate(wg, wgw, AF_INET, &so);
3188 if (error != 0) 3188 if (error != 0)
3189 goto error; 3189 goto error;
3190 wgw->wgw_so4 = so; 3190 wgw->wgw_so4 = so;
3191#ifdef INET6 3191#ifdef INET6
3192 error = wg_worker_socreate(wg, wgw, AF_INET6, &so); 3192 error = wg_worker_socreate(wg, wgw, AF_INET6, &so);
3193 if (error != 0) 3193 if (error != 0)
@@ -3204,26 +3204,28 @@ wg_worker_init(struct wg_softc *wg) @@ -3204,26 +3204,28 @@ wg_worker_init(struct wg_softc *wg)
3204 3204
3205 return 0; 3205 return 0;
3206 3206
3207error: 3207error:
3208#ifdef INET6 3208#ifdef INET6
3209 if (wgw->wgw_so6 != NULL) 3209 if (wgw->wgw_so6 != NULL)
3210 soclose(wgw->wgw_so6); 3210 soclose(wgw->wgw_so6);
3211#endif 3211#endif
3212 if (wgw->wgw_so4 != NULL) 3212 if (wgw->wgw_so4 != NULL)
3213 soclose(wgw->wgw_so4); 3213 soclose(wgw->wgw_so4);
3214 cv_destroy(&wgw->wgw_cv); 3214 cv_destroy(&wgw->wgw_cv);
3215 mutex_destroy(&wgw->wgw_lock); 3215 mutex_destroy(&wgw->wgw_lock);
3216 3216
 3217 kmem_free(wgw, sizeof(*wgw));
 3218
3217 return error; 3219 return error;
3218} 3220}
3219 3221
3220static void 3222static void
3221wg_worker_destroy(struct wg_softc *wg) 3223wg_worker_destroy(struct wg_softc *wg)
3222{ 3224{
3223 struct wg_worker *wgw = wg->wg_worker; 3225 struct wg_worker *wgw = wg->wg_worker;
3224 3226
3225 mutex_enter(&wgw->wgw_lock); 3227 mutex_enter(&wgw->wgw_lock);
3226 wgw->wgw_todie = true; 3228 wgw->wgw_todie = true;
3227 wgw->wgw_wakeup_reasons = 0; 3229 wgw->wgw_wakeup_reasons = 0;
3228 cv_broadcast(&wgw->wgw_cv); 3230 cv_broadcast(&wgw->wgw_cv);
3229 mutex_exit(&wgw->wgw_lock); 3231 mutex_exit(&wgw->wgw_lock);