From: Etienne AUJAMES Date: Tue, 19 Oct 2021 14:10:43 +0000 (+0200) Subject: LU-15130 nrs: null pointer dereference in nrs_tbf_id_parse X-Git-Tag: 2.14.57~45 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F91%2F45291%2F4;p=fs%2Flustre-release.git LU-15130 nrs: null pointer dereference in nrs_tbf_id_parse cfs_gettok() set next->ls_str to NULL if no delimiter is found but it does not update next->ls_len to 0. We have to check if next->ls_str is null inside nrs_tbf_id_parse() to verify if the tbf expression is valid. * Reproducer * lctl set_param mds.MDS.mdt.nrs_tbf_rule="start tbf_name gid{500} rate=100" This patch fix cfs_gettok() to update "next->ls_len = 0;" if no delimiter is found. Signed-off-by: Etienne AUJAMES Change-Id: Iaa4eb5085262cee547ea3a944ddb94c6df1f8aa3 Reviewed-on: https://review.whamcloud.com/45291 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Li Xi Reviewed-by: Oleg Drokin --- diff --git a/libcfs/libcfs/libcfs_string.c b/libcfs/libcfs/libcfs_string.c index 5549417..7ba00df 100644 --- a/libcfs/libcfs/libcfs_string.c +++ b/libcfs/libcfs/libcfs_string.c @@ -151,6 +151,7 @@ cfs_gettok(struct cfs_lstr *next, char delim, struct cfs_lstr *res) /* there is no the delimeter in the string */ end = next->ls_str + next->ls_len; next->ls_str = NULL; + next->ls_len = 0; } else { next->ls_str = end + 1; next->ls_len -= (end - res->ls_str + 1); diff --git a/libcfs/libcfs/util/string.c b/libcfs/libcfs/util/string.c index 9e92339..700f002 100644 --- a/libcfs/libcfs/util/string.c +++ b/libcfs/libcfs/util/string.c @@ -84,6 +84,7 @@ cfs_gettok(struct cfs_lstr *next, char delim, struct cfs_lstr *res) /* there is no the delimeter in the string */ end = next->ls_str + next->ls_len; next->ls_str = NULL; + next->ls_len = 0; } else { next->ls_str = end + 1; next->ls_len -= (end - res->ls_str + 1); diff --git a/lustre/ptlrpc/nrs_tbf.c b/lustre/ptlrpc/nrs_tbf.c index 37edf58..2b819e7 100644 --- a/lustre/ptlrpc/nrs_tbf.c +++ b/lustre/ptlrpc/nrs_tbf.c @@ -929,8 +929,8 @@ static int nrs_tbf_check_id_value(struct cfs_lstr *src, char *key) rc = cfs_gettok(src, '=', &res); if (rc == 0 || res.ls_len != keylen || strncmp(res.ls_str, key, keylen) != 0 || - src->ls_len <= 2 || src->ls_str[0] != '{' || - src->ls_str[src->ls_len - 1] != '}') + !src->ls_str || src->ls_len <= 2 || + src->ls_str[0] != '{' || src->ls_str[src->ls_len - 1] != '}') return -EINVAL; /* Skip '{' and '}' */ @@ -1840,8 +1840,8 @@ nrs_tbf_expression_parse(struct cfs_lstr *src, struct list_head *cond_list) return -ENOMEM; rc = cfs_gettok(src, NRS_TBF_EXPRESSION_DELIM, &field); - if (rc == 0 || src->ls_len <= 2 || src->ls_str[0] != '{' || - src->ls_str[src->ls_len - 1] != '}') + if (rc == 0 || !src->ls_str || src->ls_len <= 2 || + src->ls_str[0] != '{' || src->ls_str[src->ls_len - 1] != '}') GOTO(out, rc = -EINVAL); /* Skip '{' and '}' */