[linux] 02/03: Fix/ignore ABI changes

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Wed Nov 30 03:16:22 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 67fb8ddd2e185fff950beb31b361f0337799f817
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Wed Nov 30 01:12:15 2016 +0000

    Fix/ignore ABI changes
---
 debian/changelog                                   |   3 +
 debian/config/defines                              |   1 +
 .../debian/fs-fix-abi-change-in-3.2.84.patch       | 126 ++++++++++++++++++
 .../debian/i8042-revert-abi-break-in-3.2.84.patch  | 147 +++++++++++++++++++++
 debian/patches/series                              |   2 +
 5 files changed, 279 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 10981b7..d4a1b24 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -94,6 +94,9 @@ linux (3.2.84-1) UNRELEASED; urgency=medium
 
   [ Ben Hutchings ]
   * drm, agp: Update to 3.4.113 (no functional change)
+  * i8042: Revert ABI break in 3.2.84
+  * fs: Fix ABI change in 3.2.84
+  * can: Ignore ABI change in 3.2.84
 
  -- Ben Hutchings <ben at decadent.org.uk>  Mon, 28 Nov 2016 18:43:52 +0000
 
diff --git a/debian/config/defines b/debian/config/defines
index 0b430f4..75396dc 100644
--- a/debian/config/defines
+++ b/debian/config/defines
@@ -96,6 +96,7 @@ ignore-changes:
  scm_detach_fds
  scm_fp_dup
  af_alg_*
+ module:drivers/net/can/can-dev
 
 [base]
 arches:
