Commit d9740535 authored by Xu Kuohai's avatar Xu Kuohai Committed by Andrii Nakryiko
Browse files

libbpf: Avoid allocating reg_name with sscanf in parse_usdt_arg()



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: default avatarAndrii Nakryiko <andrii.nakryiko@gmail.com>
Signed-off-by: default avatarXu Kuohai <xukuohai@huawei.com>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Acked-by: default avatarStanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/bpf/20221018145538.2046842-1-xukuohai@huaweicloud.com
parent eb814cf1
Loading
Loading
Loading
Loading
+6 −10
Original line number Diff line number Diff line
@@ -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;