Date: Mon, 9 Jan 2017 13:12:09 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r311785 - projects/ipsec/sys/netipsec Message-ID: <201701091312.v09DC9BT084254@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701091312.v09DC9BT084254>