Looks good,

Ethan

On Fri, Sep 9, 2011 at 10:21, Ben Pfaff <b...@nicira.com> wrote:
> Commit e408762f "netlink-socket: New function nl_lookup_genl_mcgroup()"
> modified do_lookup_genl_family() to return the Netlink attributes to the
> caller, but it still freed the Netlink message itself, which meant that
> the attributes pointed into freed memory.  This commit fixes the problem.
>
> This commit is not a minimal fix.  It refactors do_lookup_genl_family(),
> changing the return value from "negative errno value or positive genl
> family id" to the more common "zero or positive errno value".
>
> Found by valgrind.
> ---
>  lib/netlink-socket.c |   71 
> +++++++++++++++++++++++++++++---------------------
>  1 files changed, 41 insertions(+), 30 deletions(-)
>
> diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c
> index 394107e..2d2aa29 100644
> --- a/lib/netlink-socket.c
> +++ b/lib/netlink-socket.c
> @@ -727,45 +727,41 @@ genl_family_to_name(uint16_t id)
>  }
>
>  static int
> -do_lookup_genl_family(const char *name, struct nlattr **attrs)
> +do_lookup_genl_family(const char *name, struct nlattr **attrs,
> +                      struct ofpbuf **replyp)
>  {
>     struct nl_sock *sock;
>     struct ofpbuf request, *reply;
> -    int retval;
> +    int error;
>
> -    retval = nl_sock_create(NETLINK_GENERIC, &sock);
> -    if (retval) {
> -        return -retval;
> +    *replyp = NULL;
> +    error = nl_sock_create(NETLINK_GENERIC, &sock);
> +    if (error) {
> +        return error;
>     }
>
>     ofpbuf_init(&request, 0);
>     nl_msg_put_genlmsghdr(&request, 0, GENL_ID_CTRL, NLM_F_REQUEST,
>                           CTRL_CMD_GETFAMILY, 1);
>     nl_msg_put_string(&request, CTRL_ATTR_FAMILY_NAME, name);
> -    retval = nl_sock_transact(sock, &request, &reply);
> +    error = nl_sock_transact(sock, &request, &reply);
>     ofpbuf_uninit(&request);
> -    if (retval) {
> +    if (error) {
>         nl_sock_destroy(sock);
> -        return -retval;
> +        return error;
>     }
>
>     if (!nl_policy_parse(reply, NLMSG_HDRLEN + GENL_HDRLEN,
> -                         family_policy, attrs, ARRAY_SIZE(family_policy))) {
> +                         family_policy, attrs, ARRAY_SIZE(family_policy))
> +        || nl_attr_get_u16(attrs[CTRL_ATTR_FAMILY_ID]) == 0) {
>         nl_sock_destroy(sock);
>         ofpbuf_delete(reply);
> -        return -EPROTO;
> +        return EPROTO;
>     }
>
> -    retval = nl_attr_get_u16(attrs[CTRL_ATTR_FAMILY_ID]);
> -    if (retval == 0) {
> -        retval = -EPROTO;
> -    } else {
> -        define_genl_family(retval, name);
> -    }
>     nl_sock_destroy(sock);
> -    ofpbuf_delete(reply);
> -
> -    return retval;
> +    *replyp = reply;
> +    return 0;
>  }
>
>  /* Finds the multicast group called 'group_name' in genl family 
> 'family_name'.
> @@ -777,15 +773,15 @@ nl_lookup_genl_mcgroup(const char *family_name, const 
> char *group_name,
>  {
>     struct nlattr *family_attrs[ARRAY_SIZE(family_policy)];
>     struct ofpbuf all_mcs;
> +    struct ofpbuf *reply;
>     struct nlattr *mc;
>     unsigned int left;
> -    int retval;
> +    int error;
>
>     *multicast_group = 0;
> -    retval = do_lookup_genl_family(family_name, family_attrs);
> -    if (retval <= 0) {
> -        assert(retval);
> -        return -retval;
> +    error = do_lookup_genl_family(family_name, family_attrs, &reply);
> +    if (error) {
> +        return error;
>     }
>
>     nl_attr_get_nested(family_attrs[CTRL_ATTR_MCAST_GROUPS], &all_mcs);
> @@ -799,18 +795,23 @@ nl_lookup_genl_mcgroup(const char *family_name, const 
> char *group_name,
>         const char *mc_name;
>
>         if (!nl_parse_nested(mc, mc_policy, mc_attrs, ARRAY_SIZE(mc_policy))) 
> {
> -            return EPROTO;
> +            error = EPROTO;
> +            goto exit;
>         }
>
>         mc_name = nl_attr_get_string(mc_attrs[CTRL_ATTR_MCAST_GRP_NAME]);
>         if (!strcmp(group_name, mc_name)) {
>             *multicast_group =
>                 nl_attr_get_u32(mc_attrs[CTRL_ATTR_MCAST_GRP_ID]);
> -            return 0;
> +            error = 0;
> +            goto exit;
>         }
>     }
> +    error = EPROTO;
>
> -    return EPROTO;
> +exit:
> +    ofpbuf_delete(reply);
> +    return error;
>  }
>
>  /* If '*number' is 0, translates the given Generic Netlink family 'name' to a
> @@ -820,10 +821,20 @@ nl_lookup_genl_mcgroup(const char *family_name, const 
> char *group_name,
>  int
>  nl_lookup_genl_family(const char *name, int *number)
>  {
> -    struct nlattr *attrs[ARRAY_SIZE(family_policy)];
> -
>     if (*number == 0) {
> -        *number = do_lookup_genl_family(name, attrs);
> +        struct nlattr *attrs[ARRAY_SIZE(family_policy)];
> +        struct ofpbuf *reply;
> +        int error;
> +
> +        error = do_lookup_genl_family(name, attrs, &reply);
> +        if (!error) {
> +            *number = nl_attr_get_u16(attrs[CTRL_ATTR_FAMILY_ID]);
> +            define_genl_family(*number, name);
> +        } else {
> +            *number = -error;
> +        }
> +        ofpbuf_delete(reply);
> +
>         assert(*number != 0);
>     }
>     return *number > 0 ? 0 : -*number;
> --
> 1.7.4.4
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to