From owner-svn-src-projects@freebsd.org Mon Jan 9 13:12:10 2017 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id EAB3CCA61EC for ; Mon, 9 Jan 2017 13:12:10 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AA8AE124E; Mon, 9 Jan 2017 13:12:10 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v09DC90h084257; Mon, 9 Jan 2017 13:12:09 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v09DC9BT084254; Mon, 9 Jan 2017 13:12:09 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201701091312.v09DC9BT084254@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Mon, 9 Jan 2017 13:12:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r311785 - projects/ipsec/sys/netipsec X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Jan 2017 13:12:11 -0000 Author: ae Date: Mon Jan 9 13:12:09 2017 New Revision: 311785 URL: https://svnweb.freebsd.org/changeset/base/311785 Log: Change IPsec default policy to be allocated on module initialization, instead of using static variable. Since each security policy can be cached in PCB, static variable becomes invalid after module unload. When module is loaded again, the cache will be invalidated, and this leads to access to invalid memory. Now default security policy is allocated on module initialization like all another policies. And such policies will be kept until last reference isn't released on next cache invalidation. Also modify corresponding sysctl variables to be SYSCTL_PROC. Modified: projects/ipsec/sys/netipsec/ipsec.c projects/ipsec/sys/netipsec/ipsec.h projects/ipsec/sys/netipsec/ipsec_mod.c Modified: projects/ipsec/sys/netipsec/ipsec.c ============================================================================== --- projects/ipsec/sys/netipsec/ipsec.c Mon Jan 9 11:37:25 2017 (r311784) +++ projects/ipsec/sys/netipsec/ipsec.c Mon Jan 9 13:12:09 2017 (r311785) @@ -123,8 +123,24 @@ static VNET_DEFINE(int, ip4_filtertunnel #define V_ip4_filtertunnel VNET(ip4_filtertunnel) static VNET_DEFINE(int, check_policy_history) = 0; #define V_check_policy_history VNET(check_policy_history) -static VNET_DEFINE(struct secpolicy, def_policy); +static VNET_DEFINE(struct secpolicy *, def_policy) = NULL; #define V_def_policy VNET(def_policy) +static int +sysctl_def_policy(SYSCTL_HANDLER_ARGS) +{ + int error, value; + + value = V_def_policy->policy; + error = sysctl_handle_int(oidp, &value, 0, req); + if (error == 0) { + if (value != IPSEC_POLICY_DISCARD && + value != IPSEC_POLICY_NONE) + return (EINVAL); + V_def_policy->policy = value; + } + return (error); +} + /* * Crypto support requirements: * @@ -148,8 +164,8 @@ FEATURE(ipsec_natt, "UDP Encapsulation o SYSCTL_DECL(_net_inet_ipsec); /* net.inet.ipsec */ -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY, def_policy, - CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(def_policy).policy, 0, +SYSCTL_PROC(_net_inet_ipsec, IPSECCTL_DEF_POLICY, def_policy, + CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_RW, 0, 0, sysctl_def_policy, "I", "IPsec default policy."); SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_esp_trans_deflev), 0, @@ -229,8 +245,8 @@ static VNET_DEFINE(int, ip6_filtertunnel SYSCTL_DECL(_net_inet6_ipsec6); /* net.inet6.ipsec6 */ -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY, def_policy, - CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(def_policy).policy, 0, +SYSCTL_PROC(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY, def_policy, + CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_RW, 0, 0, sysctl_def_policy, "I", "IPsec default policy."); SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_esp_trans_deflev), 0, @@ -272,17 +288,9 @@ static void ipsec6_setspidx_ipaddr(const static struct secpolicy * key_allocsp_default(void) { - struct secpolicy *sp; - sp = &V_def_policy; - if (sp->policy != IPSEC_POLICY_DISCARD && - sp->policy != IPSEC_POLICY_NONE) { - ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n", - sp->policy, IPSEC_POLICY_NONE)); - sp->policy = IPSEC_POLICY_NONE; - } - key_addref(sp); - return (sp); + key_addref(V_def_policy); + return (V_def_policy); } static void @@ -1345,16 +1353,38 @@ ipsec_updateid(struct secasvar *sav, uin return (0); } +int +ipsec_initialized(void) +{ + + return (V_def_policy != NULL); +} + static void def_policy_init(const void *unused __unused) { - bzero(&V_def_policy, sizeof(struct secpolicy)); - V_def_policy.policy = IPSEC_POLICY_NONE; - V_def_policy.refcnt = 1; + V_def_policy = key_newsp(); + if (V_def_policy != NULL) { + V_def_policy->policy = IPSEC_POLICY_NONE; + /* Force INPCB SP cache invalidation */ + key_bumpspgen(); + } else + printf("%s: failed to initialize default policy\n", __func__); +} + - /* Force INPCB SP cache invalidation */ - key_bumpspgen(); +static void +def_policy_uninit(const void *unused __unused) +{ + + if (V_def_policy != NULL) { + key_freesp(&V_def_policy); + key_bumpspgen(); + } } + VNET_SYSINIT(def_policy_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, def_policy_init, NULL); +VNET_SYSUNINIT(def_policy_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, + def_policy_uninit, NULL); Modified: projects/ipsec/sys/netipsec/ipsec.h ============================================================================== --- projects/ipsec/sys/netipsec/ipsec.h Mon Jan 9 11:37:25 2017 (r311784) +++ projects/ipsec/sys/netipsec/ipsec.h Mon Jan 9 13:12:09 2017 (r311785) @@ -319,6 +319,7 @@ int udp_ipsec_pcbctl(struct inpcb *, str int ipsec_chkreplay(uint32_t, struct secasvar *); int ipsec_updatereplay(uint32_t, struct secasvar *); int ipsec_updateid(struct secasvar *, uint64_t *, uint64_t *); +int ipsec_initialized(void); void ipsec_setspidx_inpcb(struct inpcb *, struct secpolicyindex *, u_int); Modified: projects/ipsec/sys/netipsec/ipsec_mod.c ============================================================================== --- projects/ipsec/sys/netipsec/ipsec_mod.c Mon Jan 9 11:37:25 2017 (r311784) +++ projects/ipsec/sys/netipsec/ipsec_mod.c Mon Jan 9 13:12:09 2017 (r311785) @@ -107,6 +107,8 @@ ipsec_modevent(module_t mod, int type, v switch (type) { case MOD_LOAD: /* All xforms are registered via SYSINIT */ + if (!ipsec_initialized()) + return (ENOMEM); #ifdef KLD_MODULE #ifdef INET ipsec_support_enable(ipv4_ipsec_support, &ipv4_methods);