aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/fs/smb/server/vfs_cache.h
diff options
context:
space:
mode:
authorNamjae Jeon <linkinjeon@kernel.org>2023-10-04 18:28:39 +0900
committerSteve French <stfrench@microsoft.com>2023-10-04 20:21:48 -0500
commit5a7ee91d1154f35418367a6eaae74046fd06ed89 (patch)
tree4fe9ab46726de64bd927b559f0b6624a1e1278ec /fs/smb/server/vfs_cache.h
parentksmbd: fix race condition between session lookup and expire (diff)
downloadwireguard-linux-5a7ee91d1154f35418367a6eaae74046fd06ed89.tar.xz
wireguard-linux-5a7ee91d1154f35418367a6eaae74046fd06ed89.zip
ksmbd: fix race condition with fp
fp can used in each command. If smb2_close command is coming at the same time, UAF issue can happen by race condition. Time + Thread A | Thread B1 B2 .... B5 smb2_open | smb2_close | __open_id | insert fp to file_table | | | atomic_dec_and_test(&fp->refcount) | if fp->refcount == 0, free fp by kfree. // UAF! | use fp | + This patch add f_state not to use freed fp is used and not to free fp in use. Reported-by: luosili <rootlab@huawei.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to '')
-rw-r--r--fs/smb/server/vfs_cache.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h
index fcb13413fa8d..03d0bf941216 100644
--- a/fs/smb/server/vfs_cache.h
+++ b/fs/smb/server/vfs_cache.h
@@ -60,6 +60,12 @@ struct ksmbd_inode {
__le32 m_fattr;
};
+enum {
+ FP_NEW = 0,
+ FP_INITED,
+ FP_CLOSED
+};
+
struct ksmbd_file {
struct file *filp;
u64 persistent_id;
@@ -98,6 +104,7 @@ struct ksmbd_file {
/* if ls is happening on directory, below is valid*/
struct ksmbd_readdir_data readdir_data;
int dot_dotdot[2];
+ unsigned int f_state;
};
static inline void set_ctx_actor(struct dir_context *ctx,
@@ -142,6 +149,8 @@ int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode);
int ksmbd_init_global_file_table(void);
void ksmbd_free_global_file_table(void);
void ksmbd_set_fd_limit(unsigned long limit);
+void ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp,
+ unsigned int state);
/*
* INODE hash