[ovs-dev] [PATCH] compat: Restrict __ro_after_init usage

Greg Rose gvrose8192 at gmail.com
Fri Jun 16 21:48:52 UTC 2017


On 06/16/2017 02:02 PM, Greg Rose wrote:
> The attribute __ro_after_init was introduced in Linux kernel 4.5.  If
> a data structure is given this attribute then after the driver module
> loads the memory page where the data resides will be marked read only.
> 
> The compat code in cache.h always defines __ro_after_init if it is not
> already defined so that it can be used as an attribute for the datapath
> genl_family structure definitions.  If __ro_after_init is defined then
> it is used "as-is" where it will apply the read only attribute after
> driver initialization.
> 
> This is incorrect usage for the Generic Netlink genl_family structure
> definitions prior to Linux kernel 4.10.  The genl_family structure
> in those kernels includes a list header member that will be written
> to when the generic netlink family is unregistered.  This will cause
> a subsequent page fault and kernel panic because at this time the
> genl_family structure data has been marked read only in the page
> descriptor.
> 
> A new compat macro is introduced in acinclude.m4 to detect when the
> genl_family structure has the family_list list header as a member.
> In this case HAVE_GENL_FAMILY_LIST is defined and if __ro_after_init
> is also defined then it is undefined and redefined as empty.  This
> will prevent the genl_family data structure from being marked read
> only in kernels 4.5 through 4.9 and thus prevent the page fault when
> the generic netlink families in datapath.c are unregistered.

Oops - wrong patch.  There's supposed to be a signed off by and fixes tag.

I'll resend.

- Greg

> ---
>   acinclude.m4                                | 3 +++
>   datapath/linux/compat/include/linux/cache.h | 9 ++++++++-
>   2 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/acinclude.m4 b/acinclude.m4
> index 22cb897..2145ecc 100644
> --- a/acinclude.m4
> +++ b/acinclude.m4
> @@ -736,6 +736,9 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
>     OVS_FIND_PARAM_IFELSE([$KSRC/include/net/netfilter/ipv6/nf_defrag_ipv6.h],
>                           [nf_defrag_ipv6_enable], [net],
>                           [OVS_DEFINE([HAVE_DEFRAG_ENABLE_TAKES_NET])])
> +  OVS_GREP_IFELSE([$KSRC/include/net/genetlink.h], [family_list],
> +                        [OVS_DEFINE([HAVE_GENL_FAMILY_LIST])])
> +
>   
>     if cmp -s datapath/linux/kcompat.h.new \
>               datapath/linux/kcompat.h >/dev/null 2>&1; then
> diff --git a/datapath/linux/compat/include/linux/cache.h b/datapath/linux/compat/include/linux/cache.h
> index 917defa..35da4e7 100644
> --- a/datapath/linux/compat/include/linux/cache.h
> +++ b/datapath/linux/compat/include/linux/cache.h
> @@ -3,8 +3,15 @@
>   
>   #include_next <linux/cache.h>
>   
> +#ifdef HAVE_GENL_FAMILY_LIST
> +#ifdef __ro_after_init
> +#undef __ro_after_init
> +#endif /* #ifdef __ro_after_init */
> +#define __ro_after_init
> +#else
>   #ifndef __ro_after_init
>   #define __ro_after_init
> -#endif
> +#endif /* #ifndef __ro_after_init */
> +#endif /* #ifdef HAVE_GENL_FAMILY_LIST */
>   
>   #endif
> 



More information about the dev mailing list