diff --git a/debian/patches/debian/fs-fix-abi-change-in-3.2.84.patch b/debian/patches/debian/fs-fix-abi-change-in-3.2.84.patch
new file mode 100644
index 0000000..04cf860
--- /dev/null
+++ b/debian/patches/debian/fs-fix-abi-change-in-3.2.84.patch
@@ -0,0 +1,126 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Tue, 29 Nov 2016 02:10:21 +0000
+Subject: fs: Fix ABI change in 3.2.84
+Forwarded: not-needed
+
+In order to fix CVE-2015-1350, inode_change_ok() had to be changed
+to take a dentry pointer as passed down from inode_setattr(), and
+it was renamed to setattr_prepare().
+
+Add inode_change_ok() back, along with a hack to pass the dentry
+down via struct attr when there isn't a file pointer there.  In 3.2
+there don't appear to be any cases where both the file pointer is
+provided and the dentry pointer is needed.  (In upstream there is -
+truncate operations set both ATTR_FILE and ATTR_KILL_PRIV.)  WARN
+and return an error if that does happen.  
+
+---
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -455,6 +455,7 @@ typedef void (dio_iodone_t)(struct kiocb
+ #define ATTR_KILL_PRIV	(1 << 14)
+ #define ATTR_OPEN	(1 << 15) /* Truncating from open(O_TRUNC) */
+ #define ATTR_TIMES_SET	(1 << 16)
++#define ATTR_DENTRY	(1 << 18) /* ia_file is actually a dentry */
+ 
+ /*
+  * This is the Inode Attributes structure, used for notify_change().  It
+@@ -2614,6 +2615,7 @@ extern int buffer_migrate_page(struct ad
+ #define buffer_migrate_page NULL
+ #endif
+ 
++extern int inode_change_ok(const struct inode *, struct iattr *);
+ extern int setattr_prepare(struct dentry *, struct iattr *);
+ extern int inode_newsize_ok(const struct inode *, loff_t offset);
+ extern void setattr_copy(struct inode *inode, const struct iattr *attr);
+--- a/fs/attr.c
++++ b/fs/attr.c
+@@ -15,6 +15,9 @@
+ #include <linux/security.h>
+ #include <linux/evm.h>
+ 
++static int __setattr_prepare(struct dentry *dentry, const struct inode *inode,
++			     struct iattr *attr);
++
+ /**
+  * setattr_prepare - check if attribute changes to a dentry are allowed
+  * @dentry:	dentry to check
+@@ -31,7 +34,35 @@
+  */
+ int setattr_prepare(struct dentry *dentry, struct iattr *attr)
+ {
+-	struct inode *inode = dentry->d_inode;
++	return __setattr_prepare(dentry, dentry->d_inode, attr);
++}
++EXPORT_SYMBOL(setattr_prepare);
++
++/* Backward-compatible version of setattr_prepare() */
++int inode_change_ok(const struct inode *inode, struct iattr *attr)
++{
++	struct dentry *dentry;
++
++	/*
++	 * If ia_file holds a dentry and it matches the inode then
++	 * pass it down.  Otherwise, pass NULL.  The dentry is only
++	 * needed if ATTR_KILL_PRIV is set in ia_flags.
++	 */
++	if ((attr->ia_valid & (ATTR_FILE | ATTR_DENTRY)) == ATTR_DENTRY) {
++		dentry = (struct dentry *)attr->ia_file;
++		if (dentry->d_inode != inode)
++			dentry = NULL;
++	} else {
++		dentry = NULL;
++	}
++
++	return __setattr_prepare(dentry, inode, attr);
++}
++EXPORT_SYMBOL(inode_change_ok);
++
++static int __setattr_prepare(struct dentry *dentry, const struct inode *inode,
++			     struct iattr *attr)
++{
+ 	unsigned int ia_valid = attr->ia_valid;
+ 
+ 	/*
+@@ -82,6 +113,9 @@ kill_priv:
+ 	if (ia_valid & ATTR_KILL_PRIV) {
+ 		int error;
+ 
++		if (WARN_ON_ONCE(!dentry))
++			return -EIO;
++
+ 		error = security_inode_killpriv(dentry);
+ 		if (error)
+ 			return error;
+@@ -89,7 +123,6 @@ kill_priv:
+ 
+ 	return 0;
+ }
+-EXPORT_SYMBOL(setattr_prepare);
+ 
+ /**
+  * inode_newsize_ok - may this inode be truncated to a given size
+@@ -249,11 +282,23 @@ int notify_change(struct dentry * dentry
+ 	if (error)
+ 		return error;
+ 
++	/* Smuggle the dentry through to inode_change_ok() */
++	if (!(attr->ia_valid & ATTR_FILE)) {
++		attr->ia_file = (struct file *)dentry;
++		attr->ia_valid |= ATTR_DENTRY;
++	}
++
+ 	if (inode->i_op->setattr)
+ 		error = inode->i_op->setattr(dentry, attr);
+ 	else
+ 		error = simple_setattr(dentry, attr);
+ 
++	if (attr->ia_valid & ATTR_DENTRY) {
++		if (!(attr->ia_valid & ATTR_FILE))
++			attr->ia_file = NULL;
++		attr->ia_valid &= ~ATTR_DENTRY;
++	}
++
+ 	if (!error) {
+ 		fsnotify_change(dentry, ia_valid);
+ 		evm_inode_post_setattr(dentry, ia_valid);
diff --git a/debian/patches/debian/i8042-revert-abi-break-in-3.2.84.patch b/debian/patches/debian/i8042-revert-abi-break-in-3.2.84.patch
new file mode 100644
index 0000000..d6bcf2a
--- /dev/null
+++ b/debian/patches/debian/i8042-revert-abi-break-in-3.2.84.patch
@@ -0,0 +1,147 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Fri, 09 Sep 2016 02:13:06 +0100
+Subject: i8042: Revert ABI break in 4.7.3
+Forwarded: not-needed
+
+Revert "Input: i8042 - set up shared ps2_cmd_mutex for AUX ports" and
+"Input: i8042 - break load dependency between atkbd/psmouse and i8042"
+to avoid an ABI break.
+
+CONFIG_SERIO_I8042=m is absurd on x86 so this didn't really deserve a
+stable update.
+
+---
+--- a/drivers/input/serio/i8042.c
++++ b/drivers/input/serio/i8042.c
+@@ -1223,7 +1223,6 @@ static int __init i8042_create_kbd_port(
+ 	serio->start		= i8042_start;
+ 	serio->stop		= i8042_stop;
+ 	serio->close		= i8042_port_close;
+-	serio->ps2_cmd_mutex	= &i8042_mutex;
+ 	serio->port_data	= port;
+ 	serio->dev.parent	= &i8042_platform_device->dev;
+ 	strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
+@@ -1249,7 +1248,6 @@ static int __init i8042_create_aux_port(
+ 	serio->write		= i8042_aux_write;
+ 	serio->start		= i8042_start;
+ 	serio->stop		= i8042_stop;
+-	serio->ps2_cmd_mutex	= &i8042_mutex;
+ 	serio->port_data	= port;
+ 	serio->dev.parent	= &i8042_platform_device->dev;
+ 	if (idx < 0) {
+@@ -1312,6 +1310,21 @@ static void __devexit i8042_unregister_p
+ 	}
+ }
+ 
++/*
++ * Checks whether port belongs to i8042 controller.
++ */
++bool i8042_check_port_owner(const struct serio *port)
++{
++	int i;
++
++	for (i = 0; i < I8042_NUM_PORTS; i++)
++		if (i8042_ports[i].serio == port)
++			return true;
++
++	return false;
++}
++EXPORT_SYMBOL(i8042_check_port_owner);
++
+ static void i8042_free_irqs(void)
+ {
+ 	if (i8042_aux_irq_registered)
+--- a/drivers/input/serio/libps2.c
++++ b/drivers/input/serio/libps2.c
+@@ -57,17 +57,19 @@ EXPORT_SYMBOL(ps2_sendbyte);
+ 
+ void ps2_begin_command(struct ps2dev *ps2dev)
+ {
+-	struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
++	mutex_lock(&ps2dev->cmd_mutex);
+ 
+-	mutex_lock(m);
++	if (i8042_check_port_owner(ps2dev->serio))
++		i8042_lock_chip();
+ }
+ EXPORT_SYMBOL(ps2_begin_command);
+ 
+ void ps2_end_command(struct ps2dev *ps2dev)
+ {
+-	struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
++	if (i8042_check_port_owner(ps2dev->serio))
++		i8042_unlock_chip();
+ 
+-	mutex_unlock(m);
++	mutex_unlock(&ps2dev->cmd_mutex);
+ }
+ EXPORT_SYMBOL(ps2_end_command);
+ 
+--- a/include/linux/i8042.h
++++ b/include/linux/i8042.h
+@@ -38,6 +38,7 @@ struct serio;
+ void i8042_lock_chip(void);
+ void i8042_unlock_chip(void);
+ int i8042_command(unsigned char *param, int command);
++bool i8042_check_port_owner(const struct serio *);
+ int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
+ 					struct serio *serio));
+ int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
+@@ -58,6 +59,11 @@ static inline int i8042_command(unsigned
+ 	return -ENODEV;
+ }
+ 
++static inline bool i8042_check_port_owner(const struct serio *serio)
++{
++	return false;
++}
++
+ static inline int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
+ 					struct serio *serio))
+ {
+--- a/include/linux/serio.h
++++ b/include/linux/serio.h
+@@ -33,8 +33,7 @@ struct serio {
+ 
+ 	struct serio_device_id id;
+ 
+-	/* Protects critical sections from port's interrupt handler */
+-	spinlock_t lock;
++	spinlock_t lock;		/* protects critical sections from port's interrupt handler */
+ 
+ 	int (*write)(struct serio *, unsigned char);
+ 	int (*open)(struct serio *);
+@@ -43,29 +42,16 @@ struct serio {
+ 	void (*stop)(struct serio *);
+ 
+ 	struct serio *parent;
+-	/* Entry in parent->children list */
+-	struct list_head child_node;
++	struct list_head child_node;	/* Entry in parent->children list */
+ 	struct list_head children;
+-	/* Level of nesting in serio hierarchy */
+-	unsigned int depth;
++	unsigned int depth;		/* level of nesting in serio hierarchy */
+ 
+-	/*
+-	 * serio->drv is accessed from interrupt handlers; when modifying
+-	 * caller should acquire serio->drv_mutex and serio->lock.
+-	 */
+-	struct serio_driver *drv;
+-	/* Protects serio->drv so attributes can pin current driver */
+-	struct mutex drv_mutex;
++	struct serio_driver *drv;	/* accessed from interrupt, must be protected by serio->lock and serio->sem */
++	struct mutex drv_mutex;		/* protects serio->drv so attributes can pin driver */
+ 
+ 	struct device dev;
+ 
+ 	struct list_head node;
+-
+-	/*
+-	 * For use by PS/2 layer when several ports share hardware and
+-	 * may get indigestion when exposed to concurrent access (i8042).
+-	 */
+-	struct mutex *ps2_cmd_mutex;
+ };
+ #define to_serio_port(d)	container_of(d, struct serio, dev)
+ 
diff --git a/debian/patches/series b/debian/patches/series
index 06f36f5..90cd5bc 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1170,3 +1170,5 @@ debian/pci-fix-abi-change-in-3.2.80.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
 debian/fs-move-procfs-ecryptfs-stacking-check-into-ecryptfs.patch
+debian/i8042-revert-abi-break-in-3.2.84.patch
+debian/fs-fix-abi-change-in-3.2.84.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