Fix bug of `sysctl` in tools/compat/sysctl.c.

The ff msg shouldn't to free while `ff_ipc_send` success but `ff_ipc_recv` failed (such as F-Stack app are breaking by gdb).
This commit is contained in:
fengbojiang 2020-11-21 21:27:55 +08:00
parent 9817534a21
commit 32ff8fda83
3 changed files with 21 additions and 14 deletions

View File

@ -443,6 +443,8 @@ ff_msg_init(struct rte_mempool *mp,
msg->msg_type = FF_UNKNOWN;
msg->buf_addr = (char *)msg + sizeof(struct ff_msg);
msg->buf_len = mp->elt_size - sizeof(struct ff_msg);
msg->original_buf = NULL;
msg->original_buf_len = 0;
}
static int

View File

@ -137,6 +137,8 @@ struct ff_msg {
size_t buf_len;
/* Address of segment buffer. */
char *buf_addr;
char *original_buf;
size_t original_buf_len;
union {
struct ff_sysctl_args sysctl;

View File

@ -30,13 +30,23 @@
#include "ff_ipc.h"
#define FREE_FF_MSG(m) do { \
if (m->original_buf) { \
rte_free(m->buf_addr); \
m->buf_addr = m->original_buf; \
m->buf_len = m->original_buf_len; \
m->original_buf = NULL; \
} \
ff_ipc_msg_free(m); \
} while (0);
int
sysctl(int *name, unsigned namelen, void *old,
size_t *oldlenp, const void *new, size_t newlen)
{
struct ff_msg *msg, *retmsg = NULL;
char *extra_buf = NULL, *original_buf = NULL;
size_t total_len, original_buf_len;
char *extra_buf = NULL;
size_t total_len;
if (old != NULL && oldlenp == NULL) {
errno = EINVAL;
@ -62,8 +72,8 @@ sysctl(int *name, unsigned namelen, void *old,
ff_ipc_msg_free(msg);
return -1;
}
original_buf = msg->buf_addr;
original_buf_len = msg->buf_len;
msg->original_buf = msg->buf_addr;
msg->original_buf_len = msg->buf_len;
msg->buf_addr = extra_buf;
msg->buf_len = total_len;
}
@ -113,12 +123,12 @@ sysctl(int *name, unsigned namelen, void *old,
do {
if (retmsg != NULL) {
ff_ipc_msg_free(retmsg);
FREE_FF_MSG(retmsg)
}
ret = ff_ipc_recv(&retmsg, msg->msg_type);
if (ret < 0) {
errno = EPIPE;
goto error;
return -1;
}
} while (msg != retmsg);
@ -137,14 +147,7 @@ sysctl(int *name, unsigned namelen, void *old,
}
error:
if (original_buf) {
msg->buf_addr = original_buf;
msg->buf_len = original_buf_len;
}
ff_ipc_msg_free(msg);
if (extra_buf) {
rte_free(extra_buf);
}
FREE_FF_MSG(msg)
return ret;
}