lkml.org 
[lkml]   [2022]   [Mar]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 17/42] xfrm: enforce validity of offload input flags
    Date
    From: Leon Romanovsky <leonro@nvidia.com>

    commit 7c76ecd9c99b6e9a771d813ab1aa7fa428b3ade1 upstream.

    struct xfrm_user_offload has flags variable that received user input,
    but kernel didn't check if valid bits were provided. It caused a situation
    where not sanitized input was forwarded directly to the drivers.

    For example, XFRM_OFFLOAD_IPV6 define that was exposed, was used by
    strongswan, but not implemented in the kernel at all.

    As a solution, check and sanitize input flags to forward
    XFRM_OFFLOAD_INBOUND to the drivers.

    Fixes: d77e38e612a0 ("xfrm: Add an IPsec hardware offloading API")
    Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
    Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    include/uapi/linux/xfrm.h | 6 ++++++
    net/xfrm/xfrm_device.c | 6 +++++-
    2 files changed, 11 insertions(+), 1 deletion(-)

    --- a/include/uapi/linux/xfrm.h
    +++ b/include/uapi/linux/xfrm.h
    @@ -501,6 +501,12 @@ struct xfrm_user_offload {
    int ifindex;
    __u8 flags;
    };
    +/* This flag was exposed without any kernel code that supporting it.
    + * Unfortunately, strongswan has the code that uses sets this flag,
    + * which makes impossible to reuse this bit.
    + *
    + * So leave it here to make sure that it won't be reused by mistake.
    + */
    #define XFRM_OFFLOAD_IPV6 1
    #define XFRM_OFFLOAD_INBOUND 2

    --- a/net/xfrm/xfrm_device.c
    +++ b/net/xfrm/xfrm_device.c
    @@ -69,6 +69,9 @@ int xfrm_dev_state_add(struct net *net,
    if (x->encap || x->tfcpad || (x->props.flags & XFRM_STATE_ESN))
    return 0;

    + if (xuo->flags & ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND))
    + return -EINVAL;
    +
    dev = dev_get_by_index(net, xuo->ifindex);
    if (!dev) {
    if (!(xuo->flags & XFRM_OFFLOAD_INBOUND)) {
    @@ -98,7 +101,8 @@ int xfrm_dev_state_add(struct net *net,

    xso->dev = dev;
    xso->num_exthdrs = 1;
    - xso->flags = xuo->flags;
    + /* Don't forward bit that is not implemented */
    + xso->flags = xuo->flags & ~XFRM_OFFLOAD_IPV6;

    err = dev->xfrmdev_ops->xdo_dev_state_add(x);
    if (err) {

    \
     
     \ /
      Last update: 2022-03-07 10:25    [W:4.062 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site