Handle ibuf_add() errors.
authorrenato <renato@openbsd.org>
Mon, 27 Jun 2016 19:06:33 +0000 (19:06 +0000)
committerrenato <renato@openbsd.org>
Mon, 27 Jun 2016 19:06:33 +0000 (19:06 +0000)
tweaks from claudio@

usr.sbin/ldpd/address.c
usr.sbin/ldpd/hello.c
usr.sbin/ldpd/init.c
usr.sbin/ldpd/labelmapping.c
usr.sbin/ldpd/ldpe.h
usr.sbin/ldpd/notification.c

index ee7181d..fe2e174 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: address.c,v 1.25 2016/05/23 19:11:42 renato Exp $ */
+/*     $OpenBSD: address.c,v 1.26 2016/06/27 19:06:33 renato Exp $ */
 
 /*
  * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -25,7 +25,7 @@
 #include "lde.h"
 #include "log.h"
 
-static void    gen_address_list_tlv(struct ibuf *, uint16_t, int,
+static int     gen_address_list_tlv(struct ibuf *, uint16_t, int,
                    struct if_addr *);
 
 void
@@ -35,6 +35,7 @@ send_address(struct nbr *nbr, int af, struct if_addr *if_addr, int withdraw)
        uint32_t         msg_type;
        uint16_t         size;
        int              iface_count = 0;
+       int              err = 0;
 
        if (!withdraw)
                msg_type = MSG_TYPE_ADDR;
@@ -63,11 +64,15 @@ send_address(struct nbr *nbr, int af, struct if_addr *if_addr, int withdraw)
        if ((buf = ibuf_open(size)) == NULL)
                fatal(__func__);
 
-       gen_ldp_hdr(buf, size);
+       err |= gen_ldp_hdr(buf, size);
        size -= LDP_HDR_SIZE;
-       gen_msg_hdr(buf, msg_type, size);
+       err |= gen_msg_hdr(buf, msg_type, size);
        size -= LDP_MSG_SIZE;
-       gen_address_list_tlv(buf, size, af, if_addr);
+       err |= gen_address_list_tlv(buf, size, af, if_addr);
+       if (err) {
+               ibuf_free(buf);
+               return;
+       }
 
        evbuf_enqueue(&nbr->tcp->wbuf, buf);
 
@@ -169,12 +174,13 @@ recv_address(struct nbr *nbr, char *buf, uint16_t len)
        return (0);
 }
 
-static void
+static int
 gen_address_list_tlv(struct ibuf *buf, uint16_t size, int af,
     struct if_addr *if_addr)
 {
        struct address_list_tlv  alt;
        uint16_t                 addr_size;
+       int                      err = 0;
 
        memset(&alt, 0, sizeof(alt));
        alt.type = TLV_TYPE_ADDRLIST;
@@ -192,13 +198,15 @@ gen_address_list_tlv(struct ibuf *buf, uint16_t size, int af,
                fatalx("gen_address_list_tlv: unknown af");
        }
 
-       ibuf_add(buf, &alt, sizeof(alt));
-
+       err |= ibuf_add(buf, &alt, sizeof(alt));
        if (if_addr == NULL) {
                LIST_FOREACH(if_addr, &global.addr_list, entry) {
-                       if (if_addr->af == af)
-                               ibuf_add(buf, &if_addr->addr, addr_size);
+                       if (if_addr->af != af)
+                               continue;
+                       err |= ibuf_add(buf, &if_addr->addr, addr_size);
                }
        } else
-               ibuf_add(buf, &if_addr->addr, addr_size);
+               err |= ibuf_add(buf, &if_addr->addr, addr_size);
+
+       return (err);
 }
index 192bdf9..e9c6da1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: hello.c,v 1.50 2016/06/18 17:31:32 renato Exp $ */
+/*     $OpenBSD: hello.c,v 1.51 2016/06/27 19:06:33 renato Exp $ */
 
 /*
  * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -41,6 +41,7 @@ send_hello(enum hello_type type, struct iface_af *ia, struct tnbr *tnbr)
        uint16_t                 size, holdtime = 0, flags = 0;
        int                      fd = 0;
        struct ibuf             *buf;
+       int                      err = 0;
 
        switch (type) {
        case HELLO_LINK:
@@ -96,10 +97,10 @@ send_hello(enum hello_type type, struct iface_af *ia, struct tnbr *tnbr)
        if ((buf = ibuf_open(size)) == NULL)
                fatal(__func__);
 
-       gen_ldp_hdr(buf, size);
+       err |= gen_ldp_hdr(buf, size);
        size -= LDP_HDR_SIZE;
-       gen_msg_hdr(buf, MSG_TYPE_HELLO, size);
-       gen_hello_prms_tlv(buf, holdtime, flags);
+       err |= gen_msg_hdr(buf, MSG_TYPE_HELLO, size);
+       err |= gen_hello_prms_tlv(buf, holdtime, flags);
 
        /*
         * RFC 7552 - Section 6.1:
@@ -109,18 +110,18 @@ send_hello(enum hello_type type, struct iface_af *ia, struct tnbr *tnbr)
         */
        switch (af) {
        case AF_INET:
-               gen_opt4_hello_prms_tlv(buf, TLV_TYPE_IPV4TRANSADDR,
+               err |= gen_opt4_hello_prms_tlv(buf, TLV_TYPE_IPV4TRANSADDR,
                    leconf->ipv4.trans_addr.v4.s_addr);
                break;
        case AF_INET6:
-               gen_opt16_hello_prms_tlv(buf, TLV_TYPE_IPV6TRANSADDR,
+               err |= gen_opt16_hello_prms_tlv(buf, TLV_TYPE_IPV6TRANSADDR,
                    leconf->ipv6.trans_addr.v6.s6_addr);
                break;
        default:
                fatalx("send_hello: unknown af");
        }
 
-       gen_opt4_hello_prms_tlv(buf, TLV_TYPE_CONFIG,
+       err |= gen_opt4_hello_prms_tlv(buf, TLV_TYPE_CONFIG,
            htonl(global.conf_seqnum));
 
        /*
@@ -129,7 +130,12 @@ send_hello(enum hello_type type, struct iface_af *ia, struct tnbr *tnbr)
         * MUST include the Dual-Stack capability TLV in all of its LDP Hellos".
         */
        if (ldp_is_dual_stack(leconf))
-               gen_ds_hello_prms_tlv(buf, leconf->trans_pref);
+               err |= gen_ds_hello_prms_tlv(buf, leconf->trans_pref);
+
+       if (err) {
+               ibuf_free(buf);
+               return (-1);
+       }
 
        send_packet(fd, af, &dst, ia, buf->buf, buf->wpos);
        ibuf_free(buf);
index 7832cd1..c6039cc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: init.c,v 1.29 2016/06/11 01:55:35 renato Exp $ */
+/*     $OpenBSD: init.c,v 1.30 2016/06/27 19:06:33 renato Exp $ */
 
 /*
  * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -32,6 +32,7 @@ send_init(struct nbr *nbr)
 {
        struct ibuf             *buf;
        uint16_t                 size;
+       int                      err = 0;
 
        log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
 
@@ -39,11 +40,15 @@ send_init(struct nbr *nbr)
        if ((buf = ibuf_open(size)) == NULL)
                fatal(__func__);
 
-       gen_ldp_hdr(buf, size);
+       err |= gen_ldp_hdr(buf, size);
        size -= LDP_HDR_SIZE;
-       gen_msg_hdr(buf, MSG_TYPE_INIT, size);
+       err |= gen_msg_hdr(buf, MSG_TYPE_INIT, size);
        size -= LDP_MSG_SIZE;
-       gen_init_prms_tlv(buf, nbr, size);
+       err |= gen_init_prms_tlv(buf, nbr, size);
+       if (err) {
+               ibuf_free(buf);
+               return;
+       }
 
        evbuf_enqueue(&nbr->tcp->wbuf, buf);
 }
index c064a54..c901ea3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: labelmapping.c,v 1.51 2016/06/18 01:29:05 renato Exp $ */
+/*     $OpenBSD: labelmapping.c,v 1.52 2016/06/27 19:06:33 renato Exp $ */
 
 /*
  * Copyright (c) 2014, 2015 Renato Westphal <renato@openbsd.org>
 #include "log.h"
 
 static void     enqueue_pdu(struct nbr *, struct ibuf *, uint16_t);
-static void     gen_label_tlv(struct ibuf *, uint32_t);
+static int      gen_label_tlv(struct ibuf *, uint32_t);
 static int      tlv_decode_label(struct nbr *, struct ldp_msg *, char *,
                    uint16_t, uint32_t *);
-static void     gen_reqid_tlv(struct ibuf *, uint32_t);
+static int      gen_reqid_tlv(struct ibuf *, uint32_t);
 
 static void
 enqueue_pdu(struct nbr *nbr, struct ibuf *buf, uint16_t size)
@@ -53,6 +53,7 @@ send_labelmessage(struct nbr *nbr, uint16_t type, struct mapping_head *mh)
        struct mapping_entry    *me;
        uint16_t                 msg_size, size = 0;
        int                      first = 1;
+       int                      err = 0;
 
        /* nothing to send */
        if (TAILQ_EMPTY(mh))
@@ -66,7 +67,7 @@ send_labelmessage(struct nbr *nbr, uint16_t type, struct mapping_head *mh)
                                fatal(__func__);
 
                        /* real size will be set up later */
-                       gen_ldp_hdr(buf, 0);
+                       err |= gen_ldp_hdr(buf, 0);
 
                        size = LDP_HDR_PDU_LEN;
                        first = 0;
@@ -110,14 +111,18 @@ send_labelmessage(struct nbr *nbr, uint16_t type, struct mapping_head *mh)
                size += msg_size;
 
                /* append message and tlvs */
-               gen_msg_hdr(buf, type, msg_size);
-               gen_fec_tlv(buf, &me->map);
+               err |= gen_msg_hdr(buf, type, msg_size);
+               err |= gen_fec_tlv(buf, &me->map);
                if (me->map.label != NO_LABEL)
-                       gen_label_tlv(buf, me->map.label);
+                       err |= gen_label_tlv(buf, me->map.label);
                if (me->map.flags & F_MAP_REQ_ID)
-                       gen_reqid_tlv(buf, me->map.requestid);
+                       err |= gen_reqid_tlv(buf, me->map.requestid);
                if (me->map.flags & F_MAP_PW_STATUS)
-                       gen_pw_status_tlv(buf, me->map.pw_status);
+                       err |= gen_pw_status_tlv(buf, me->map.pw_status);
+               if (err) {
+                       ibuf_free(buf);
+                       return;
+               }
 
                TAILQ_REMOVE(mh, me, entry);
                free(me);
@@ -423,7 +428,7 @@ err:
 }
 
 /* Other TLV related functions */
-static void
+static int
 gen_label_tlv(struct ibuf *buf, uint32_t label)
 {
        struct label_tlv        lt;
@@ -432,7 +437,7 @@ gen_label_tlv(struct ibuf *buf, uint32_t label)
        lt.length = htons(sizeof(label));
        lt.label = htonl(label);
 
-       ibuf_add(buf, &lt, sizeof(lt));
+       return (ibuf_add(buf, &lt, sizeof(lt)));
 }
 
 static int
@@ -482,7 +487,7 @@ tlv_decode_label(struct nbr *nbr, struct ldp_msg *lm, char *buf,
        return (sizeof(lt));
 }
 
-static void
+static int
 gen_reqid_tlv(struct ibuf *buf, uint32_t reqid)
 {
        struct reqid_tlv        rt;
@@ -491,10 +496,10 @@ gen_reqid_tlv(struct ibuf *buf, uint32_t reqid)
        rt.length = htons(sizeof(reqid));
        rt.reqid = htonl(reqid);
 
-       ibuf_add(buf, &rt, sizeof(rt));
+       return (ibuf_add(buf, &rt, sizeof(rt)));
 }
 
-void
+int
 gen_pw_status_tlv(struct ibuf *buf, uint32_t status)
 {
        struct pw_status_tlv    st;
@@ -503,38 +508,39 @@ gen_pw_status_tlv(struct ibuf *buf, uint32_t status)
        st.length = htons(sizeof(status));
        st.value = htonl(status);
 
-       ibuf_add(buf, &st, sizeof(st));
+       return (ibuf_add(buf, &st, sizeof(st)));
 }
 
-void
+int
 gen_fec_tlv(struct ibuf *buf, struct map *map)
 {
        struct tlv      ft;
        uint16_t        family, len, pw_type, ifmtu;
        uint8_t         pw_len = 0;
        uint32_t        group_id, pwid;
+       int             err = 0;
 
        ft.type = htons(TLV_TYPE_FEC);
 
        switch (map->type) {
        case MAP_TYPE_WILDCARD:
                ft.length = htons(sizeof(uint8_t));
-               ibuf_add(buf, &ft, sizeof(ft));
-               ibuf_add(buf, &map->type, sizeof(map->type));
+               err |= ibuf_add(buf, &ft, sizeof(ft));
+               err |= ibuf_add(buf, &map->type, sizeof(map->type));
                break;
        case MAP_TYPE_PREFIX:
                len = PREFIX_SIZE(map->fec.prefix.prefixlen);
                ft.length = htons(sizeof(map->type) + sizeof(family) +
                    sizeof(map->fec.prefix.prefixlen) + len);
-               ibuf_add(buf, &ft, sizeof(ft));
+               err |= ibuf_add(buf, &ft, sizeof(ft));
 
-               ibuf_add(buf, &map->type, sizeof(map->type));
+               err |= ibuf_add(buf, &map->type, sizeof(map->type));
                family = htons(map->fec.prefix.af);
-               ibuf_add(buf, &family, sizeof(family));
-               ibuf_add(buf, &map->fec.prefix.prefixlen,
+               err |= ibuf_add(buf, &family, sizeof(family));
+               err |= ibuf_add(buf, &map->fec.prefix.prefixlen,
                    sizeof(map->fec.prefix.prefixlen));
                if (len)
-                       ibuf_add(buf, &map->fec.prefix.prefix, len);
+                       err |= ibuf_add(buf, &map->fec.prefix.prefix, len);
                break;
        case MAP_TYPE_PWID:
                if (map->flags & F_MAP_PW_ID)
@@ -545,35 +551,37 @@ gen_fec_tlv(struct ibuf *buf, struct map *map)
                len = FEC_PWID_ELM_MIN_LEN + pw_len;
 
                ft.length = htons(len);
-               ibuf_add(buf, &ft, sizeof(ft));
+               err |= ibuf_add(buf, &ft, sizeof(ft));
 
-               ibuf_add(buf, &map->type, sizeof(uint8_t));
+               err |= ibuf_add(buf, &map->type, sizeof(uint8_t));
                pw_type = map->fec.pwid.type;
                if (map->flags & F_MAP_PW_CWORD)
                        pw_type |= CONTROL_WORD_FLAG;
                pw_type = htons(pw_type);
-               ibuf_add(buf, &pw_type, sizeof(uint16_t));
-               ibuf_add(buf, &pw_len, sizeof(uint8_t));
+               err |= ibuf_add(buf, &pw_type, sizeof(uint16_t));
+               err |= ibuf_add(buf, &pw_len, sizeof(uint8_t));
                group_id = htonl(map->fec.pwid.group_id);
-               ibuf_add(buf, &group_id, sizeof(uint32_t));
+               err |= ibuf_add(buf, &group_id, sizeof(uint32_t));
                if (map->flags & F_MAP_PW_ID) {
                        pwid = htonl(map->fec.pwid.pwid);
-                       ibuf_add(buf, &pwid, sizeof(uint32_t));
+                       err |= ibuf_add(buf, &pwid, sizeof(uint32_t));
                }
                if (map->flags & F_MAP_PW_IFMTU) {
                        struct subtlv   stlv;
 
                        stlv.type = SUBTLV_IFMTU;
                        stlv.length = FEC_SUBTLV_IFMTU_LEN;
-                       ibuf_add(buf, &stlv, sizeof(uint16_t));
+                       err |= ibuf_add(buf, &stlv, sizeof(uint16_t));
 
                        ifmtu = htons(map->fec.pwid.ifmtu);
-                       ibuf_add(buf, &ifmtu, sizeof(uint16_t));
+                       err |= ibuf_add(buf, &ifmtu, sizeof(uint16_t));
                }
                break;
        default:
                break;
        }
+
+       return (err);
 }
 
 int
index 9c52a3e..dade57b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ldpe.h,v 1.62 2016/06/18 17:31:32 renato Exp $ */
+/*     $OpenBSD: ldpe.h,v 1.63 2016/06/27 19:06:33 renato Exp $ */
 
 /*
  * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -169,8 +169,8 @@ int  recv_address(struct nbr *, char *, uint16_t);
 #define PREFIX_SIZE(x) (((x) + 7) / 8)
 void    send_labelmessage(struct nbr *, uint16_t, struct mapping_head *);
 int     recv_labelmessage(struct nbr *, char *, uint16_t, uint16_t);
-void    gen_pw_status_tlv(struct ibuf *, uint32_t);
-void    gen_fec_tlv(struct ibuf *, struct map *);
+int     gen_pw_status_tlv(struct ibuf *, uint32_t);
+int     gen_fec_tlv(struct ibuf *, struct map *);
 int     tlv_decode_fec_elm(struct nbr *, struct ldp_msg *, char *,
            uint16_t, struct map *);
 
index 06233cf..e6c9cc9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: notification.c,v 1.35 2016/06/11 01:55:35 renato Exp $ */
+/*     $OpenBSD: notification.c,v 1.36 2016/06/27 19:06:33 renato Exp $ */
 
 /*
  * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -32,6 +32,7 @@ send_notification_full(struct tcp_conn *tcp, struct notify_msg *nm)
 {
        struct ibuf     *buf;
        uint16_t         size;
+       int              err = 0;
 
        /* calculate size */
        size = LDP_HDR_SIZE + LDP_MSG_SIZE + STATUS_SIZE;
@@ -51,15 +52,19 @@ send_notification_full(struct tcp_conn *tcp, struct notify_msg *nm)
        if ((buf = ibuf_open(size)) == NULL)
                fatal(__func__);
 
-       gen_ldp_hdr(buf, size);
+       err |= gen_ldp_hdr(buf, size);
        size -= LDP_HDR_SIZE;
-       gen_msg_hdr(buf, MSG_TYPE_NOTIFICATION, size);
-       gen_status_tlv(buf, nm->status, nm->messageid, nm->type);
+       err |= gen_msg_hdr(buf, MSG_TYPE_NOTIFICATION, size);
+       err |= gen_status_tlv(buf, nm->status, nm->messageid, nm->type);
        /* optional tlvs */
        if (nm->flags & F_NOTIF_PW_STATUS)
-               gen_pw_status_tlv(buf, nm->pw_status);
+               err |= gen_pw_status_tlv(buf, nm->pw_status);
        if (nm->flags & F_NOTIF_FEC)
-               gen_fec_tlv(buf, &nm->fec);
+               err |= gen_fec_tlv(buf, &nm->fec);
+       if (err) {
+               ibuf_free(buf);
+               return;
+       }
 
        evbuf_enqueue(&tcp->wbuf, buf);
 }