fbmem: don't call copy_from/to_user() with mutex held
Avoid calling copy_from/to_user() with fb_info->lock mutex held in fbmem ioctl(). fb_mmap() is called under mm->mmap_sem (A) held, that also acquires fb_info->lock (B); fb_ioctl() takes fb_info->lock (B) and does copy_from/to_user() that might acquire mm->mmap_sem (A), causing a deadlock. NOTE: it doesn't push down the fb_info->lock in each own driver's fb_ioctl(), so there are still potential deadlocks elsewhere. Signed-off-by: Andrea Righi <righi.andrea@gmail.com> Cc: Dave Jones <davej@redhat.com> Cc: "Rafael J. Wysocki" <rjw@sisk.pl> Cc: Johannes Weiner <hannes@saeurebad.de> Cc: Krzysztof Helt <krzysztof.h1@wp.pl> Cc: Harvey Harrison <harvey.harrison@gmail.com> Cc: Stefan Richter <stefanr@s5r6.in-berlin.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:

committed by
Linus Torvalds

parent
afd8d0f940
commit
1f5e31d7e5
@@ -960,6 +960,21 @@ extern struct fb_info *registered_fb[FB_MAX];
|
||||
extern int num_registered_fb;
|
||||
extern struct class *fb_class;
|
||||
|
||||
static inline int lock_fb_info(struct fb_info *info)
|
||||
{
|
||||
mutex_lock(&info->lock);
|
||||
if (!info->fbops) {
|
||||
mutex_unlock(&info->lock);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void unlock_fb_info(struct fb_info *info)
|
||||
{
|
||||
mutex_unlock(&info->lock);
|
||||
}
|
||||
|
||||
static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
|
||||
u8 *src, u32 s_pitch, u32 height)
|
||||
{
|
||||
|
Reference in New Issue
Block a user