Skip to content

Commit a26dc49

Browse files
LiBaokun96brauner
authored andcommitted
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: Baokun Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jeff Layton <[email protected]> Reviewed-by: Jingbo Xu <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 3e6d704 commit a26dc49

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

fs/cachefiles/ondemand.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,23 +82,28 @@ static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos,
8282
}
8383

8484
static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl,
85-
unsigned long arg)
85+
unsigned long id)
8686
{
8787
struct cachefiles_object *object = filp->private_data;
8888
struct cachefiles_cache *cache = object->volume->cache;
8989
struct cachefiles_req *req;
90-
unsigned long id;
90+
XA_STATE(xas, &cache->reqs, id);
9191

9292
if (ioctl != CACHEFILES_IOC_READ_COMPLETE)
9393
return -EINVAL;
9494

9595
if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags))
9696
return -EOPNOTSUPP;
9797

98-
id = arg;
99-
req = xa_erase(&cache->reqs, id);
100-
if (!req)
98+
xa_lock(&cache->reqs);
99+
req = xas_load(&xas);
100+
if (!req || req->msg.opcode != CACHEFILES_OP_READ ||
101+
req->object != object) {
102+
xa_unlock(&cache->reqs);
101103
return -EINVAL;
104+
}
105+
xas_store(&xas, NULL);
106+
xa_unlock(&cache->reqs);
102107

103108
trace_cachefiles_ondemand_cread(object, id);
104109
complete(&req->done);
@@ -126,6 +131,7 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args)
126131
unsigned long id;
127132
long size;
128133
int ret;
134+
XA_STATE(xas, &cache->reqs, 0);
129135

130136
if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags))
131137
return -EOPNOTSUPP;
@@ -149,9 +155,16 @@ int cachefiles_ondemand_copen(struct cachefiles_cache *cache, char *args)
149155
if (ret)
150156
return ret;
151157

152-
req = xa_erase(&cache->reqs, id);
153-
if (!req)
158+
xa_lock(&cache->reqs);
159+
xas.xa_index = id;
160+
req = xas_load(&xas);
161+
if (!req || req->msg.opcode != CACHEFILES_OP_OPEN ||
162+
!req->object->ondemand->ondemand_id) {
163+
xa_unlock(&cache->reqs);
154164
return -EINVAL;
165+
}
166+
xas_store(&xas, NULL);
167+
xa_unlock(&cache->reqs);
155168

156169
/* fail OPEN request if copen format is invalid */
157170
ret = kstrtol(psize, 0, &size);

0 commit comments

Comments
 (0)