[linux] 01/01: aufs: Make fcntl(F_SETFL, ...) work (Closes: #627782)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Mon May 9 11:41:38 UTC 2016


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch wheezy-security
in repository linux.

commit 593428da7c447e03a517c772655dec1ac197b488
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Sun May 8 18:07:55 2016 +0100

    aufs: Make fcntl(F_SETFL, ...) work (Closes: #627782)
    
    - for aufs: new f_op->setfl() to support fcntl(F_SETFL)
    - aufs: implement new f_op->setfl()
    - fs: Fix ABI change for aufs F_SETFL fix
---
 debian/changelog                                   |  4 ++
 .../fs-fix-abi-change-for-aufs-f_setfl-fix.patch   | 70 ++++++++++++++++++++++
 .../all/aufs3/aufs-implement-new-f_op-setfl.patch  | 60 +++++++++++++++++++
 debian/patches/features/all/aufs3/aufs3-base.patch | 59 ++++++++++++++----
 .../features/all/aufs3/aufs3-standalone.patch      | 12 ++++
 debian/patches/series                              |  2 +
 6 files changed, 194 insertions(+), 13 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 0e7e118..8afe688 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -165,6 +165,10 @@ linux (3.2.80-1) UNRELEASED; urgency=medium
   * Revert "net: validate variable length ll headers", "ax25: add link layer
     header validation function" and "net/ipv6: add sysctl option
     accept_ra_min_hop_limit" to avoid ABI changes
+  * aufs: Make fcntl(F_SETFL, ...) work (Closes: #627782):
+    - for aufs: new f_op->setfl() to support fcntl(F_SETFL)
+    - aufs: implement new f_op->setfl()
+    - fs: Fix ABI change for aufs F_SETFL fix
 
  -- Ben Hutchings <ben at decadent.org.uk>  Fri, 01 Apr 2016 02:11:16 +0100
 
diff --git a/debian/patches/debian/fs-fix-abi-change-for-aufs-f_setfl-fix.patch b/debian/patches/debian/fs-fix-abi-change-for-aufs-f_setfl-fix.patch
new file mode 100644
index 0000000..487ee4a
--- /dev/null
+++ b/debian/patches/debian/fs-fix-abi-change-for-aufs-f_setfl-fix.patch
@@ -0,0 +1,70 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Sun, 08 May 2016 17:54:21 +0100
+Subject: fs: Fix ABI change for aufs F_SETFL fix
+Forwarded: not-needed
+Bug-Debian: https://bugs.debian.org/627782
+
+struct file_operations is not embedded in any larger structures so it
+is safe to extend it.  Move setfl to the end and hide it from
+genksyms.
+
+setfl() still needs to be able to tell whether the
+file_operations::setfl pointer is valid, though.  My first thought was
+to look at the file's superblock, but that won't work because
+e.g. dentries for character devices point to the superblock of the
+filesystem where the device node was found!  Instead, add a keyword to
+the version string of aufs and make do_setfl() check the name and
+version of the module that implements the file_operations.
+
+---
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -175,7 +175,16 @@ int setfl(int fd, struct file * filp, un
+ 
+ 	if (filp->f_op && filp->f_op->check_flags)
+ 		error = filp->f_op->check_flags(arg);
+-	if (!error && filp->f_op->setfl)
++
++	/*
++	 * bwh: setfl() is an extension to file_operations.  For ABI
++	 * compatibility, we can't assume the pointer is even valid.
++	 * Since only aufs will implement it, check that the file ops
++	 * are implemented by a version of aufs that does.  (Ugh.)
++	 */
++	if (!error && filp->f_op->owner &&
++	    !strcmp(filp->f_op->owner->name, "aufs") &&
++	    strstr(filp->f_op->owner->version, "+setfl"))
+ 		error = filp->f_op->setfl(filp, arg);
+ 	if (error)
+ 		return error;
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1621,13 +1621,16 @@ struct file_operations {
+ 	ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
+ 	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+ 	int (*check_flags)(int);
+-	int (*setfl)(struct file *, unsigned long);
+ 	int (*flock) (struct file *, int, struct file_lock *);
+ 	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
+ 	ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
+ 	int (*setlease)(struct file *, long, struct file_lock **);
+ 	long (*fallocate)(struct file *file, int mode, loff_t offset,
+ 			  loff_t len);
++#ifndef __GENKSYMS__
++	/* bwh: For aufs only */
++	int (*setfl)(struct file *, unsigned long);
++#endif
+ };
+ 
+ struct inode_operations {
+--- a/include/linux/aufs_type.h
++++ b/include/linux/aufs_type.h
+@@ -39,7 +39,7 @@
+ 
+ #include <linux/limits.h>
+ 
+-#define AUFS_VERSION	"3.2.x-debian"
++#define AUFS_VERSION	"3.2.x+setfl-debian"
+ 
+ /* todo? move this to linux-2.6.19/include/magic.h */
+ #define AUFS_SUPER_MAGIC	('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
diff --git a/debian/patches/features/all/aufs3/aufs-implement-new-f_op-setfl.patch b/debian/patches/features/all/aufs3/aufs-implement-new-f_op-setfl.patch
new file mode 100644
index 0000000..034ee0f
--- /dev/null
+++ b/debian/patches/features/all/aufs3/aufs-implement-new-f_op-setfl.patch
@@ -0,0 +1,60 @@
+From: "J. R. Okajima" <hooanon05g at gmail.com>
+Date: Sun, 28 Feb 2016 07:08:26 +0900
+Subject: aufs: implement new f_op->setfl()
+Origin: https://github.com/sfjro/aufs3-linux/commit/e3fb13540a9cc40f106a13bfe89460f251b1ca30
+Bug-Debian: https://bugs.debian.org/627782
+
+Propagate the file flags from the virtual aufs's file object to the real
+fs's file object. The exception is FASYNC/O_ASYNC since f_op already has
+->fasync().
+
+Reported-by: Akihiro Suda <suda.kyoto at gmail.com>
+Signed-off-by: J. R. Okajima <hooanon05g at gmail.com>
+[bwh: Backported to aufs-3.2.x-debian: open-code au_read_pre()]
+---
+ fs/aufs/f_op.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/fs/aufs/f_op.c
++++ b/fs/aufs/f_op.c
+@@ -766,6 +766,32 @@ out:
+ 	return err;
+ }
+ 
++static int aufs_setfl(struct file *file, unsigned long arg)
++{
++	int err;
++	struct file *h_file;
++	struct super_block *sb;
++
++	sb = file->f_dentry->d_sb;
++	si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
++	err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
++	if (err)
++		goto out;
++
++	di_read_unlock(file->f_dentry, AuLock_IR);
++	h_file = au_hf_top(file);
++	get_file(h_file);
++	fi_read_unlock(file);
++
++	arg |= vfsub_file_flags(file) & FASYNC; /* stop calling h_file->fasync */
++	err = setfl(/*unused fd*/-1, h_file, arg);
++	fput(h_file); /* instead of au_read_post() */
++
++out:
++	si_read_unlock(sb);
++	return err;
++}
++
+ /* ---------------------------------------------------------------------- */
+ 
+ /* no one supports this operation, currently */
+@@ -803,6 +829,7 @@ const struct file_operations aufs_file_f
+ 	/* .aio_fsync	= aufs_aio_fsync_nondir, */
+ 	.fasync		= aufs_fasync,
+ 	/* .sendpage	= aufs_sendpage, */
++	.setfl		= aufs_setfl,
+ 	.splice_write	= aufs_splice_write,
+ 	.splice_read	= aufs_splice_read,
+ #if 0
diff --git a/debian/patches/features/all/aufs3/aufs3-base.patch b/debian/patches/features/all/aufs3/aufs3-base.patch
index ac30c8d..d78c668 100644
--- a/debian/patches/features/all/aufs3/aufs3-base.patch
+++ b/debian/patches/features/all/aufs3/aufs3-base.patch
@@ -1,10 +1,31 @@
 aufs3.2 base patch
 
-diff --git a/fs/namei.c b/fs/namei.c
-index 5008f01..4cc94cf 100644
+[bwh: Fold in changes from commit 565ce4aa6196 "for aufs: new f_op->setfl() to
+ support fcntl(F_SETFL)"]
+
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -145,7 +145,7 @@ SYSCALL_DEFINE1(dup, unsigned int, filde
+ 
+ #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
+ 
+-static int setfl(int fd, struct file * filp, unsigned long arg)
++int setfl(int fd, struct file * filp, unsigned long arg)
+ {
+ 	struct inode * inode = filp->f_path.dentry->d_inode;
+ 	int error = 0;
+@@ -175,6 +175,8 @@ static int setfl(int fd, struct file * f
+ 
+ 	if (filp->f_op && filp->f_op->check_flags)
+ 		error = filp->f_op->check_flags(arg);
++	if (!error && filp->f_op->setfl)
++		error = filp->f_op->setfl(filp, arg);
+ 	if (error)
+ 		return error;
+ 
 --- a/fs/namei.c
 +++ b/fs/namei.c
-@@ -1753,7 +1753,7 @@ static struct dentry *__lookup_hash(struct qstr *name,
+@@ -1788,7 +1788,7 @@ static struct dentry *__lookup_hash(stru
   * needs parent already locked. Doesn't follow mounts.
   * SMP-safe.
   */
@@ -13,11 +34,9 @@ index 5008f01..4cc94cf 100644
  {
  	return __lookup_hash(&nd->last, nd->path.dentry, nd);
  }
-diff --git a/fs/splice.c b/fs/splice.c
-index fa2defa..e3569b0 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1085,8 +1085,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+@@ -1127,8 +1127,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
  /*
   * Attempt to initiate a splice from pipe to file.
   */
@@ -28,7 +47,7 @@ index fa2defa..e3569b0 100644
  {
  	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
  				loff_t *, size_t, unsigned int);
-@@ -1113,9 +1113,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1155,9 +1155,9 @@ static long do_splice_from(struct pipe_i
  /*
   * Attempt to initiate a splice from a file to a pipe.
   */
@@ -41,11 +60,27 @@ index fa2defa..e3569b0 100644
  {
  	ssize_t (*splice_read)(struct file *, loff_t *,
  			       struct pipe_inode_info *, size_t, unsigned int);
-diff --git a/include/linux/namei.h b/include/linux/namei.h
-index ffc0213..ef35a31 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1394,6 +1394,7 @@ extern void fasync_free(struct fasync_st
+ /* can be called from interrupts */
+ extern void kill_fasync(struct fasync_struct **, int, int);
+ 
++extern int setfl(int fd, struct file * filp, unsigned long arg);
+ extern int __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
+ extern int f_setown(struct file *filp, unsigned long arg, int force);
+ extern void f_delown(struct file *filp);
+@@ -1618,6 +1619,7 @@ struct file_operations {
+ 	ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
+ 	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+ 	int (*check_flags)(int);
++	int (*setfl)(struct file *, unsigned long);
+ 	int (*flock) (struct file *, int, struct file_lock *);
+ 	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
+ 	ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
 --- a/include/linux/namei.h
 +++ b/include/linux/namei.h
-@@ -85,6 +85,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
+@@ -85,6 +85,7 @@ extern int vfs_path_lookup(struct dentry
  extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
  		int (*open)(struct inode *, struct file *));
  
@@ -53,11 +88,9 @@ index ffc0213..ef35a31 100644
  extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
  
  extern int follow_down_one(struct path *);
-diff --git a/include/linux/splice.h b/include/linux/splice.h
-index 26e5b61..3ffef2f 100644
 --- a/include/linux/splice.h
 +++ b/include/linux/splice.h
-@@ -91,4 +91,10 @@ extern void splice_shrink_spd(struct pipe_inode_info *,
+@@ -91,4 +91,10 @@ extern void splice_shrink_spd(struct spl
  extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
  
  extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
diff --git a/debian/patches/features/all/aufs3/aufs3-standalone.patch b/debian/patches/features/all/aufs3/aufs3-standalone.patch
index 460b535..ead1736 100644
--- a/debian/patches/features/all/aufs3/aufs3-standalone.patch
+++ b/debian/patches/features/all/aufs3/aufs3-standalone.patch
@@ -1,5 +1,17 @@
 aufs3.2 standalone patch
 
+[bwh: Add export of setfl() to support "aufs: implement new f_op->setfl()"]
+---
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -80,6 +80,7 @@ int setfl(int fd, struct file * filp, un
+  out:
+ 	return error;
+ }
++EXPORT_SYMBOL_GPL(setfl);
+ 
+ static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
+                      int force)
 diff --git a/fs/file_table.c b/fs/file_table.c
 index c322794..2aad244 100644
 --- a/fs/file_table.c
diff --git a/debian/patches/series b/debian/patches/series
index 301eac8..464b29d 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -13,6 +13,7 @@ features/all/aufs3/aufs3-base.patch
 features/all/aufs3/aufs3-standalone.patch
 features/all/aufs3/aufs3-kbuild.patch
 features/all/aufs3/aufs3-add.patch
+features/all/aufs3/aufs-implement-new-f_op-setfl.patch
 # mark as staging/crap
 features/all/aufs3/mark-as-staging.patch
 # fix added exports from security/device_cgroup.c
@@ -1174,3 +1175,4 @@ debian/pci-fix-abi-change-in-3.2.80.patch
 bugfix/all/revert-ax25-add-link-layer-header-validation-functio.patch
 bugfix/all/revert-net-validate-variable-length-ll-headers.patch
 debian/revert-net-ipv6-add-sysctl-option-accept_ra_min_hop_limit.patch
+debian/fs-fix-abi-change-for-aufs-f_setfl-fix.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list