libbpf: Avoid allocating reg_name with sscanf in parse_usdt_arg()
authorXu Kuohai <xukuohai@huawei.com>
Tue, 18 Oct 2022 14:55:38 +0000 (10:55 -0400)
committerAndrii Nakryiko <andrii@kernel.org>
Fri, 21 Oct 2022 21:28:14 +0000 (14:28 -0700)
The reg_name in parse_usdt_arg() is used to hold register name, which
is short enough to be held in a 16-byte array, so we could define
reg_name as char reg_name[16] to avoid dynamically allocating reg_name
with sscanf.

Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Signed-off-by: Xu Kuohai <xukuohai@huawei.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Stanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/bpf/20221018145538.2046842-1-xukuohai@huaweicloud.com
tools/lib/bpf/usdt.c

index 49f3c3b7f60954a6fe1732e1129f9b99b01a02c5..28fa1b2283de6eec22dcb0876adc187f6dee92d6 100644 (file)
@@ -1225,26 +1225,24 @@ 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 @ %ld ( %%%m[^)] ) %n", &arg_sz, &off, &reg_name, &len) == 3) {
+       if (sscanf(arg_str, " %d @ %ld ( %%%15[^)] ) %n", &arg_sz, &off, reg_name, &len) == 3) {
                /* Memory dereference case, e.g., -4@-20(%rbp) */
                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 @ %%%ms %n", &arg_sz, &reg_name, &len) == 2) {
+       } else if (sscanf(arg_str, " %d @ %%%15s %n", &arg_sz, reg_name, &len) == 2) {
                /* Register read case, e.g., -4@%eax */
                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;
@@ -1456,16 +1454,15 @@ 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 @ %ld ( %m[a-z0-9] ) %n", &arg_sz, &off, &reg_name, &len) == 3) {
+       if (sscanf(arg_str, " %d @ %ld ( %15[a-z0-9] ) %n", &arg_sz, &off, reg_name, &len) == 3) {
                /* Memory dereference case, e.g., -8@-88(s0) */
                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;
@@ -1474,12 +1471,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@a1 */
                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;