zebra: check for buffer boundary

* Move code encoding Netlink messages to separate functions
 * Add buffer bounds checking while creating Nelink messages

Signed-off-by: Jakub Urbańczyk <xthaid@gmail.com>
This commit is contained in:
Jakub Urbańczyk 2020-06-10 11:44:31 +02:00
parent 312a6beed6
commit 0be6e7d75d
5 changed files with 463 additions and 270 deletions

View File

@ -709,11 +709,12 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
switch (op) {
case DPLANE_OP_ROUTE_UPDATE:
case DPLANE_OP_ROUTE_DELETE:
rv = netlink_route_multipath(RTM_DELROUTE, ctx, nl_buf,
sizeof(nl_buf), true,
fnc->use_nhg);
rv = netlink_route_multipath_msg_encode(RTM_DELROUTE, ctx,
nl_buf, sizeof(nl_buf),
true, fnc->use_nhg);
if (rv <= 0) {
zlog_err("%s: netlink_route_multipath failed",
zlog_err(
"%s: netlink_route_multipath_msg_encode failed",
__func__);
return 0;
}
@ -726,11 +727,12 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
/* FALL THROUGH */
case DPLANE_OP_ROUTE_INSTALL:
rv = netlink_route_multipath(
rv = netlink_route_multipath_msg_encode(
RTM_NEWROUTE, ctx, &nl_buf[nl_buf_len],
sizeof(nl_buf) - nl_buf_len, true, fnc->use_nhg);
if (rv <= 0) {
zlog_err("%s: netlink_route_multipath failed",
zlog_err(
"%s: netlink_route_multipath_msg_encode failed",
__func__);
return 0;
}
@ -751,10 +753,11 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
break;
case DPLANE_OP_NH_DELETE:
rv = netlink_nexthop_encode(RTM_DELNEXTHOP, ctx, nl_buf,
rv = netlink_nexthop_msg_encode(RTM_DELNEXTHOP, ctx, nl_buf,
sizeof(nl_buf));
if (rv <= 0) {
zlog_err("%s: netlink_nexthop_encode failed", __func__);
zlog_err("%s: netlink_nexthop_msg_encode failed",
__func__);
return 0;
}
@ -762,10 +765,11 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
break;
case DPLANE_OP_NH_INSTALL:
case DPLANE_OP_NH_UPDATE:
rv = netlink_nexthop_encode(RTM_NEWNEXTHOP, ctx, nl_buf,
rv = netlink_nexthop_msg_encode(RTM_NEWNEXTHOP, ctx, nl_buf,
sizeof(nl_buf));
if (rv <= 0) {
zlog_err("%s: netlink_nexthop_encode failed", __func__);
zlog_err("%s: netlink_nexthop_msg_encode failed",
__func__);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -64,11 +64,14 @@ extern "C" {
void rt_netlink_init(void);
/* MPLS label forwarding table change, using dataplane context information. */
extern int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx);
extern ssize_t netlink_mpls_multipath_msg_encode(int cmd,
struct zebra_dplane_ctx *ctx,
void *buf, size_t buflen);
extern ssize_t netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx,
uint8_t *data, size_t datalen, bool fpm,
bool force_nhg);
extern ssize_t netlink_route_multipath_msg_encode(int cmd,
struct zebra_dplane_ctx *ctx,
uint8_t *data, size_t datalen,
bool fpm, bool force_nhg);
extern ssize_t netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx,
uint8_t *data, size_t datalen);
@ -78,7 +81,7 @@ extern int netlink_route_read(struct zebra_ns *zns);
extern int netlink_nexthop_change(struct nlmsghdr *h, ns_id_t ns_id,
int startup);
extern int netlink_nexthop_read(struct zebra_ns *zns);
extern ssize_t netlink_nexthop_encode(uint16_t cmd,
extern ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
const struct zebra_dplane_ctx *ctx,
void *buf, size_t buflen);

View File

@ -87,38 +87,48 @@ static ssize_t netlink_rule_msg_encode(
req->frh.family = family;
req->frh.action = FR_ACT_TO_TBL;
nl_attr_put(&req->n, buflen, FRA_PROTOCOL, &protocol, sizeof(protocol));
if (!nl_attr_put(&req->n, buflen, FRA_PROTOCOL, &protocol,
sizeof(protocol)))
return 0;
/* rule's pref # */
nl_attr_put32(&req->n, buflen, FRA_PRIORITY, priority);
if (!nl_attr_put32(&req->n, buflen, FRA_PRIORITY, priority))
return 0;
/* interface on which applied */
nl_attr_put(&req->n, buflen, FRA_IFNAME, ifname, strlen(ifname) + 1);
if (!nl_attr_put(&req->n, buflen, FRA_IFNAME, ifname,
strlen(ifname) + 1))
return 0;
/* source IP, if specified */
if (filter_bm & PBR_FILTER_SRC_IP) {
req->frh.src_len = src_ip->prefixlen;
nl_attr_put(&req->n, buflen, FRA_SRC, &src_ip->u.prefix,
bytelen);
if (!nl_attr_put(&req->n, buflen, FRA_SRC, &src_ip->u.prefix,
bytelen))
return 0;
}
/* destination IP, if specified */
if (filter_bm & PBR_FILTER_DST_IP) {
req->frh.dst_len = dst_ip->prefixlen;
nl_attr_put(&req->n, buflen, FRA_DST, &dst_ip->u.prefix,
bytelen);
if (!nl_attr_put(&req->n, buflen, FRA_DST, &dst_ip->u.prefix,
bytelen))
return 0;
}
/* fwmark, if specified */
if (filter_bm & PBR_FILTER_FWMARK)
nl_attr_put32(&req->n, buflen, FRA_FWMARK, fwmark);
if (filter_bm & PBR_FILTER_FWMARK) {
if (!nl_attr_put32(&req->n, buflen, FRA_FWMARK, fwmark))
return 0;
}
/* Route table to use to forward, if filter criteria matches. */
if (table < 256)
req->frh.table = table;
else {
req->frh.table = RT_TABLE_UNSPEC;
nl_attr_put32(&req->n, buflen, FRA_TABLE, table);
if (!nl_attr_put32(&req->n, buflen, FRA_TABLE, table))
return 0;
}
if (IS_ZEBRA_DEBUG_KERNEL)

View File

@ -26,13 +26,16 @@
#include "zebra/rt.h"
#include "zebra/rt_netlink.h"
#include "zebra/zebra_mpls.h"
#include "zebra/kernel_netlink.h"
/*
* LSP forwarding update using dataplane context information.
*/
enum zebra_dplane_result kernel_lsp_update(struct zebra_dplane_ctx *ctx)
{
int cmd, ret = -1;
uint8_t nl_pkt[NL_PKT_BUF_SIZE];
ssize_t ret = -1;
int cmd;
/* Call to netlink layer based on type of update */
if (dplane_ctx_get_op(ctx) == DPLANE_OP_LSP_DELETE) {
@ -53,7 +56,13 @@ enum zebra_dplane_result kernel_lsp_update(struct zebra_dplane_ctx *ctx)
/* Invalid op? */
goto done;
ret = netlink_mpls_multipath(cmd, ctx);
ret = netlink_mpls_multipath_msg_encode(cmd, ctx, nl_pkt,
sizeof(nl_pkt));
if (ret <= 0)
return ZEBRA_DPLANE_REQUEST_FAILURE;
ret = netlink_talk_info(netlink_talk_filter, (struct nlmsghdr *)nl_pkt,
dplane_ctx_get_ns(ctx), 0);
done: