"http-request capture <expr> id <idx>" and "http-response capture <expr> id
<idx>" parse their identifier with strtol() and only reject trailing garbage:
id = strtol(args[cur_arg], &error, 10);
if (*error != '\0') {
memprintf(err, "cannot parse id '%s'", args[cur_arg]);
A negative identifier is therefore accepted at boot. The check functions only
verify the upper bound ("idx >= px->nb_req_cap"), and even that only for a proxy
with the frontend capability, so nothing complains. At run time,
http_action_req_capture_by_id() looks the slot up by walking the capture list
backwards:
for (h = fe->req_cap, i = fe->nb_req_cap - 1;
h != NULL && i != rule->arg.capid.idx ;
i--, h = h->next);
if (!h)
return ACT_RET_CONT;
<i> never matches a negative <idx> so the walk ends on a NULL <h> and the action
silently does nothing. There is no out-of-bounds access here, unlike in the
"capture.req.hdr" sample fetch, but a configuration that can only ever be a
no-op must be rejected rather than silently ignored.
Let's reject negative ids where they are parsed, which also covers the proxies
that have no frontend capability and are thus not checked at all.
This should be backported to all supported versions.
}
id = strtol(args[cur_arg], &error, 10);
- if (*error != '\0') {
+ if (*error != '\0' || id < 0) {
memprintf(err, "cannot parse id '%s'", args[cur_arg]);
release_sample_expr(expr);
return ACT_RET_PRS_ERR;
}
id = strtol(args[cur_arg], &error, 10);
- if (*error != '\0') {
+ if (*error != '\0' || id < 0) {
memprintf(err, "cannot parse id '%s'", args[cur_arg]);
release_sample_expr(expr);
return ACT_RET_PRS_ERR;