Commit a26dc49d authored by Baokun Li's avatar Baokun Li Committed by Christian Brauner

cachefiles: add consistency check for copen/cread

This prevents malicious processes from completing random copen/cread
requests and crashing the system. Added checks are listed below:

  * Generic, copen can only complete open requests, and cread can only
    complete read requests.
  * For copen, ondemand_id must not be 0, because this indicates that the
    request has not been read by the daemon.
  * For cread, the object corresponding to fd and req should be the same.
Signed-off-by: default avatarBaokun Li <libaokun1@huawei.com>
Link: https://lore.kernel.org/r/20240522114308.2402121-7-libaokun@huaweicloud.comAcked-by: default avatarJeff Layton <jlayton@kernel.org>
Reviewed-by: default avatarJingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent 3e6d704f
...@@ -82,12 +82,12 @@ static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos, ...@@ -82,12 +82,12 @@ static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos,
} }
static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl, static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl,
unsigned long arg) unsigned long id)
{ {
struct cachefiles_object *object = filp->private_data; struct cachefiles_object *object = filp->private_data;
struct cachefiles_cache *cache = object->volume->cache; struct cachefiles_cache *cache = object->volume->cache;
struct cachefiles_req *req; struct cachefiles_req *req;
unsigned long id; XA_STATE(xas, &cache->reqs, id);
if (ioctl != CACHEFILES_IOC_READ_COMPLETE) if (ioctl != CACHEFILES_IOC_READ_COMPLETE)
return -EINVAL; return -EINVAL;
...@@ -95,10 +95,15 @@ static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl, ...@@ -95,10 +95,15 @@ static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl,
if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags)) if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags))
return -EOPNOTSUPP; return -EOPNOTSUPP;
id = arg; xa_lock(&cache->reqs);
req = xa_erase(&cache->reqs, id); req = xas_load(&xas);
if (!req) if (!req || req->msg.opcode != CACHEFILES_OP_READ ||
req->object != object) {
xa_unlock(&cache->reqs);
return -EINVAL; return -EINVAL;
}
xas_store(&xas, NULL);
xa_unlock(&cache->reqs);
trace_cachefiles_ondemand_cread(object, id); trace_cachefiles_ondemand_cread(object, id);
complete(&req->done); complete(&req->done);
...@@ -126,6 +131,7 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args) ...@@ -126,6 +131,7 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args)
unsigned long id; unsigned long id;
long size; long size;
int ret; int ret;
XA_STATE(xas, &cache->reqs, 0);
if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags)) if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -149,9 +155,16 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args) ...@@ -149,9 +155,16 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args)
if (ret) if (ret)
return ret; return ret;
req = xa_erase(&cache->reqs, id); xa_lock(&cache->reqs);
if (!req) xas.xa_index = id;
req = xas_load(&xas);
if (!req || req->msg.opcode != CACHEFILES_OP_OPEN ||
!req->object->ondemand->ondemand_id) {
xa_unlock(&cache->reqs);
return -EINVAL; return -EINVAL;
}
xas_store(&xas, NULL);
xa_unlock(&cache->reqs);
/* fail OPEN request if copen format is invalid */ /* fail OPEN request if copen format is invalid */
ret = kstrtol(psize, 0, &size); ret = kstrtol(psize, 0, &size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment