Eliminate a number of instances of undefined behavior related to passing NULL in parameters having "nonnull" annotations.
Found with gcc's undefined behavior sanitizer. Signed-off-by: Lance Richardson <lrich...@redhat.com> --- Posting this as RFC because there is no apparent risk of unwanted compiler optimizations related to undefined behavior in existing code. The main value in fixing these issues is in reducing noise to make it easier to find problematic cases in the future. Here is a small example of the type of unwanted optimization to be concerned about: test1a.c: #include <stdio.h> extern void foo(char*, size_t); int main(int argc, char **argv) { char x[128]; foo(x, sizeof x); foo(NULL, 0); return 0; } test1b.c: #include <stdio.h> #include <string.h> void foo(char *bar, size_t len) { memset(bar, 0, len); if (bar) printf("bar is non-null: %p\n", bar); } Compile and run: gcc -o test -O2 test1a.c test1b.c ./test Output (second line might be a bit of a surprise): bar is non-null: 0x7fff80f90d50 bar is non-null: (nil) lib/netlink.c | 7 ++++++- lib/ofpbuf.c | 4 +++- lib/svec.c | 4 +++- lib/util.c | 4 +++- ovn/utilities/ovn-nbctl.c | 32 ++++++++++++++++++++++++-------- 5 files changed, 39 insertions(+), 12 deletions(-) diff --git a/lib/netlink.c b/lib/netlink.c index 3da22a1..fcad884 100644 --- a/lib/netlink.c +++ b/lib/netlink.c @@ -241,7 +241,12 @@ void nl_msg_put_unspec(struct ofpbuf *msg, uint16_t type, const void *data, size_t size) { - memcpy(nl_msg_put_unspec_uninit(msg, type, size), data, size); + void *ptr; + + ptr = nl_msg_put_unspec_uninit(msg, type, size); + if (size) { + memcpy(ptr, data, size); + } } /* Appends a Netlink attribute of the given 'type' and no payload to 'msg'. diff --git a/lib/ofpbuf.c b/lib/ofpbuf.c index 3019c4a..2e71fed 100644 --- a/lib/ofpbuf.c +++ b/lib/ofpbuf.c @@ -375,7 +375,9 @@ void * ofpbuf_put_zeros(struct ofpbuf *b, size_t size) { void *dst = ofpbuf_put_uninit(b, size); - memset(dst, 0, size); + if (size) { + memset(dst, 0, size); + } return dst; } diff --git a/lib/svec.c b/lib/svec.c index aad04e3..297a60c 100644 --- a/lib/svec.c +++ b/lib/svec.c @@ -127,7 +127,9 @@ compare_strings(const void *a_, const void *b_) void svec_sort(struct svec *svec) { - qsort(svec->names, svec->n, sizeof *svec->names, compare_strings); + if (svec->n) { + qsort(svec->names, svec->n, sizeof *svec->names, compare_strings); + } } void diff --git a/lib/util.c b/lib/util.c index b2a1f8a..ddf8546 100644 --- a/lib/util.c +++ b/lib/util.c @@ -132,7 +132,9 @@ void * xmemdup(const void *p_, size_t size) { void *p = xmalloc(size); - memcpy(p, p_, size); + if (size) { + memcpy(p, p_, size); + } return p; } diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c index bd0160a..3b2d3e9 100644 --- a/ovn/utilities/ovn-nbctl.c +++ b/ovn/utilities/ovn-nbctl.c @@ -920,7 +920,9 @@ nbctl_lsp_add(struct ctl_context *ctx) nbrec_logical_switch_verify_ports(ls); struct nbrec_logical_switch_port **new_ports = xmalloc(sizeof *new_ports * (ls->n_ports + 1)); - memcpy(new_ports, ls->ports, sizeof *new_ports * ls->n_ports); + if (ls->n_ports) { + memcpy(new_ports, ls->ports, sizeof *new_ports * ls->n_ports); + } new_ports[ls->n_ports] = CONST_CAST(struct nbrec_logical_switch_port *, lsp); nbrec_logical_switch_set_ports(ls, new_ports, ls->n_ports + 1); @@ -1379,7 +1381,9 @@ nbctl_acl_add(struct ctl_context *ctx) /* Insert the acl into the logical switch. */ nbrec_logical_switch_verify_acls(ls); struct nbrec_acl **new_acls = xmalloc(sizeof *new_acls * (ls->n_acls + 1)); - memcpy(new_acls, ls->acls, sizeof *new_acls * ls->n_acls); + if (ls->n_acls) { + memcpy(new_acls, ls->acls, sizeof *new_acls * ls->n_acls); + } new_acls[ls->n_acls] = acl; nbrec_logical_switch_set_acls(ls, new_acls, ls->n_acls + 1); free(new_acls); @@ -1697,7 +1701,10 @@ nbctl_lr_lb_add(struct ctl_context *ctx) struct nbrec_load_balancer **new_lbs = xmalloc(sizeof *new_lbs * (lr->n_load_balancer + 1)); - memcpy(new_lbs, lr->load_balancer, sizeof *new_lbs * lr->n_load_balancer); + if (lr->n_load_balancer) { + memcpy(new_lbs, lr->load_balancer, + sizeof *new_lbs * lr->n_load_balancer); + } new_lbs[lr->n_load_balancer] = CONST_CAST(struct nbrec_load_balancer *, new_lb); nbrec_logical_router_set_load_balancer(lr, new_lbs, @@ -1793,7 +1800,10 @@ nbctl_ls_lb_add(struct ctl_context *ctx) struct nbrec_load_balancer **new_lbs = xmalloc(sizeof *new_lbs * (ls->n_load_balancer + 1)); - memcpy(new_lbs, ls->load_balancer, sizeof *new_lbs * ls->n_load_balancer); + if (ls->n_load_balancer) { + memcpy(new_lbs, ls->load_balancer, + sizeof *new_lbs * ls->n_load_balancer); + } new_lbs[ls->n_load_balancer] = CONST_CAST(struct nbrec_load_balancer *, new_lb); nbrec_logical_switch_set_load_balancer(ls, new_lbs, @@ -2200,8 +2210,10 @@ nbctl_lr_route_add(struct ctl_context *ctx) nbrec_logical_router_verify_static_routes(lr); struct nbrec_logical_router_static_route **new_routes = xmalloc(sizeof *new_routes * (lr->n_static_routes + 1)); - memcpy(new_routes, lr->static_routes, - sizeof *new_routes * lr->n_static_routes); + if (lr->n_static_routes) { + memcpy(new_routes, lr->static_routes, + sizeof *new_routes * lr->n_static_routes); + } new_routes[lr->n_static_routes] = route; nbrec_logical_router_set_static_routes(lr, new_routes, lr->n_static_routes + 1); @@ -2364,7 +2376,9 @@ nbctl_lr_nat_add(struct ctl_context *ctx) /* Insert the NAT into the logical router. */ nbrec_logical_router_verify_nat(lr); struct nbrec_nat **new_nats = xmalloc(sizeof *new_nats * (lr->n_nat + 1)); - memcpy(new_nats, lr->nat, sizeof *new_nats * lr->n_nat); + if (lr->n_nat) { + memcpy(new_nats, lr->nat, sizeof *new_nats * lr->n_nat); + } new_nats[lr->n_nat] = nat; nbrec_logical_router_set_nat(lr, new_nats, lr->n_nat + 1); free(new_nats); @@ -2642,7 +2656,9 @@ nbctl_lrp_add(struct ctl_context *ctx) nbrec_logical_router_verify_ports(lr); struct nbrec_logical_router_port **new_ports = xmalloc(sizeof *new_ports * (lr->n_ports + 1)); - memcpy(new_ports, lr->ports, sizeof *new_ports * lr->n_ports); + if (lr->n_ports) { + memcpy(new_ports, lr->ports, sizeof *new_ports * lr->n_ports); + } new_ports[lr->n_ports] = CONST_CAST(struct nbrec_logical_router_port *, lrp); nbrec_logical_router_set_ports(lr, new_ports, lr->n_ports + 1); -- 2.9.4 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev