From: Jingbo Xu jefflexu@linux.alibaba.com
anolis inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IB5UKT
Reference: https://gitee.com/anolis/cloud-kernel/commit/9342646eeaf7
--------------------------------
ANBZ: #3211
Prior to fscache refactoring, the volume key in fscache_volume is a string with trailing NUL; while after refactoring, the volume key in fscache_cookie is actually a string without trailing NUL.
Thus the current volume key setup for cachefiles_open may cause oops since it attempts to access volume key from the bad address. This can be reproduced by specifying "fsid" with 10 characters, e.g. "-o fsid=abigdomain".
Fix this by determining if volume key is stored in volume->key or volume->inline_key by checking volume->key_len, rather than volume_key_size (which is actually volume->key_len plus 1).
Reported-by: Jia Zhu zhujia.zj@bytedance.com Fixes: 8fc28945e193 ("cachefiles: notify the user daemon when looking up cookie") Signed-off-by: Jingbo Xu jefflexu@linux.alibaba.com Reviewed-by: Gao Xiang hsiangkao@linux.alibaba.com Acked-by: Joseph Qi joseph.qi@linux.alibaba.com Link: https://gitee.com/anolis/cloud-kernel/pulls/881 Link: https://gitee.com/anolis/cloud-kernel/pulls/884 Signed-off-by: Baokun Li libaokun1@huawei.com --- fs/cachefiles/ondemand.c | 14 ++++++++++---- include/uapi/linux/cachefiles.h | 5 +++-- 2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c index ee0d283ac863..0ea22ae2f96a 100644 --- a/fs/cachefiles/ondemand.c +++ b/fs/cachefiles/ondemand.c @@ -407,21 +407,27 @@ static int cachefiles_ondemand_init_open_req(struct cachefiles_req *req, { struct cachefiles_object *object = req->object; struct fscache_cookie *cookie = object->fscache.cookie; - struct fscache_cookie *volume; + struct fscache_cookie *volume = object->fscache.parent->cookie; struct cachefiles_open *load = (void *)req->msg.data; size_t volume_key_size, cookie_key_size; char *cookie_key, *volume_key;
- /* Cookie key is binary data, which is netfs specific. */ + /* + * cookie_key is a string without trailing '\0', while cachefiles_open + * expects cookie key a string without trailing '\0'. + */ cookie_key_size = cookie->key_len; if (cookie->key_len <= sizeof(cookie->inline_key)) cookie_key = cookie->inline_key; else cookie_key = cookie->key;
- volume = object->fscache.parent->cookie; + /* + * volume_key is a string without trailing '\0', while cachefiles_open + * expects volume key a string with trailing '\0'. + */ volume_key_size = volume->key_len + 1; - if (volume_key_size <= sizeof(cookie->inline_key)) + if (volume->key_len <= sizeof(volume->inline_key)) volume_key = volume->inline_key; else volume_key = volume->key; diff --git a/include/uapi/linux/cachefiles.h b/include/uapi/linux/cachefiles.h index 78caa73e5343..b6746a2fe57c 100644 --- a/include/uapi/linux/cachefiles.h +++ b/include/uapi/linux/cachefiles.h @@ -37,8 +37,9 @@ struct cachefiles_msg { /* * @data contains the volume_key followed directly by the cookie_key. volume_key * is a NUL-terminated string; @volume_key_size indicates the size of the volume - * key in bytes. cookie_key is binary data, which is netfs specific; - * @cookie_key_size indicates the size of the cookie key in bytes. + * key in bytes (with trailing NUL). cookie_key is a string without trailing + * NUL; @cookie_key_size indicates the size of the cookie key in bytes (without + * trailing NUL). * * @fd identifies an anon_fd referring to the cache file. */