lkml.org 
[lkml]   [2017]   [Dec]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 02/27] ipsec: Fix aborted xfrm policy dump crash
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Herbert Xu <herbert@gondor.apana.org.au>

    commit 1137b5e2529a8f5ca8ee709288ecba3e68044df2 upstream.

    An independent security researcher, Mohamed Ghannam, has reported
    this vulnerability to Beyond Security's SecuriTeam Secure Disclosure
    program.

    The xfrm_dump_policy_done function expects xfrm_dump_policy to
    have been called at least once or it will crash. This can be
    triggered if a dump fails because the target socket's receive
    buffer is full.

    This patch fixes it by using the cb->start mechanism to ensure that
    the initialisation is always done regardless of the buffer situation.

    Fixes: 12a169e7d8f4 ("ipsec: Put dumpers on the dump list")
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
    Cc: Guenter Roeck <linux@roeck-us.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    net/xfrm/xfrm_user.c | 25 +++++++++++++++----------
    1 file changed, 15 insertions(+), 10 deletions(-)

    --- a/net/xfrm/xfrm_user.c
    +++ b/net/xfrm/xfrm_user.c
    @@ -1652,32 +1652,34 @@ static int dump_one_policy(struct xfrm_p

    static int xfrm_dump_policy_done(struct netlink_callback *cb)
    {
    - struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
    + struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args;
    struct net *net = sock_net(cb->skb->sk);

    xfrm_policy_walk_done(walk, net);
    return 0;
    }

    +static int xfrm_dump_policy_start(struct netlink_callback *cb)
    +{
    + struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args;
    +
    + BUILD_BUG_ON(sizeof(*walk) > sizeof(cb->args));
    +
    + xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY);
    + return 0;
    +}
    +
    static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb)
    {
    struct net *net = sock_net(skb->sk);
    - struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
    + struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *)cb->args;
    struct xfrm_dump_info info;

    - BUILD_BUG_ON(sizeof(struct xfrm_policy_walk) >
    - sizeof(cb->args) - sizeof(cb->args[0]));
    -
    info.in_skb = cb->skb;
    info.out_skb = skb;
    info.nlmsg_seq = cb->nlh->nlmsg_seq;
    info.nlmsg_flags = NLM_F_MULTI;

    - if (!cb->args[0]) {
    - cb->args[0] = 1;
    - xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY);
    - }
    -
    (void) xfrm_policy_walk(net, walk, dump_one_policy, &info);

    return skb->len;
    @@ -2415,6 +2417,7 @@ static const struct nla_policy xfrma_spd

    static const struct xfrm_link {
    int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **);
    + int (*start)(struct netlink_callback *);
    int (*dump)(struct sk_buff *, struct netlink_callback *);
    int (*done)(struct netlink_callback *);
    const struct nla_policy *nla_pol;
    @@ -2428,6 +2431,7 @@ static const struct xfrm_link {
    [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy },
    [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy },
    [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy,
    + .start = xfrm_dump_policy_start,
    .dump = xfrm_dump_policy,
    .done = xfrm_dump_policy_done },
    [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi },
    @@ -2479,6 +2483,7 @@ static int xfrm_user_rcv_msg(struct sk_b

    {
    struct netlink_dump_control c = {
    + .start = link->start,
    .dump = link->dump,
    .done = link->done,
    };

    \
     
     \ /
      Last update: 2017-12-04 17:00    [W:4.604 / U:0.172 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site