iproute2/rdma/res-ctx.c
wenglianfa 3a882b6b4e rdma: Fix the error of accessing string variable outside the lifecycle
All these SPRINT_BUF(b) definitions are inside the 'if' block, but
accessed outside the 'if' block through the pointers 'comm'. This
leads to empty 'comm' attribute when querying resource information.
So move the definitions to the beginning of the functions to extend
their life cycle.

Before:
$ rdma res show srq
dev hns_0 srqn 0 type BASIC lqpn 18 pdn 5 pid 7775 comm

After:
$ rdma res show srq
dev hns_0 srqn 0 type BASIC lqpn 18 pdn 5 pid 7775 comm ib_send_bw

Fixes: 1808f002df ("lib/fs: fix memory leak in get_task_name()")
Signed-off-by: wenglianfa <wenglianfa@huawei.com>
Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Acked-by: Andrea Claudi <aclaudi@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
2024-01-08 08:45:17 -08:00

104 lines
2.6 KiB
C

// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/*
* res-ctx.c RDMA tool
* Authors: Neta Ostrovsky <netao@nvidia.com>
*/
#include "res.h"
#include <inttypes.h>
static int res_ctx_line(struct rd *rd, const char *name, int idx,
struct nlattr **nla_line)
{
char *comm = NULL;
uint32_t ctxn = 0;
uint32_t pid = 0;
SPRINT_BUF(b);
if (!nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
return MNL_CB_ERROR;
if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]);
if (!get_task_name(pid, b, sizeof(b)))
comm = b;
} else if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) {
/* discard const from mnl_attr_get_str */
comm = (char *)mnl_attr_get_str(
nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
}
if (rd_is_filtered_attr(rd, "pid", pid,
nla_line[RDMA_NLDEV_ATTR_RES_PID]))
goto out;
if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
ctxn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
if (rd_is_filtered_attr(rd, "ctxn", ctxn,
nla_line[RDMA_NLDEV_ATTR_RES_CTXN]))
goto out;
open_json_object(NULL);
print_dev(idx, name);
res_print_u32("ctxn", ctxn, nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
res_print_u32("pid", pid, nla_line[RDMA_NLDEV_ATTR_RES_PID]);
print_comm(comm, nla_line);
print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
close_json_object();
newline();
out:
return MNL_CB_OK;
}
int res_ctx_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
struct rd *rd = data;
const char *name;
uint32_t idx;
mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
return MNL_CB_ERROR;
name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
return res_ctx_line(rd, name, idx, tb);
}
int res_ctx_parse_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
struct nlattr *nla_table, *nla_entry;
struct rd *rd = data;
int ret = MNL_CB_OK;
const char *name;
uint32_t idx;
mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME] ||
!tb[RDMA_NLDEV_ATTR_RES_CTX])
return MNL_CB_ERROR;
name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
nla_table = tb[RDMA_NLDEV_ATTR_RES_CTX];
mnl_attr_for_each_nested(nla_entry, nla_table) {
struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
if (ret != MNL_CB_OK)
break;
ret = res_ctx_line(rd, name, idx, nla_line);
if (ret != MNL_CB_OK)
break;
}
return ret;
}