Message ID | 20240424033916.2748488-11-libaokun@huaweicloud.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | cachefiles: some bugfixes and cleanups for ondemand requests | expand |
在 2024/4/24 11:39, libaokun@huaweicloud.com 写道: > From: Zizhi Wo <wozizhi@huawei.com> > > If copen is maliciously called in the user mode, it may delete the request > corresponding to the random id. And the request may have not been read yet. > > Note that when the object is set to reopen, the open request will be done > with the still reopen state in above case. As a result, the request > corresponding to this object is always skipped in select_req function, so > the read request is never completed and blocks other process. > > Fix this issue by simply set object to close if its id < 0 in copen. > > Signed-off-by: Zizhi Wo <wozizhi@huawei.com> > Signed-off-by: Baokun Li <libaokun1@huawei.com> Reviewed-by: Jia Zhu <zhujia.zj@bytedance.com> > --- > fs/cachefiles/ondemand.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c > index 7c2d43104120..673e7ad52041 100644 > --- a/fs/cachefiles/ondemand.c > +++ b/fs/cachefiles/ondemand.c > @@ -182,6 +182,7 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args) > xas_store(&xas, NULL); > xa_unlock(&cache->reqs); > > + info = req->object->ondemand; > /* fail OPEN request if copen format is invalid */ > ret = kstrtol(psize, 0, &size); > if (ret) { > @@ -201,7 +202,6 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args) > goto out; > } > > - info = req->object->ondemand; > spin_lock(&info->lock); > /* The anonymous fd was closed before copen ? */ > if (info->ondemand_id == CACHEFILES_ONDEMAND_ID_CLOSED) { > @@ -222,6 +222,11 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args) > wake_up_all(&cache->daemon_pollwq); > > out: > + spin_lock(&info->lock); > + /* Need to set object close to avoid reopen status continuing */ > + if (info->ondemand_id == CACHEFILES_ONDEMAND_ID_CLOSED) > + cachefiles_ondemand_set_object_close(req->object); > + spin_unlock(&info->lock); > complete(&req->done); > return ret; > }
diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c index 7c2d43104120..673e7ad52041 100644 --- a/fs/cachefiles/ondemand.c +++ b/fs/cachefiles/ondemand.c @@ -182,6 +182,7 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args) xas_store(&xas, NULL); xa_unlock(&cache->reqs); + info = req->object->ondemand; /* fail OPEN request if copen format is invalid */ ret = kstrtol(psize, 0, &size); if (ret) { @@ -201,7 +202,6 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args) goto out; } - info = req->object->ondemand; spin_lock(&info->lock); /* The anonymous fd was closed before copen ? */ if (info->ondemand_id == CACHEFILES_ONDEMAND_ID_CLOSED) { @@ -222,6 +222,11 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args) wake_up_all(&cache->daemon_pollwq); out: + spin_lock(&info->lock); + /* Need to set object close to avoid reopen status continuing */ + if (info->ondemand_id == CACHEFILES_ONDEMAND_ID_CLOSED) + cachefiles_ondemand_set_object_close(req->object); + spin_unlock(&info->lock); complete(&req->done); return ret; }