mirror of
https://github.com/openvswitch/ovs
synced 2025-08-30 05:47:55 +00:00
ofp-parse: Don't segfault when an OpenFlow action's argument is missing.
Some actions checked that 'arg' was nonnull before attempting to parse it but a lot of them didn't. This commit avoids the segfault by substituting an empty string when no argument is given. It also updates a few of the action implementations to correspond. Reported-by: Reid Price <reid@nicira.com> Bug #4462. Coverity #10712.
This commit is contained in:
parent
338bd6a0fe
commit
c4894ed48f
@ -43,7 +43,7 @@ str_to_u32(const char *str)
|
|||||||
char *tail;
|
char *tail;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
|
|
||||||
if (!str) {
|
if (!str[0]) {
|
||||||
ovs_fatal(0, "missing required numeric argument");
|
ovs_fatal(0, "missing required numeric argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +61,10 @@ str_to_u64(const char *str)
|
|||||||
char *tail;
|
char *tail;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
|
||||||
|
if (!str[0]) {
|
||||||
|
ovs_fatal(0, "missing required numeric argument");
|
||||||
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
value = strtoull(str, &tail, 0);
|
value = strtoull(str, &tail, 0);
|
||||||
if (errno == EINVAL || errno == ERANGE || *tail) {
|
if (errno == EINVAL || errno == ERANGE || *tail) {
|
||||||
@ -271,6 +275,7 @@ str_to_action(char *str, struct ofpbuf *b)
|
|||||||
pos = str;
|
pos = str;
|
||||||
n_actions = 0;
|
n_actions = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
char empty_string[] = "";
|
||||||
char *act, *arg;
|
char *act, *arg;
|
||||||
size_t actlen;
|
size_t actlen;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
@ -320,7 +325,7 @@ str_to_action(char *str, struct ofpbuf *b)
|
|||||||
pos = arg + arglen;
|
pos = arg + arglen;
|
||||||
} else {
|
} else {
|
||||||
/* There might be no argument at all. */
|
/* There might be no argument at all. */
|
||||||
arg = NULL;
|
arg = empty_string;
|
||||||
pos = act + actlen + (act[actlen] != '\0');
|
pos = act + actlen + (act[actlen] != '\0');
|
||||||
}
|
}
|
||||||
act[actlen] = '\0';
|
act[actlen] = '\0';
|
||||||
@ -410,7 +415,7 @@ str_to_action(char *str, struct ofpbuf *b)
|
|||||||
nan->subtype = htons(NXAST_NOTE);
|
nan->subtype = htons(NXAST_NOTE);
|
||||||
|
|
||||||
b->size -= sizeof nan->note;
|
b->size -= sizeof nan->note;
|
||||||
while (arg && *arg != '\0') {
|
while (*arg != '\0') {
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
bool ok;
|
bool ok;
|
||||||
|
|
||||||
@ -472,7 +477,7 @@ str_to_action(char *str, struct ofpbuf *b)
|
|||||||
|
|
||||||
/* Unless a numeric argument is specified, we send the whole
|
/* Unless a numeric argument is specified, we send the whole
|
||||||
* packet to the controller. */
|
* packet to the controller. */
|
||||||
if (arg && (strspn(arg, "0123456789") == strlen(arg))) {
|
if (arg[0] && (strspn(arg, "0123456789") == strlen(arg))) {
|
||||||
oao->max_len = htons(str_to_u32(arg));
|
oao->max_len = htons(str_to_u32(arg));
|
||||||
} else {
|
} else {
|
||||||
oao->max_len = htons(UINT16_MAX);
|
oao->max_len = htons(UINT16_MAX);
|
||||||
@ -909,4 +914,3 @@ parse_ofp_flow_stats_request_str(struct flow_stats_request *fsr,
|
|||||||
fsr->out_port = fm.out_port;
|
fsr->out_port = fm.out_port;
|
||||||
fsr->table_id = table_id;
|
fsr->table_id = table_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user