libbpf: Fix memory leak in parse_usdt_arg()
authorXu Kuohai <xukuohai@huawei.com>
Tue, 11 Oct 2022 12:01:04 +0000 (08:01 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 31 Dec 2022 12:32:02 +0000 (13:32 +0100)
[ Upstream commit 0dc9254e03704c75f2ebc9cbef2ce4de83fba603 ]

In the arm64 version of parse_usdt_arg(), when sscanf returns 2, reg_name
is allocated but not freed. Fix it.

Fixes: 0f8619929c57 ("libbpf: Usdt aarch64 arg parsing support")
Signed-off-by: Xu Kuohai <xukuohai@huawei.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/bpf/20221011120108.782373-3-xukuohai@huaweicloud.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
tools/lib/bpf/usdt.c

index e83b497..49f3c3b 100644 (file)
@@ -1348,25 +1348,23 @@ static int calc_pt_regs_off(const char *reg_name)
 
 static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec *arg)
 {
-       char *reg_name = NULL;
+       char reg_name[16];
        int arg_sz, len, reg_off;
        long off;
 
-       if (sscanf(arg_str, " %d @ \[ %m[a-z0-9], %ld ] %n", &arg_sz, &reg_name, &off, &len) == 3) {
+       if (sscanf(arg_str, " %d @ \[ %15[a-z0-9], %ld ] %n", &arg_sz, reg_name, &off, &len) == 3) {
                /* Memory dereference case, e.g., -4@[sp, 96] */
                arg->arg_type = USDT_ARG_REG_DEREF;
                arg->val_off = off;
                reg_off = calc_pt_regs_off(reg_name);
-               free(reg_name);
                if (reg_off < 0)
                        return reg_off;
                arg->reg_off = reg_off;
-       } else if (sscanf(arg_str, " %d @ \[ %m[a-z0-9] ] %n", &arg_sz, &reg_name, &len) == 2) {
+       } else if (sscanf(arg_str, " %d @ \[ %15[a-z0-9] ] %n", &arg_sz, reg_name, &len) == 2) {
                /* Memory dereference case, e.g., -4@[sp] */
                arg->arg_type = USDT_ARG_REG_DEREF;
                arg->val_off = 0;
                reg_off = calc_pt_regs_off(reg_name);
-               free(reg_name);
                if (reg_off < 0)
                        return reg_off;
                arg->reg_off = reg_off;
@@ -1375,12 +1373,11 @@ static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec
                arg->arg_type = USDT_ARG_CONST;
                arg->val_off = off;
                arg->reg_off = 0;
-       } else if (sscanf(arg_str, " %d @ %m[a-z0-9] %n", &arg_sz, &reg_name, &len) == 2) {
+       } else if (sscanf(arg_str, " %d @ %15[a-z0-9] %n", &arg_sz, reg_name, &len) == 2) {
                /* Register read case, e.g., -8@x4 */
                arg->arg_type = USDT_ARG_REG;
                arg->val_off = 0;
                reg_off = calc_pt_regs_off(reg_name);
-               free(reg_name);
                if (reg_off < 0)
                        return reg_off;
                arg->reg_off = reg_off;