Changeset View
Standalone View
sys/compat/linuxkpi/common/include/linux/fs.h
Show First 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | |||||
#define LINUX_KQ_FLAG_NEED_READ (1 << 2) | #define LINUX_KQ_FLAG_NEED_READ (1 << 2) | ||||
#define LINUX_KQ_FLAG_NEED_WRITE (1 << 3) | #define LINUX_KQ_FLAG_NEED_WRITE (1 << 3) | ||||
/* protects f_selinfo.si_note */ | /* protects f_selinfo.si_note */ | ||||
spinlock_t f_kqlock; | spinlock_t f_kqlock; | ||||
struct linux_file_wait_queue f_wait_queue; | struct linux_file_wait_queue f_wait_queue; | ||||
/* pointer to associated character device, if any */ | /* pointer to associated character device, if any */ | ||||
struct linux_cdev *f_cdev; | struct linux_cdev *f_cdev; | ||||
struct rcu_head rcu; | |||||
}; | }; | ||||
#define file linux_file | #define file linux_file | ||||
#define fasync_struct sigio * | #define fasync_struct sigio * | ||||
#define fasync_helper(fd, filp, on, queue) \ | #define fasync_helper(fd, filp, on, queue) \ | ||||
({ \ | ({ \ | ||||
if ((on)) \ | if ((on)) \ | ||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | |||||
#define iminor(...) linux_iminor(__VA_ARGS__) | #define iminor(...) linux_iminor(__VA_ARGS__) | ||||
static inline struct linux_file * | static inline struct linux_file * | ||||
get_file(struct linux_file *f) | get_file(struct linux_file *f) | ||||
{ | { | ||||
refcount_acquire(f->_file == NULL ? &f->f_count : &f->_file->f_count); | refcount_acquire(f->_file == NULL ? &f->f_count : &f->_file->f_count); | ||||
return (f); | return (f); | ||||
} | |||||
static inline bool | |||||
hselasky: This change alone is incorrect! Please ensure that all structures being accessed by this… | |||||
Done Inline Actions
As I see, release handler of this file uses ordinary kfree(), not kfree_rcu()
Do you mean that linux_file_close() content should be replaced with single call_rcu() with current it's content moved to call_rcu's callback? wulf: > This change alone is incorrect! Please ensure that all structures being accessed by this… | |||||
Done Inline Actions
wulf: > > This change alone is incorrect! Please ensure that all structures being accessed by this… | |||||
get_file_rcu(struct linux_file *f) | |||||
{ | |||||
return (refcount_acquire_if_not_zero( | |||||
f->_file == NULL ? &f->f_count : &f->_file->f_count)); | |||||
} | } | ||||
static inline struct inode * | static inline struct inode * | ||||
igrab(struct inode *inode) | igrab(struct inode *inode) | ||||
{ | { | ||||
int error; | int error; | ||||
error = vget(inode, 0); | error = vget(inode, 0); | ||||
▲ Show 20 Lines • Show All 42 Lines • Show Last 20 Lines |
This change alone is incorrect! Please ensure that all structures being accessed by this function is freed by kfree_rcu()!
f_count being zero only happens when the Linux file is freed.
But neither "struct linux_file" nor "struct file" is currently freed by RCU.
That means this function will introduce use-after-free! And is not safe to use.