commit 080e5563f878 only checks for len > DLM_RESNAME_MAXLEN, which does
not catch negative values. While the input 'len' can be negative and a
negative int passed to memcpy() is implicitly converted to a large
size_t, causing a stack buffer overflow on the key[] array.
Fix this by changing the 'len' parameter type from int to unsigned int.
This ensures negative values from callers are implicitly converted to
large unsigned values that are caught by the existing
len > DLM_RESNAME_MAXLEN check.
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
---
fs/dlm/lock.c | 6 ++++--
fs/dlm/lock.h | 4 ++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index c381e1028446..373abdb4354a 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -622,12 +622,14 @@ static int get_rsb_struct(struct dlm_ls *ls, const void *name, int len,
return 0;
}
-int dlm_search_rsb_tree(struct rhashtable *rhash, const void *name, int len,
- struct dlm_rsb **r_ret)
+int dlm_search_rsb_tree(struct rhashtable *rhash, const void *name,
+ unsigned int len, struct dlm_rsb **r_ret)
{
char key[DLM_RESNAME_MAXLEN] = {};
+
if (len > DLM_RESNAME_MAXLEN)
return -EINVAL;
+
memcpy(key, name, len);
*r_ret = rhashtable_lookup_fast(rhash, &key, dlm_rhash_rsb_params);
if (*r_ret)
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h
index b23d7b854ed4..c75975937331 100644
--- a/fs/dlm/lock.h
+++ b/fs/dlm/lock.h
@@ -31,8 +31,8 @@ void resume_scan_timer(struct dlm_ls *ls);
int dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *name,
int len, unsigned int flags, int *r_nodeid, int *result);
-int dlm_search_rsb_tree(struct rhashtable *rhash, const void *name, int len,
- struct dlm_rsb **r_ret);
+int dlm_search_rsb_tree(struct rhashtable *rhash, const void *name,
+ unsigned int len, struct dlm_rsb **r_ret);
void dlm_recover_purge(struct dlm_ls *ls, const struct list_head *root_list);
void dlm_purge_mstcpy_locks(struct dlm_rsb *r);
--
2.39.3