diff options
-rw-r--r-- | lib/rtnl.c | 30 | ||||
-rw-r--r-- | lib/struct.c | 9 |
2 files changed, 27 insertions, 12 deletions
@@ -1345,10 +1345,13 @@ uc_nl_convert_attrs(struct nl_msg *msg, void *buf, size_t buflen, size_t headsiz if (!tb) return false; - if (buflen > headsize) - nla_parse(tb, maxattr, buf + headsize, buflen - headsize, NULL); - else + if (buflen > headsize) { + if (maxattr) + nla_parse(tb, maxattr, buf + headsize, buflen - headsize, NULL); + } + else { structlen = buflen; + } for (i = 0; i < nattrs; i++) { if (attrs[i].attr == 0 && (uintptr_t)attrs[i].auxdata >= structlen) @@ -3088,10 +3091,7 @@ cb_reply(struct nl_msg *msg, void *arg) } } - if (hdr->nlmsg_flags & NLM_F_MULTI) - s->state = STATE_CONTINUE; - else - s->state = STATE_REPLIED; + s->state = STATE_CONTINUE; return NL_SKIP; } @@ -3122,6 +3122,7 @@ uc_nl_request(uc_vm_t *vm, size_t nargs) int enable = 1, err; struct nl_msg *msg; struct nl_cb *cb; + void *buf; size_t i; if (ucv_type(cmd) != UC_INTEGER || ucv_int64_get(cmd) < 0 || @@ -3169,7 +3170,17 @@ uc_nl_request(uc_vm_t *vm, size_t nargs) err_return(NLE_NOMEM, NULL); if (st.spec) { - nlmsg_reserve(msg, st.spec->headsize, 0); + if (st.spec->headsize) { + buf = nlmsg_reserve(msg, st.spec->headsize, 0); + + if (!buf) { + nlmsg_free(msg); + + return NULL; + } + + memset(buf, 0, st.spec->headsize); + } if (!uc_nl_parse_attrs(msg, NLMSG_DATA(nlmsg_hdr(msg)), st.spec->attrs, st.spec->nattrs, vm, payload)) { nlmsg_free(msg); @@ -3187,6 +3198,7 @@ uc_nl_request(uc_vm_t *vm, size_t nargs) nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_reply, &st); nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_done, &st); nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st); nl_send_auto_complete(sock, msg); @@ -3200,7 +3212,7 @@ uc_nl_request(uc_vm_t *vm, size_t nargs) st.state = STATE_ERROR; } } - while (st.state == STATE_CONTINUE); + while (st.state < STATE_REPLIED); nlmsg_free(msg); nl_cb_put(cb); diff --git a/lib/struct.c b/lib/struct.c index 5d301db..bd418b2 100644 --- a/lib/struct.c +++ b/lib/struct.c @@ -2182,17 +2182,17 @@ overflow: static uc_value_t * uc_pack_common(uc_vm_t *vm, size_t nargs, formatstate_t *state, size_t argoff) { + size_t ncode, arg, off; formatcode_t *code; - size_t ncode, off; uc_string_t *buf; ssize_t size, n; const void *p; - for (ncode = 0, code = &state->codes[0], off = 0; + for (ncode = 0, code = &state->codes[0], arg = argoff, off = 0; ncode < state->ncodes; code = &state->codes[++ncode]) { if (code->fmtdef->format == '*') { - uc_value_t *v = uc_fn_arg(argoff + ncode); + uc_value_t *v = uc_fn_arg(arg++); if (ucv_type(v) != UC_STRING) continue; @@ -2204,6 +2204,9 @@ uc_pack_common(uc_vm_t *vm, size_t nargs, formatstate_t *state, size_t argoff) else off += code->size; } + else { + arg += code->repeat; + } } buf = xalloc(sizeof(*buf) + state->size + off + 1); |