2021-11-26 22:32:29 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/* General netfs cache on cache files internal defs
|
|
|
|
*
|
|
|
|
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
|
|
|
|
* Written by David Howells (dhowells@redhat.com)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef pr_fmt
|
|
|
|
#undef pr_fmt
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define pr_fmt(fmt) "CacheFiles: " fmt
|
|
|
|
|
|
|
|
|
|
|
|
#include <linux/fscache-cache.h>
|
|
|
|
#include <linux/cred.h>
|
|
|
|
#include <linux/security.h>
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
#include <linux/xarray.h>
|
|
|
|
#include <linux/cachefiles.h>
|
2021-11-26 22:32:29 +08:00
|
|
|
|
2021-10-21 15:50:10 +08:00
|
|
|
#define CACHEFILES_DIO_BLOCK_SIZE 4096
|
|
|
|
|
2021-11-26 22:45:38 +08:00
|
|
|
struct cachefiles_cache;
|
|
|
|
struct cachefiles_object;
|
|
|
|
|
2021-11-18 00:22:21 +08:00
|
|
|
enum cachefiles_content {
|
|
|
|
/* These values are saved on disk */
|
|
|
|
CACHEFILES_CONTENT_NO_DATA = 0, /* No content stored */
|
|
|
|
CACHEFILES_CONTENT_SINGLE = 1, /* Content is monolithic, all is present */
|
|
|
|
CACHEFILES_CONTENT_ALL = 2, /* Content is all present, no map */
|
|
|
|
CACHEFILES_CONTENT_BACKFS_MAP = 3, /* Content is piecemeal, mapped through backing fs */
|
|
|
|
CACHEFILES_CONTENT_DIRTY = 4, /* Content is dirty (only seen on disk) */
|
|
|
|
nr__cachefiles_content
|
|
|
|
};
|
|
|
|
|
2021-10-21 16:55:21 +08:00
|
|
|
/*
|
|
|
|
* Cached volume representation.
|
|
|
|
*/
|
|
|
|
struct cachefiles_volume {
|
|
|
|
struct cachefiles_cache *cache;
|
|
|
|
struct list_head cache_link; /* Link in cache->volumes */
|
|
|
|
struct fscache_volume *vcookie; /* The netfs's representation */
|
|
|
|
struct dentry *dentry; /* The volume dentry */
|
|
|
|
struct dentry *fanout[256]; /* Fanout subdirs */
|
|
|
|
};
|
|
|
|
|
2023-11-20 12:14:18 +08:00
|
|
|
enum cachefiles_object_state {
|
|
|
|
CACHEFILES_ONDEMAND_OBJSTATE_CLOSE, /* Anonymous fd closed by daemon or initial state */
|
|
|
|
CACHEFILES_ONDEMAND_OBJSTATE_OPEN, /* Anonymous fd associated with object is available */
|
2023-11-20 12:14:20 +08:00
|
|
|
CACHEFILES_ONDEMAND_OBJSTATE_REOPENING, /* Object that was closed and is being reopened. */
|
2024-06-28 14:29:26 +08:00
|
|
|
CACHEFILES_ONDEMAND_OBJSTATE_DROPPING, /* Object is being dropped. */
|
2023-11-20 12:14:18 +08:00
|
|
|
};
|
|
|
|
|
2023-11-20 12:14:19 +08:00
|
|
|
struct cachefiles_ondemand_info {
|
2023-11-20 12:14:20 +08:00
|
|
|
struct work_struct ondemand_work;
|
2023-11-20 12:14:19 +08:00
|
|
|
int ondemand_id;
|
|
|
|
enum cachefiles_object_state state;
|
|
|
|
struct cachefiles_object *object;
|
2024-05-22 19:43:03 +08:00
|
|
|
spinlock_t lock;
|
2023-11-20 12:14:19 +08:00
|
|
|
};
|
|
|
|
|
2021-11-26 22:45:38 +08:00
|
|
|
/*
|
2021-11-18 00:22:21 +08:00
|
|
|
* Backing file state.
|
2021-11-26 22:45:38 +08:00
|
|
|
*/
|
|
|
|
struct cachefiles_object {
|
2021-11-18 00:22:21 +08:00
|
|
|
struct fscache_cookie *cookie; /* Netfs data storage object cookie */
|
|
|
|
struct cachefiles_volume *volume; /* Cache volume that holds this object */
|
|
|
|
struct list_head cache_link; /* Link in cache->*_list */
|
|
|
|
struct file *file; /* The file representing this object */
|
|
|
|
char *d_name; /* Backing file name */
|
|
|
|
int debug_id;
|
|
|
|
spinlock_t lock;
|
|
|
|
refcount_t ref;
|
|
|
|
u8 d_name_len; /* Length of filename */
|
|
|
|
enum cachefiles_content content_info:8; /* Info about content presence */
|
|
|
|
unsigned long flags;
|
2021-11-18 00:11:07 +08:00
|
|
|
#define CACHEFILES_OBJECT_USING_TMPFILE 0 /* Have an unlinked tmpfile */
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
#ifdef CONFIG_CACHEFILES_ONDEMAND
|
2023-11-20 12:14:19 +08:00
|
|
|
struct cachefiles_ondemand_info *ondemand;
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
#endif
|
2021-11-26 22:45:38 +08:00
|
|
|
};
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
#define CACHEFILES_ONDEMAND_ID_CLOSED -1
|
|
|
|
|
2021-11-26 22:45:38 +08:00
|
|
|
/*
|
|
|
|
* Cache files cache definition
|
|
|
|
*/
|
|
|
|
struct cachefiles_cache {
|
2021-10-21 16:08:54 +08:00
|
|
|
struct fscache_cache *cache; /* Cache cookie */
|
2021-11-26 22:45:38 +08:00
|
|
|
struct vfsmount *mnt; /* mountpoint holding the cache */
|
2021-11-26 22:29:06 +08:00
|
|
|
struct dentry *store; /* Directory into which live objects go */
|
|
|
|
struct dentry *graveyard; /* directory into which dead objects go */
|
2021-11-26 22:45:38 +08:00
|
|
|
struct file *cachefilesd; /* manager daemon handle */
|
2021-10-21 16:55:21 +08:00
|
|
|
struct list_head volumes; /* List of volume objects */
|
2021-10-21 15:50:10 +08:00
|
|
|
struct list_head object_list; /* List of active objects */
|
2021-10-21 16:55:21 +08:00
|
|
|
spinlock_t object_list_lock; /* Lock for volumes and object_list */
|
2021-11-26 22:45:38 +08:00
|
|
|
const struct cred *cache_cred; /* security override for accessing cache */
|
|
|
|
struct mutex daemon_mutex; /* command serialisation mutex */
|
|
|
|
wait_queue_head_t daemon_pollwq; /* poll waitqueue for daemon */
|
|
|
|
atomic_t gravecounter; /* graveyard uniquifier */
|
|
|
|
atomic_t f_released; /* number of objects released lately */
|
|
|
|
atomic_long_t b_released; /* number of blocks released lately */
|
2021-10-21 15:59:46 +08:00
|
|
|
atomic_long_t b_writing; /* Number of blocks being written */
|
2021-11-26 22:45:38 +08:00
|
|
|
unsigned frun_percent; /* when to stop culling (% files) */
|
|
|
|
unsigned fcull_percent; /* when to start culling (% files) */
|
|
|
|
unsigned fstop_percent; /* when to stop allocating (% files) */
|
|
|
|
unsigned brun_percent; /* when to stop culling (% blocks) */
|
|
|
|
unsigned bcull_percent; /* when to start culling (% blocks) */
|
|
|
|
unsigned bstop_percent; /* when to stop allocating (% blocks) */
|
|
|
|
unsigned bsize; /* cache's block size */
|
2022-01-14 22:13:59 +08:00
|
|
|
unsigned bshift; /* ilog2(bsize) */
|
2021-11-26 22:45:38 +08:00
|
|
|
uint64_t frun; /* when to stop culling */
|
|
|
|
uint64_t fcull; /* when to start culling */
|
|
|
|
uint64_t fstop; /* when to stop allocating */
|
|
|
|
sector_t brun; /* when to stop culling */
|
|
|
|
sector_t bcull; /* when to start culling */
|
|
|
|
sector_t bstop; /* when to stop allocating */
|
|
|
|
unsigned long flags;
|
|
|
|
#define CACHEFILES_READY 0 /* T if cache prepared */
|
|
|
|
#define CACHEFILES_DEAD 1 /* T if cache dead */
|
|
|
|
#define CACHEFILES_CULLING 2 /* T if cull engaged */
|
|
|
|
#define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
#define CACHEFILES_ONDEMAND_MODE 4 /* T if in on-demand read mode */
|
2021-11-26 22:45:38 +08:00
|
|
|
char *rootdirname; /* name of cache root directory */
|
|
|
|
char *secctx; /* LSM security context */
|
|
|
|
char *tag; /* cache binding tag */
|
2022-04-25 20:21:25 +08:00
|
|
|
refcount_t unbind_pincount;/* refcount to do daemon unbind */
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
struct xarray reqs; /* xarray of pending on-demand requests */
|
2022-08-25 10:09:45 +08:00
|
|
|
unsigned long req_id_next;
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
struct xarray ondemand_ids; /* xarray for ondemand_id allocation */
|
|
|
|
u32 ondemand_id_next;
|
cachefiles: cyclic allocation of msg_id to avoid reuse
[ Upstream commit 19f4f399091478c95947f6bd7ad61622300c30d9 ]
Reusing the msg_id after a maliciously completed reopen request may cause
a read request to remain unprocessed and result in a hung, as shown below:
t1 | t2 | t3
-------------------------------------------------
cachefiles_ondemand_select_req
cachefiles_ondemand_object_is_close(A)
cachefiles_ondemand_set_object_reopening(A)
queue_work(fscache_object_wq, &info->work)
ondemand_object_worker
cachefiles_ondemand_init_object(A)
cachefiles_ondemand_send_req(OPEN)
// get msg_id 6
wait_for_completion(&req_A->done)
cachefiles_ondemand_daemon_read
// read msg_id 6 req_A
cachefiles_ondemand_get_fd
copy_to_user
// Malicious completion msg_id 6
copen 6,-1
cachefiles_ondemand_copen
complete(&req_A->done)
// will not set the object to close
// because ondemand_id && fd is valid.
// ondemand_object_worker() is done
// but the object is still reopening.
// new open req_B
cachefiles_ondemand_init_object(B)
cachefiles_ondemand_send_req(OPEN)
// reuse msg_id 6
process_open_req
copen 6,A.size
// The expected failed copen was executed successfully
Expect copen to fail, and when it does, it closes fd, which sets the
object to close, and then close triggers reopen again. However, due to
msg_id reuse resulting in a successful copen, the anonymous fd is not
closed until the daemon exits. Therefore read requests waiting for reopen
to complete may trigger hung task.
To avoid this issue, allocate the msg_id cyclically to avoid reusing the
msg_id for a very short duration of time.
Fixes: c8383054506c ("cachefiles: notify the user daemon when looking up cookie")
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Link: https://lore.kernel.org/r/20240628062930.2467993-9-libaokun@huaweicloud.com
Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: Jia Zhu <zhujia.zj@bytedance.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2024-06-28 14:29:29 +08:00
|
|
|
u32 msg_id_next;
|
2021-11-26 22:45:38 +08:00
|
|
|
};
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
static inline bool cachefiles_in_ondemand_mode(struct cachefiles_cache *cache)
|
|
|
|
{
|
|
|
|
return IS_ENABLED(CONFIG_CACHEFILES_ONDEMAND) &&
|
|
|
|
test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct cachefiles_req {
|
|
|
|
struct cachefiles_object *object;
|
|
|
|
struct completion done;
|
cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()
[ Upstream commit de3e26f9e5b76fc628077578c001c4a51bf54d06 ]
We got the following issue in a fuzz test of randomly issuing the restore
command:
==================================================================
BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0x609/0xab0
Write of size 4 at addr ffff888109164a80 by task ondemand-04-dae/4962
CPU: 11 PID: 4962 Comm: ondemand-04-dae Not tainted 6.8.0-rc7-dirty #542
Call Trace:
kasan_report+0x94/0xc0
cachefiles_ondemand_daemon_read+0x609/0xab0
vfs_read+0x169/0xb50
ksys_read+0xf5/0x1e0
Allocated by task 626:
__kmalloc+0x1df/0x4b0
cachefiles_ondemand_send_req+0x24d/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
Freed by task 626:
kfree+0xf1/0x2c0
cachefiles_ondemand_send_req+0x568/0x690
cachefiles_create_tmpfile+0x249/0xb30
cachefiles_create_file+0x6f/0x140
cachefiles_look_up_object+0x29c/0xa60
cachefiles_lookup_cookie+0x37d/0xca0
fscache_cookie_state_machine+0x43c/0x1230
[...]
==================================================================
Following is the process that triggers the issue:
mount | daemon_thread1 | daemon_thread2
------------------------------------------------------------
cachefiles_ondemand_init_object
cachefiles_ondemand_send_req
REQ_A = kzalloc(sizeof(*req) + data_len)
wait_for_completion(&REQ_A->done)
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
cachefiles_ondemand_get_fd
copy_to_user(_buffer, msg, n)
process_open_req(REQ_A)
------ restore ------
cachefiles_ondemand_restore
xas_for_each(&xas, req, ULONG_MAX)
xas_set_mark(&xas, CACHEFILES_REQ_NEW);
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
write(devfd, ("copen %u,%llu", msg->msg_id, size));
cachefiles_ondemand_copen
xa_erase(&cache->reqs, id)
complete(&REQ_A->done)
kfree(REQ_A)
cachefiles_ondemand_get_fd(REQ_A)
fd = get_unused_fd_flags
file = anon_inode_getfile
fd_install(fd, file)
load = (void *)REQ_A->msg.data;
load->fd = fd;
// load UAF !!!
This issue is caused by issuing a restore command when the daemon is still
alive, which results in a request being processed multiple times thus
triggering a UAF. So to avoid this problem, add an additional reference
count to cachefiles_req, which is held while waiting and reading, and then
released when the waiting and reading is over.
Note that since there is only one reference count for waiting, we need to
avoid the same request being completed multiple times, so we can only
complete the request if it is successfully removed from the xarray.
Fixes: e73fa11a356c ("cachefiles: add restore command to recover inflight ondemand read requests")
Suggested-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Link: https://lore.kernel.org/r/20240522114308.2402121-4-libaokun@huaweicloud.com
Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jia Zhu <zhujia.zj@bytedance.com>
Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 4b4391e77a6b ("cachefiles: defer exposing anon_fd until after copy_to_user() succeeds")
Signed-off-by: Sasha Levin <sashal@kernel.org>
2024-05-22 19:42:59 +08:00
|
|
|
refcount_t ref;
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
int error;
|
|
|
|
struct cachefiles_msg msg;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define CACHEFILES_REQ_NEW XA_MARK_1
|
|
|
|
|
2021-10-21 15:42:18 +08:00
|
|
|
#include <trace/events/cachefiles.h>
|
2021-11-26 22:32:29 +08:00
|
|
|
|
2021-10-21 18:05:53 +08:00
|
|
|
static inline
|
|
|
|
struct file *cachefiles_cres_file(struct netfs_cache_resources *cres)
|
|
|
|
{
|
|
|
|
return cres->cache_priv2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline
|
|
|
|
struct cachefiles_object *cachefiles_cres_object(struct netfs_cache_resources *cres)
|
|
|
|
{
|
|
|
|
return fscache_cres_cookie(cres)->cache_priv;
|
|
|
|
}
|
|
|
|
|
2021-11-26 23:12:07 +08:00
|
|
|
/*
|
|
|
|
* note change of state for daemon
|
|
|
|
*/
|
|
|
|
static inline void cachefiles_state_changed(struct cachefiles_cache *cache)
|
|
|
|
{
|
|
|
|
set_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
|
|
|
|
wake_up_all(&cache->daemon_pollwq);
|
|
|
|
}
|
|
|
|
|
2021-10-21 15:59:46 +08:00
|
|
|
/*
|
|
|
|
* cache.c
|
|
|
|
*/
|
2021-11-26 22:29:06 +08:00
|
|
|
extern int cachefiles_add_cache(struct cachefiles_cache *cache);
|
|
|
|
extern void cachefiles_withdraw_cache(struct cachefiles_cache *cache);
|
2021-10-21 15:59:46 +08:00
|
|
|
|
2021-10-22 04:58:29 +08:00
|
|
|
enum cachefiles_has_space_for {
|
|
|
|
cachefiles_has_space_check,
|
|
|
|
cachefiles_has_space_for_write,
|
|
|
|
cachefiles_has_space_for_create,
|
|
|
|
};
|
|
|
|
extern int cachefiles_has_space(struct cachefiles_cache *cache,
|
|
|
|
unsigned fnr, unsigned bnr,
|
|
|
|
enum cachefiles_has_space_for reason);
|
|
|
|
|
2021-11-26 23:12:07 +08:00
|
|
|
/*
|
|
|
|
* daemon.c
|
|
|
|
*/
|
|
|
|
extern const struct file_operations cachefiles_daemon_fops;
|
2024-05-22 19:43:07 +08:00
|
|
|
extern void cachefiles_flush_reqs(struct cachefiles_cache *cache);
|
2022-04-25 20:21:25 +08:00
|
|
|
extern void cachefiles_get_unbind_pincount(struct cachefiles_cache *cache);
|
|
|
|
extern void cachefiles_put_unbind_pincount(struct cachefiles_cache *cache);
|
2021-11-26 23:12:07 +08:00
|
|
|
|
2021-11-26 22:32:29 +08:00
|
|
|
/*
|
2021-10-21 15:15:26 +08:00
|
|
|
* error_inject.c
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_CACHEFILES_ERROR_INJECTION
|
|
|
|
extern unsigned int cachefiles_error_injection_state;
|
|
|
|
extern int cachefiles_register_error_injection(void);
|
|
|
|
extern void cachefiles_unregister_error_injection(void);
|
|
|
|
|
|
|
|
#else
|
|
|
|
#define cachefiles_error_injection_state 0
|
|
|
|
|
|
|
|
static inline int cachefiles_register_error_injection(void)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void cachefiles_unregister_error_injection(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
static inline int cachefiles_inject_read_error(void)
|
|
|
|
{
|
|
|
|
return cachefiles_error_injection_state & 2 ? -EIO : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int cachefiles_inject_write_error(void)
|
|
|
|
{
|
|
|
|
return cachefiles_error_injection_state & 2 ? -EIO :
|
|
|
|
cachefiles_error_injection_state & 1 ? -ENOSPC :
|
|
|
|
0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int cachefiles_inject_remove_error(void)
|
|
|
|
{
|
|
|
|
return cachefiles_error_injection_state & 2 ? -EIO : 0;
|
|
|
|
}
|
|
|
|
|
2021-11-26 22:29:06 +08:00
|
|
|
/*
|
|
|
|
* interface.c
|
|
|
|
*/
|
|
|
|
extern const struct fscache_cache_ops cachefiles_cache_ops;
|
2021-11-18 00:22:21 +08:00
|
|
|
extern void cachefiles_see_object(struct cachefiles_object *object,
|
|
|
|
enum cachefiles_obj_ref_trace why);
|
|
|
|
extern struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object *object,
|
|
|
|
enum cachefiles_obj_ref_trace why);
|
|
|
|
extern void cachefiles_put_object(struct cachefiles_object *object,
|
|
|
|
enum cachefiles_obj_ref_trace why);
|
|
|
|
|
2021-10-21 18:05:53 +08:00
|
|
|
/*
|
|
|
|
* io.c
|
|
|
|
*/
|
|
|
|
extern bool cachefiles_begin_operation(struct netfs_cache_resources *cres,
|
|
|
|
enum fscache_want_state want_state);
|
2022-04-25 20:21:23 +08:00
|
|
|
extern int __cachefiles_prepare_write(struct cachefiles_object *object,
|
|
|
|
struct file *file,
|
|
|
|
loff_t *_start, size_t *_len,
|
|
|
|
bool no_space_allocated_yet);
|
|
|
|
extern int __cachefiles_write(struct cachefiles_object *object,
|
|
|
|
struct file *file,
|
|
|
|
loff_t start_pos,
|
|
|
|
struct iov_iter *iter,
|
|
|
|
netfs_io_terminated_t term_func,
|
|
|
|
void *term_func_priv);
|
2021-10-21 18:05:53 +08:00
|
|
|
|
2021-11-17 23:48:06 +08:00
|
|
|
/*
|
|
|
|
* key.c
|
|
|
|
*/
|
|
|
|
extern bool cachefiles_cook_key(struct cachefiles_object *object);
|
|
|
|
|
2021-11-18 00:22:21 +08:00
|
|
|
/*
|
|
|
|
* main.c
|
|
|
|
*/
|
|
|
|
extern struct kmem_cache *cachefiles_object_jar;
|
2021-11-26 22:29:06 +08:00
|
|
|
|
2021-10-21 15:34:55 +08:00
|
|
|
/*
|
|
|
|
* namei.c
|
|
|
|
*/
|
2021-11-18 16:58:08 +08:00
|
|
|
extern void cachefiles_unmark_inode_in_use(struct cachefiles_object *object,
|
|
|
|
struct file *file);
|
2021-10-21 15:50:10 +08:00
|
|
|
extern int cachefiles_bury_object(struct cachefiles_cache *cache,
|
|
|
|
struct cachefiles_object *object,
|
|
|
|
struct dentry *dir,
|
|
|
|
struct dentry *rep,
|
|
|
|
enum fscache_why_object_killed why);
|
2021-10-21 15:50:10 +08:00
|
|
|
extern int cachefiles_delete_object(struct cachefiles_object *object,
|
|
|
|
enum fscache_why_object_killed why);
|
|
|
|
extern bool cachefiles_look_up_object(struct cachefiles_object *object);
|
2021-10-21 15:34:55 +08:00
|
|
|
extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
|
|
|
|
struct dentry *dir,
|
|
|
|
const char *name,
|
|
|
|
bool *_is_new);
|
|
|
|
extern void cachefiles_put_directory(struct dentry *dir);
|
|
|
|
|
2021-10-21 15:50:10 +08:00
|
|
|
extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
|
|
|
|
char *filename);
|
|
|
|
|
|
|
|
extern int cachefiles_check_in_use(struct cachefiles_cache *cache,
|
|
|
|
struct dentry *dir, char *filename);
|
2021-10-21 15:50:10 +08:00
|
|
|
extern struct file *cachefiles_create_tmpfile(struct cachefiles_object *object);
|
|
|
|
extern bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache,
|
|
|
|
struct cachefiles_object *object);
|
2021-10-21 15:50:10 +08:00
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
/*
|
|
|
|
* ondemand.c
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_CACHEFILES_ONDEMAND
|
|
|
|
extern ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
|
|
|
|
char __user *_buffer, size_t buflen);
|
|
|
|
|
|
|
|
extern int cachefiles_ondemand_copen(struct cachefiles_cache *cache,
|
|
|
|
char *args);
|
2023-11-20 12:14:22 +08:00
|
|
|
|
|
|
|
extern int cachefiles_ondemand_restore(struct cachefiles_cache *cache,
|
|
|
|
char *args);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
|
|
|
|
extern int cachefiles_ondemand_init_object(struct cachefiles_object *object);
|
2022-04-25 20:21:26 +08:00
|
|
|
extern void cachefiles_ondemand_clean_object(struct cachefiles_object *object);
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
|
2022-04-25 20:21:27 +08:00
|
|
|
extern int cachefiles_ondemand_read(struct cachefiles_object *object,
|
|
|
|
loff_t pos, size_t len);
|
|
|
|
|
2023-11-20 12:14:19 +08:00
|
|
|
extern int cachefiles_ondemand_init_obj_info(struct cachefiles_object *obj,
|
|
|
|
struct cachefiles_volume *volume);
|
|
|
|
extern void cachefiles_ondemand_deinit_obj_info(struct cachefiles_object *obj);
|
|
|
|
|
2023-11-20 12:14:18 +08:00
|
|
|
#define CACHEFILES_OBJECT_STATE_FUNCS(_state, _STATE) \
|
|
|
|
static inline bool \
|
|
|
|
cachefiles_ondemand_object_is_##_state(const struct cachefiles_object *object) \
|
|
|
|
{ \
|
2023-11-20 12:14:19 +08:00
|
|
|
return object->ondemand->state == CACHEFILES_ONDEMAND_OBJSTATE_##_STATE; \
|
2023-11-20 12:14:18 +08:00
|
|
|
} \
|
|
|
|
\
|
|
|
|
static inline void \
|
|
|
|
cachefiles_ondemand_set_object_##_state(struct cachefiles_object *object) \
|
|
|
|
{ \
|
2023-11-20 12:14:19 +08:00
|
|
|
object->ondemand->state = CACHEFILES_ONDEMAND_OBJSTATE_##_STATE; \
|
2023-11-20 12:14:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
CACHEFILES_OBJECT_STATE_FUNCS(open, OPEN);
|
|
|
|
CACHEFILES_OBJECT_STATE_FUNCS(close, CLOSE);
|
2023-11-20 12:14:20 +08:00
|
|
|
CACHEFILES_OBJECT_STATE_FUNCS(reopening, REOPENING);
|
2024-06-28 14:29:26 +08:00
|
|
|
CACHEFILES_OBJECT_STATE_FUNCS(dropping, DROPPING);
|
2023-11-20 12:14:21 +08:00
|
|
|
|
|
|
|
static inline bool cachefiles_ondemand_is_reopening_read(struct cachefiles_req *req)
|
|
|
|
{
|
|
|
|
return cachefiles_ondemand_object_is_reopening(req->object) &&
|
|
|
|
req->msg.opcode == CACHEFILES_OP_READ;
|
|
|
|
}
|
|
|
|
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
#else
|
|
|
|
static inline ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache,
|
|
|
|
char __user *_buffer, size_t buflen)
|
|
|
|
{
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int cachefiles_ondemand_init_object(struct cachefiles_object *object)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2022-04-25 20:21:26 +08:00
|
|
|
|
|
|
|
static inline void cachefiles_ondemand_clean_object(struct cachefiles_object *object)
|
|
|
|
{
|
|
|
|
}
|
2022-04-25 20:21:27 +08:00
|
|
|
|
|
|
|
static inline int cachefiles_ondemand_read(struct cachefiles_object *object,
|
|
|
|
loff_t pos, size_t len)
|
|
|
|
{
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
2023-11-20 12:14:19 +08:00
|
|
|
|
|
|
|
static inline int cachefiles_ondemand_init_obj_info(struct cachefiles_object *obj,
|
|
|
|
struct cachefiles_volume *volume)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static inline void cachefiles_ondemand_deinit_obj_info(struct cachefiles_object *obj)
|
|
|
|
{
|
|
|
|
}
|
2023-11-20 12:14:21 +08:00
|
|
|
|
|
|
|
static inline bool cachefiles_ondemand_is_reopening_read(struct cachefiles_req *req)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
cachefiles: notify the user daemon when looking up cookie
Fscache/CacheFiles used to serve as a local cache for a remote
networking fs. A new on-demand read mode will be introduced for
CacheFiles, which can boost the scenario where on-demand read semantics
are needed, e.g. container image distribution.
The essential difference between these two modes is seen when a cache
miss occurs: In the original mode, the netfs will fetch the data from
the remote server and then write it to the cache file; in on-demand
read mode, fetching the data and writing it into the cache is delegated
to a user daemon.
As the first step, notify the user daemon when looking up cookie. In
this case, an anonymous fd is sent to the user daemon, through which the
user daemon can write the fetched data to the cache file. Since the user
daemon may move the anonymous fd around, e.g. through dup(), an object
ID uniquely identifying the cache file is also attached.
Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that
the cache file size shall be retrieved at runtime. This helps the
scenario where one cache file contains multiple netfs files, e.g. for
the purpose of deduplication. In this case, netfs itself has no idea the
size of the cache file, whilst the user daemon should give the hint on
it.
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20220509074028.74954-3-jefflexu@linux.alibaba.com
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
2022-04-25 20:21:24 +08:00
|
|
|
#endif
|
|
|
|
|
2021-11-26 22:59:10 +08:00
|
|
|
/*
|
|
|
|
* security.c
|
|
|
|
*/
|
|
|
|
extern int cachefiles_get_security_ID(struct cachefiles_cache *cache);
|
|
|
|
extern int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
|
|
|
|
struct dentry *root,
|
|
|
|
const struct cred **_saved_cred);
|
|
|
|
|
|
|
|
static inline void cachefiles_begin_secure(struct cachefiles_cache *cache,
|
|
|
|
const struct cred **_saved_cred)
|
|
|
|
{
|
|
|
|
*_saved_cred = override_creds(cache->cache_cred);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
|
|
|
|
const struct cred *saved_cred)
|
|
|
|
{
|
|
|
|
revert_creds(saved_cred);
|
|
|
|
}
|
|
|
|
|
2021-10-21 16:55:21 +08:00
|
|
|
/*
|
|
|
|
* volume.c
|
|
|
|
*/
|
|
|
|
void cachefiles_acquire_volume(struct fscache_volume *volume);
|
|
|
|
void cachefiles_free_volume(struct fscache_volume *volume);
|
|
|
|
void cachefiles_withdraw_volume(struct cachefiles_volume *volume);
|
|
|
|
|
2021-11-18 00:11:07 +08:00
|
|
|
/*
|
|
|
|
* xattr.c
|
|
|
|
*/
|
|
|
|
extern int cachefiles_set_object_xattr(struct cachefiles_object *object);
|
|
|
|
extern int cachefiles_check_auxdata(struct cachefiles_object *object,
|
|
|
|
struct file *file);
|
|
|
|
extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
|
|
|
|
struct cachefiles_object *object,
|
|
|
|
struct dentry *dentry);
|
|
|
|
extern void cachefiles_prepare_to_write(struct fscache_cookie *cookie);
|
2021-12-14 17:51:43 +08:00
|
|
|
extern bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume);
|
|
|
|
extern int cachefiles_check_volume_xattr(struct cachefiles_volume *volume);
|
2021-11-18 00:11:07 +08:00
|
|
|
|
2021-10-21 16:08:54 +08:00
|
|
|
/*
|
|
|
|
* Error handling
|
|
|
|
*/
|
|
|
|
#define cachefiles_io_error(___cache, FMT, ...) \
|
|
|
|
do { \
|
|
|
|
pr_err("I/O Error: " FMT"\n", ##__VA_ARGS__); \
|
|
|
|
fscache_io_error((___cache)->cache); \
|
|
|
|
set_bit(CACHEFILES_DEAD, &(___cache)->flags); \
|
2024-05-22 19:43:07 +08:00
|
|
|
if (cachefiles_in_ondemand_mode(___cache)) \
|
|
|
|
cachefiles_flush_reqs(___cache); \
|
2021-10-21 16:08:54 +08:00
|
|
|
} while (0)
|
|
|
|
|
2021-11-18 00:11:07 +08:00
|
|
|
#define cachefiles_io_error_obj(object, FMT, ...) \
|
|
|
|
do { \
|
|
|
|
struct cachefiles_cache *___cache; \
|
|
|
|
\
|
|
|
|
___cache = (object)->volume->cache; \
|
|
|
|
cachefiles_io_error(___cache, FMT " [o=%08x]", ##__VA_ARGS__, \
|
|
|
|
(object)->debug_id); \
|
|
|
|
} while (0)
|
|
|
|
|
2021-10-21 15:15:26 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Debug tracing
|
2021-11-26 22:32:29 +08:00
|
|
|
*/
|
|
|
|
extern unsigned cachefiles_debug;
|
|
|
|
#define CACHEFILES_DEBUG_KENTER 1
|
|
|
|
#define CACHEFILES_DEBUG_KLEAVE 2
|
|
|
|
#define CACHEFILES_DEBUG_KDEBUG 4
|
|
|
|
|
|
|
|
#define dbgprintk(FMT, ...) \
|
|
|
|
printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
|
|
|
|
|
|
|
|
#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
|
|
|
|
#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
|
|
|
|
#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(__KDEBUG)
|
|
|
|
#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
|
|
|
|
#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
|
|
|
|
#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
|
|
|
|
|
|
|
|
#elif defined(CONFIG_CACHEFILES_DEBUG)
|
|
|
|
#define _enter(FMT, ...) \
|
|
|
|
do { \
|
|
|
|
if (cachefiles_debug & CACHEFILES_DEBUG_KENTER) \
|
|
|
|
kenter(FMT, ##__VA_ARGS__); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define _leave(FMT, ...) \
|
|
|
|
do { \
|
|
|
|
if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE) \
|
|
|
|
kleave(FMT, ##__VA_ARGS__); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define _debug(FMT, ...) \
|
|
|
|
do { \
|
|
|
|
if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG) \
|
|
|
|
kdebug(FMT, ##__VA_ARGS__); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#else
|
|
|
|
#define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__)
|
|
|
|
#define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
|
|
|
|
#define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if 1 /* defined(__KDEBUGALL) */
|
|
|
|
|
|
|
|
#define ASSERT(X) \
|
|
|
|
do { \
|
|
|
|
if (unlikely(!(X))) { \
|
|
|
|
pr_err("\n"); \
|
|
|
|
pr_err("Assertion failed\n"); \
|
|
|
|
BUG(); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define ASSERTCMP(X, OP, Y) \
|
|
|
|
do { \
|
|
|
|
if (unlikely(!((X) OP (Y)))) { \
|
|
|
|
pr_err("\n"); \
|
|
|
|
pr_err("Assertion failed\n"); \
|
|
|
|
pr_err("%lx " #OP " %lx is false\n", \
|
|
|
|
(unsigned long)(X), (unsigned long)(Y)); \
|
|
|
|
BUG(); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define ASSERTIF(C, X) \
|
|
|
|
do { \
|
|
|
|
if (unlikely((C) && !(X))) { \
|
|
|
|
pr_err("\n"); \
|
|
|
|
pr_err("Assertion failed\n"); \
|
|
|
|
BUG(); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define ASSERTIFCMP(C, X, OP, Y) \
|
|
|
|
do { \
|
|
|
|
if (unlikely((C) && !((X) OP (Y)))) { \
|
|
|
|
pr_err("\n"); \
|
|
|
|
pr_err("Assertion failed\n"); \
|
|
|
|
pr_err("%lx " #OP " %lx is false\n", \
|
|
|
|
(unsigned long)(X), (unsigned long)(Y)); \
|
|
|
|
BUG(); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#define ASSERT(X) do {} while (0)
|
|
|
|
#define ASSERTCMP(X, OP, Y) do {} while (0)
|
|
|
|
#define ASSERTIF(C, X) do {} while (0)
|
|
|
|
#define ASSERTIFCMP(C, X, OP, Y) do {} while (0)
|
|
|
|
|
|
|
|
#endif
|