From: Greg Kroah-Hartman Date: Thu, 13 Jun 2019 07:54:46 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v5.1.10~9 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fkernel%2Fstable-queue.git;a=commitdiff_plain;h=58def91c2268d62d2012d65b3db3017e133aa3ad 4.19-stable patches added patches: drm-vc4-fix-fb-references-in-async-update.patch ovl-check-the-capability-before-cred-overridden.patch ovl-support-stacked-seek_hole-seek_data.patch --- diff --git a/queue-4.19/drm-vc4-fix-fb-references-in-async-update.patch b/queue-4.19/drm-vc4-fix-fb-references-in-async-update.patch new file mode 100644 index 0000000000..1bad39c2b8 --- /dev/null +++ b/queue-4.19/drm-vc4-fix-fb-references-in-async-update.patch @@ -0,0 +1,39 @@ +From c16b85559dcfb5a348cc085a7b4c75ed49b05e2c Mon Sep 17 00:00:00 2001 +From: Helen Koike +Date: Mon, 3 Jun 2019 13:56:09 -0300 +Subject: drm/vc4: fix fb references in async update + +From: Helen Koike + +commit c16b85559dcfb5a348cc085a7b4c75ed49b05e2c upstream. + +Async update callbacks are expected to set the old_fb in the new_state +so prepare/cleanup framebuffers are balanced. + +Calling drm_atomic_set_fb_for_plane() (which gets a reference of the new +fb and put the old fb) is not required, as it's taken care by +drm_mode_cursor_universal() when calling drm_atomic_helper_update_plane(). + +Cc: # v4.19+ +Fixes: 539c320bfa97 ("drm/vc4: update cursors asynchronously through atomic") +Suggested-by: Boris Brezillon +Signed-off-by: Helen Koike +Reviewed-by: Boris Brezillon +Signed-off-by: Boris Brezillon +Link: https://patchwork.freedesktop.org/patch/msgid/20190603165610.24614-5-helen.koike@collabora.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/vc4/vc4_plane.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/vc4/vc4_plane.c ++++ b/drivers/gpu/drm/vc4/vc4_plane.c +@@ -818,6 +818,7 @@ static void vc4_plane_atomic_async_updat + drm_atomic_set_fb_for_plane(plane->state, state->fb); + } + ++ swap(plane->state->fb, state->fb); + /* Set the cursor's position on the screen. This is the + * expected change from the drm_mode_cursor_universal() + * helper. diff --git a/queue-4.19/ovl-check-the-capability-before-cred-overridden.patch b/queue-4.19/ovl-check-the-capability-before-cred-overridden.patch new file mode 100644 index 0000000000..61ba1288ca --- /dev/null +++ b/queue-4.19/ovl-check-the-capability-before-cred-overridden.patch @@ -0,0 +1,141 @@ +From 98487de318a6f33312471ae1e2afa16fbf8361fe Mon Sep 17 00:00:00 2001 +From: Jiufei Xue +Date: Mon, 6 May 2019 15:41:02 +0800 +Subject: ovl: check the capability before cred overridden + +From: Jiufei Xue + +commit 98487de318a6f33312471ae1e2afa16fbf8361fe upstream. + +We found that it return success when we set IMMUTABLE_FL flag to a file in +docker even though the docker didn't have the capability +CAP_LINUX_IMMUTABLE. + +The commit d1d04ef8572b ("ovl: stack file ops") and dab5ca8fd9dd ("ovl: add +lsattr/chattr support") implemented chattr operations on a regular overlay +file. ovl_real_ioctl() overridden the current process's subjective +credentials with ofs->creator_cred which have the capability +CAP_LINUX_IMMUTABLE so that it will return success in +vfs_ioctl()->cap_capable(). + +Fix this by checking the capability before cred overridden. And here we +only care about APPEND_FL and IMMUTABLE_FL, so get these information from +inode. + +[SzM: move check and call to underlying fs inside inode locked region to +prevent two such calls from racing with each other] + +Signed-off-by: Jiufei Xue +Signed-off-by: Miklos Szeredi +Cc: Amir Goldstein +Signed-off-by: Greg Kroah-Hartman + +--- + fs/overlayfs/file.c | 79 ++++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 61 insertions(+), 18 deletions(-) + +--- a/fs/overlayfs/file.c ++++ b/fs/overlayfs/file.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include "overlayfs.h" + + static char ovl_whatisit(struct inode *inode, struct inode *realinode) +@@ -372,10 +373,68 @@ static long ovl_real_ioctl(struct file * + return ret; + } + +-static long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++static unsigned int ovl_get_inode_flags(struct inode *inode) ++{ ++ unsigned int flags = READ_ONCE(inode->i_flags); ++ unsigned int ovl_iflags = 0; ++ ++ if (flags & S_SYNC) ++ ovl_iflags |= FS_SYNC_FL; ++ if (flags & S_APPEND) ++ ovl_iflags |= FS_APPEND_FL; ++ if (flags & S_IMMUTABLE) ++ ovl_iflags |= FS_IMMUTABLE_FL; ++ if (flags & S_NOATIME) ++ ovl_iflags |= FS_NOATIME_FL; ++ ++ return ovl_iflags; ++} ++ ++static long ovl_ioctl_set_flags(struct file *file, unsigned long arg) + { + long ret; + struct inode *inode = file_inode(file); ++ unsigned int flags; ++ unsigned int old_flags; ++ ++ if (!inode_owner_or_capable(inode)) ++ return -EACCES; ++ ++ if (get_user(flags, (int __user *) arg)) ++ return -EFAULT; ++ ++ ret = mnt_want_write_file(file); ++ if (ret) ++ return ret; ++ ++ inode_lock(inode); ++ ++ /* Check the capability before cred override */ ++ ret = -EPERM; ++ old_flags = ovl_get_inode_flags(inode); ++ if (((flags ^ old_flags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) && ++ !capable(CAP_LINUX_IMMUTABLE)) ++ goto unlock; ++ ++ ret = ovl_maybe_copy_up(file_dentry(file), O_WRONLY); ++ if (ret) ++ goto unlock; ++ ++ ret = ovl_real_ioctl(file, FS_IOC_SETFLAGS, arg); ++ ++ ovl_copyflags(ovl_inode_real(inode), inode); ++unlock: ++ inode_unlock(inode); ++ ++ mnt_drop_write_file(file); ++ ++ return ret; ++ ++} ++ ++static long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long ret; + + switch (cmd) { + case FS_IOC_GETFLAGS: +@@ -383,23 +442,7 @@ static long ovl_ioctl(struct file *file, + break; + + case FS_IOC_SETFLAGS: +- if (!inode_owner_or_capable(inode)) +- return -EACCES; +- +- ret = mnt_want_write_file(file); +- if (ret) +- return ret; +- +- ret = ovl_maybe_copy_up(file_dentry(file), O_WRONLY); +- if (!ret) { +- ret = ovl_real_ioctl(file, cmd, arg); +- +- inode_lock(inode); +- ovl_copyflags(ovl_inode_real(inode), inode); +- inode_unlock(inode); +- } +- +- mnt_drop_write_file(file); ++ ret = ovl_ioctl_set_flags(file, arg); + break; + + default: diff --git a/queue-4.19/ovl-support-stacked-seek_hole-seek_data.patch b/queue-4.19/ovl-support-stacked-seek_hole-seek_data.patch new file mode 100644 index 0000000000..ed7f2346c6 --- /dev/null +++ b/queue-4.19/ovl-support-stacked-seek_hole-seek_data.patch @@ -0,0 +1,82 @@ +From 9e46b840c7053b5f7a245e98cd239b60d189a96c Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Wed, 27 Feb 2019 13:32:11 +0200 +Subject: ovl: support stacked SEEK_HOLE/SEEK_DATA + +From: Amir Goldstein + +commit 9e46b840c7053b5f7a245e98cd239b60d189a96c upstream. + +Overlay file f_pos is the master copy that is preserved +through copy up and modified on read/write, but only real +fs knows how to SEEK_HOLE/SEEK_DATA and real fs may impose +limitations that are more strict than ->s_maxbytes for specific +files, so we use the real file to perform seeks. + +We do not call real fs for SEEK_CUR:0 query and for SEEK_SET:0 +requests. + +Fixes: d1d04ef8572b ("ovl: stack file ops") +Reported-by: Eddie Horng +Signed-off-by: Amir Goldstein +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/overlayfs/file.c | 44 ++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 40 insertions(+), 4 deletions(-) + +--- a/fs/overlayfs/file.c ++++ b/fs/overlayfs/file.c +@@ -146,11 +146,47 @@ static int ovl_release(struct inode *ino + + static loff_t ovl_llseek(struct file *file, loff_t offset, int whence) + { +- struct inode *realinode = ovl_inode_real(file_inode(file)); ++ struct inode *inode = file_inode(file); ++ struct fd real; ++ const struct cred *old_cred; ++ ssize_t ret; + +- return generic_file_llseek_size(file, offset, whence, +- realinode->i_sb->s_maxbytes, +- i_size_read(realinode)); ++ /* ++ * The two special cases below do not need to involve real fs, ++ * so we can optimizing concurrent callers. ++ */ ++ if (offset == 0) { ++ if (whence == SEEK_CUR) ++ return file->f_pos; ++ ++ if (whence == SEEK_SET) ++ return vfs_setpos(file, 0, 0); ++ } ++ ++ ret = ovl_real_fdget(file, &real); ++ if (ret) ++ return ret; ++ ++ /* ++ * Overlay file f_pos is the master copy that is preserved ++ * through copy up and modified on read/write, but only real ++ * fs knows how to SEEK_HOLE/SEEK_DATA and real fs may impose ++ * limitations that are more strict than ->s_maxbytes for specific ++ * files, so we use the real file to perform seeks. ++ */ ++ inode_lock(inode); ++ real.file->f_pos = file->f_pos; ++ ++ old_cred = ovl_override_creds(inode->i_sb); ++ ret = vfs_llseek(real.file, offset, whence); ++ revert_creds(old_cred); ++ ++ file->f_pos = real.file->f_pos; ++ inode_unlock(inode); ++ ++ fdput(real); ++ ++ return ret; + } + + static void ovl_file_accessed(struct file *file) diff --git a/queue-4.19/series b/queue-4.19/series index 63e24b4f96..141dec8b13 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -113,3 +113,6 @@ gpio-vf610-do-not-share-irq_chip.patch percpu-do-not-search-past-bitmap-when-allocating-an-.patch revert-bluetooth-align-minimum-encryption-key-size-for-le-and-br-edr-connections.patch revert-drm-nouveau-add-kconfig-option-to-turn-off-nouveau-legacy-contexts.-v3.patch +ovl-check-the-capability-before-cred-overridden.patch +ovl-support-stacked-seek_hole-seek_data.patch +drm-vc4-fix-fb-references-in-async-update.patch