diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2017-10-12 15:27:31 +0100 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2017-10-12 15:27:31 +0100 |
commit | ae8ef25b0a62835c1407bbde56d891c41236baba (patch) | |
tree | c7d100fa5191e107aea934d4fc65b1240e15714d /releases | |
parent | bf42ecbf1c282fe1174f83444083c1830499cdcb (diff) | |
download | linux-stable-queue-ae8ef25b0a62835c1407bbde56d891c41236baba.tar.gz |
Release 3.2.94
Diffstat (limited to 'releases')
75 files changed, 5644 insertions, 0 deletions
diff --git a/releases/3.2.94/add-usb-quirk-for-hvr-950q-to-avoid-intermittent-device-resets.patch b/releases/3.2.94/add-usb-quirk-for-hvr-950q-to-avoid-intermittent-device-resets.patch new file mode 100644 index 00000000..1de6838b --- /dev/null +++ b/releases/3.2.94/add-usb-quirk-for-hvr-950q-to-avoid-intermittent-device-resets.patch @@ -0,0 +1,37 @@ +From: Devin Heitmueller <dheitmueller@kernellabs.com> +Date: Tue, 27 Jun 2017 13:08:51 -0400 +Subject: Add USB quirk for HVR-950q to avoid intermittent device resets + +commit 6836796de4019944f4ba4c99a360e8250fd2e735 upstream. + +The USB core and sysfs will attempt to enumerate certain parameters +which are unsupported by the au0828 - causing inconsistent behavior +and sometimes causing the chip to reset. Avoid making these calls. + +This problem manifested as intermittent cases where the au8522 would +be reset on analog video startup, in particular when starting up ALSA +audio streaming in parallel - the sysfs entries created by +snd-usb-audio on streaming startup would result in unsupported control +messages being sent during tuning which would put the chip into an +unknown state. + +Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/core/quirks.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -183,6 +183,10 @@ static const struct usb_device_id usb_qu + { USB_DEVICE(0x1908, 0x1315), .driver_info = + USB_QUIRK_HONOR_BNUMINTERFACES }, + ++ /* Hauppauge HVR-950q */ ++ { USB_DEVICE(0x2040, 0x7200), .driver_info = ++ USB_QUIRK_CONFIG_INTF_STRINGS }, ++ + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + diff --git a/releases/3.2.94/af_iucv-move-sockaddr-length-checks-to-before-accessing-sa_family-in.patch b/releases/3.2.94/af_iucv-move-sockaddr-length-checks-to-before-accessing-sa_family-in.patch new file mode 100644 index 00000000..1e522ba7 --- /dev/null +++ b/releases/3.2.94/af_iucv-move-sockaddr-length-checks-to-before-accessing-sa_family-in.patch @@ -0,0 +1,48 @@ +From: Mateusz Jurczyk <mjurczyk@google.com> +Date: Fri, 23 Jun 2017 19:32:28 +0200 +Subject: af_iucv: Move sockaddr length checks to before accessing sa_family in + bind and connect handlers + +commit e3c42b61ff813921ba58cfc0019e3fd63f651190 upstream. + +Verify that the caller-provided sockaddr structure is large enough to +contain the sa_family field, before accessing it in bind() and connect() +handlers of the AF_IUCV socket. Since neither syscall enforces a minimum +size of the corresponding memory region, very short sockaddrs (zero or +one byte long) result in operating on uninitialized memory while +referencing .sa_family. + +Fixes: 52a82e23b9f2 ("af_iucv: Validate socket address length in iucv_sock_bind()") +Signed-off-by: Mateusz Jurczyk <mjurczyk@google.com> +[jwi: removed unneeded null-check for addr] +Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/iucv/af_iucv.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/net/iucv/af_iucv.c ++++ b/net/iucv/af_iucv.c +@@ -705,10 +705,8 @@ static int iucv_sock_bind(struct socket + char uid[9]; + + /* Verify the input sockaddr */ +- if (!addr || addr->sa_family != AF_IUCV) +- return -EINVAL; +- +- if (addr_len < sizeof(struct sockaddr_iucv)) ++ if (addr_len < sizeof(struct sockaddr_iucv) || ++ addr->sa_family != AF_IUCV) + return -EINVAL; + + lock_sock(sk); +@@ -879,7 +877,7 @@ static int iucv_sock_connect(struct sock + struct iucv_sock *iucv = iucv_sk(sk); + int err; + +- if (addr->sa_family != AF_IUCV || alen < sizeof(struct sockaddr_iucv)) ++ if (alen < sizeof(struct sockaddr_iucv) || addr->sa_family != AF_IUCV) + return -EINVAL; + + if (sk->sk_state != IUCV_OPEN && sk->sk_state != IUCV_BOUND) diff --git a/releases/3.2.94/bluetooth-properly-check-l2cap-config-option-output-buffer-length.patch b/releases/3.2.94/bluetooth-properly-check-l2cap-config-option-output-buffer-length.patch new file mode 100644 index 00000000..2b177717 --- /dev/null +++ b/releases/3.2.94/bluetooth-properly-check-l2cap-config-option-output-buffer-length.patch @@ -0,0 +1,273 @@ +From: Ben Seri <ben@armis.com> +Date: Sat, 9 Sep 2017 23:15:59 +0200 +Subject: Bluetooth: Properly check L2CAP config option output buffer length + +commit e860d2c904d1a9f38a24eb44c9f34b8f915a6ea3 upstream. + +Validate the output buffer length for L2CAP config requests and responses +to avoid overflowing the stack buffer used for building the option blocks. + +Signed-off-by: Ben Seri <ben@armis.com> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.2: + - Drop changes to handling of L2CAP_CONF_EFS, L2CAP_CONF_EWS + - Drop changes to l2cap_do_create(), l2cap_security_cfm(), and L2CAP_CONF_PENDING + case in l2cap_config_rsp() + - In l2cap_config_rsp(), s/buf/req/ + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -68,7 +68,7 @@ static struct sk_buff *l2cap_build_cmd(s + u8 code, u8 ident, u16 dlen, void *data); + static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, + void *data); +-static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); ++static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size); + static void l2cap_send_disconn_req(struct l2cap_conn *conn, + struct l2cap_chan *chan, int err); + +@@ -787,7 +787,7 @@ static void l2cap_conn_start(struct l2ca + + set_bit(CONF_REQ_SENT, &chan->conf_state); + l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, +- l2cap_build_conf_req(chan, buf), buf); ++ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); + chan->num_conf_req++; + } + +@@ -1825,12 +1825,15 @@ static inline int l2cap_get_conf_opt(voi + return len; + } + +-static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) ++static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val, size_t size) + { + struct l2cap_conf_opt *opt = *ptr; + + BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val); + ++ if (size < L2CAP_CONF_OPT_SIZE + len) ++ return; ++ + opt->type = type; + opt->len = len; + +@@ -1901,11 +1904,12 @@ static inline __u8 l2cap_select_mode(__u + } + } + +-static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) ++static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size) + { + struct l2cap_conf_req *req = data; + struct l2cap_conf_rfc rfc = { .mode = chan->mode }; + void *ptr = req->data; ++ void *endptr = data + data_size; + + BT_DBG("chan %p", chan); + +@@ -1926,7 +1930,7 @@ static int l2cap_build_conf_req(struct l + + done: + if (chan->imtu != L2CAP_DEFAULT_MTU) +- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); ++ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr); + + switch (chan->mode) { + case L2CAP_MODE_BASIC: +@@ -1942,7 +1946,7 @@ done: + rfc.max_pdu_size = 0; + + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), +- (unsigned long) &rfc); ++ (unsigned long) &rfc, endptr - ptr); + break; + + case L2CAP_MODE_ERTM: +@@ -1956,7 +1960,7 @@ done: + rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); + + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), +- (unsigned long) &rfc); ++ (unsigned long) &rfc, endptr - ptr); + + if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) + break; +@@ -1964,7 +1968,8 @@ done: + if (chan->fcs == L2CAP_FCS_NONE || + test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { + chan->fcs = L2CAP_FCS_NONE; +- l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); ++ l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs, ++ endptr - ptr); + } + break; + +@@ -1979,7 +1984,7 @@ done: + rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); + + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), +- (unsigned long) &rfc); ++ (unsigned long) &rfc, endptr - ptr); + + if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) + break; +@@ -1987,7 +1992,8 @@ done: + if (chan->fcs == L2CAP_FCS_NONE || + test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { + chan->fcs = L2CAP_FCS_NONE; +- l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); ++ l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs, ++ endptr - ptr); + } + break; + } +@@ -1998,10 +2004,11 @@ done: + return ptr - data; + } + +-static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) ++static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data_size) + { + struct l2cap_conf_rsp *rsp = data; + void *ptr = rsp->data; ++ void *endptr = data + data_size; + void *req = chan->conf_req; + int len = chan->conf_len; + int type, hint, olen; +@@ -2077,8 +2084,8 @@ done: + if (chan->num_conf_rsp == 1) + return -ECONNREFUSED; + +- l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, +- sizeof(rfc), (unsigned long) &rfc); ++ l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), ++ (unsigned long) &rfc, endptr - ptr); + } + + +@@ -2092,7 +2099,7 @@ done: + chan->omtu = mtu; + set_bit(CONF_MTU_DONE, &chan->conf_state); + } +- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); ++ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu, endptr - ptr); + + switch (rfc.mode) { + case L2CAP_MODE_BASIC: +@@ -2117,7 +2124,7 @@ done: + set_bit(CONF_MODE_DONE, &chan->conf_state); + + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, +- sizeof(rfc), (unsigned long) &rfc); ++ sizeof(rfc), (unsigned long) &rfc, endptr - ptr); + + break; + +@@ -2129,8 +2136,8 @@ done: + + set_bit(CONF_MODE_DONE, &chan->conf_state); + +- l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, +- sizeof(rfc), (unsigned long) &rfc); ++ l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), ++ (unsigned long) &rfc, endptr - ptr); + + break; + +@@ -2151,10 +2158,12 @@ done: + return ptr - data; + } + +-static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, void *data, u16 *result) ++static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, ++ void *data, size_t size, u16 *result) + { + struct l2cap_conf_req *req = data; + void *ptr = req->data; ++ void *endptr = data + size; + int type, olen; + unsigned long val; + struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; +@@ -2171,13 +2180,13 @@ static int l2cap_parse_conf_rsp(struct l + chan->imtu = L2CAP_DEFAULT_MIN_MTU; + } else + chan->imtu = val; +- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); ++ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr); + break; + + case L2CAP_CONF_FLUSH_TO: + chan->flush_to = val; + l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, +- 2, chan->flush_to); ++ 2, chan->flush_to, endptr - ptr); + break; + + case L2CAP_CONF_RFC: +@@ -2191,7 +2200,7 @@ static int l2cap_parse_conf_rsp(struct l + chan->fcs = 0; + + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, +- sizeof(rfc), (unsigned long) &rfc); ++ sizeof(rfc), (unsigned long) &rfc, endptr - ptr); + break; + } + } +@@ -2250,7 +2259,7 @@ void __l2cap_connect_rsp_defer(struct l2 + return; + + l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, +- l2cap_build_conf_req(chan, buf), buf); ++ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); + chan->num_conf_req++; + } + +@@ -2459,7 +2468,7 @@ sendresp: + u8 buf[128]; + set_bit(CONF_REQ_SENT, &chan->conf_state); + l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, +- l2cap_build_conf_req(chan, buf), buf); ++ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); + chan->num_conf_req++; + } + +@@ -2509,7 +2518,7 @@ static int l2cap_connect_rsp(struct l2ca + break; + + l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, +- l2cap_build_conf_req(chan, req), req); ++ l2cap_build_conf_req(chan, req, sizeof(req)), req); + chan->num_conf_req++; + break; + +@@ -2602,7 +2611,7 @@ static inline int l2cap_config_req(struc + } + + /* Complete config. */ +- len = l2cap_parse_conf_req(chan, rsp); ++ len = l2cap_parse_conf_req(chan, rsp, sizeof(rsp)); + if (len < 0) { + l2cap_send_disconn_req(conn, chan, ECONNRESET); + goto unlock; +@@ -2635,7 +2644,7 @@ static inline int l2cap_config_req(struc + if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) { + u8 buf[64]; + l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, +- l2cap_build_conf_req(chan, buf), buf); ++ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); + chan->num_conf_req++; + } + +@@ -2687,7 +2696,7 @@ static inline int l2cap_config_rsp(struc + /* throw out any old stored conf requests */ + result = L2CAP_CONF_SUCCESS; + len = l2cap_parse_conf_rsp(chan, rsp->data, len, +- req, &result); ++ req, sizeof(req), &result); + if (len < 0) { + l2cap_send_disconn_req(conn, chan, ECONNRESET); + goto done; diff --git a/releases/3.2.94/btrfs-don-t-clear-sgid-when-inheriting-acls.patch b/releases/3.2.94/btrfs-don-t-clear-sgid-when-inheriting-acls.patch new file mode 100644 index 00000000..702563f7 --- /dev/null +++ b/releases/3.2.94/btrfs-don-t-clear-sgid-when-inheriting-acls.patch @@ -0,0 +1,71 @@ +From: Jan Kara <jack@suse.cz> +Date: Thu, 22 Jun 2017 15:31:07 +0200 +Subject: btrfs: Don't clear SGID when inheriting ACLs + +commit b7f8a09f8097db776b8d160862540e4fc1f51296 upstream. + +When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit +set, DIR1 is expected to have SGID bit set (and owning group equal to +the owning group of 'DIR0'). However when 'DIR0' also has some default +ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on +'DIR1' to get cleared if user is not member of the owning group. + +Fix the problem by moving posix_acl_update_mode() out of +__btrfs_set_acl() into btrfs_set_acl(). That way the function will not be +called when inheriting ACLs which is what we want as it prevents SGID +bit clearing and the mode has been properly set by posix_acl_create() +anyway. + +Fixes: 073931017b49d9458aa351605b43a7e34598caef +CC: linux-btrfs@vger.kernel.org +CC: David Sterba <dsterba@suse.com> +Signed-off-by: Jan Kara <jack@suse.cz> +Signed-off-by: David Sterba <dsterba@suse.com> +[bwh: Backported to 3.2: move the call to posix_acl_update_mode() into + btrfs_xattr_acl_set()] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/fs/btrfs/acl.c ++++ b/fs/btrfs/acl.c +@@ -117,12 +117,6 @@ static int btrfs_set_acl(struct btrfs_tr + switch (type) { + case ACL_TYPE_ACCESS: + name = POSIX_ACL_XATTR_ACCESS; +- if (acl) { +- ret = posix_acl_update_mode(inode, &inode->i_mode, &acl); +- if (ret) +- return ret; +- } +- ret = 0; + break; + case ACL_TYPE_DEFAULT: + if (!S_ISDIR(inode->i_mode)) +@@ -161,11 +155,12 @@ static int btrfs_xattr_acl_set(struct de + { + int ret; + struct posix_acl *acl = NULL; ++ struct inode *inode = dentry->d_inode; + +- if (!inode_owner_or_capable(dentry->d_inode)) ++ if (!inode_owner_or_capable(inode)) + return -EPERM; + +- if (!IS_POSIXACL(dentry->d_inode)) ++ if (!IS_POSIXACL(inode)) + return -EOPNOTSUPP; + + if (value) { +@@ -180,7 +175,12 @@ static int btrfs_xattr_acl_set(struct de + } + } + +- ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type); ++ if (type == ACL_TYPE_ACCESS && acl) { ++ ret = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (ret) ++ goto out; ++ } ++ ret = btrfs_set_acl(NULL, inode, acl, type); + out: + posix_acl_release(acl); + diff --git a/releases/3.2.94/btrfs-preserve-i_mode-if-__btrfs_set_acl-fails.patch b/releases/3.2.94/btrfs-preserve-i_mode-if-__btrfs_set_acl-fails.patch new file mode 100644 index 00000000..0408670c --- /dev/null +++ b/releases/3.2.94/btrfs-preserve-i_mode-if-__btrfs_set_acl-fails.patch @@ -0,0 +1,47 @@ +From: =?UTF-8?q?Ernesto=20A=2E=20Fern=C3=A1ndez?= + <ernesto.mnd.fernandez@gmail.com> +Date: Wed, 2 Aug 2017 03:18:27 -0300 +Subject: btrfs: preserve i_mode if __btrfs_set_acl() fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit d7d824966530acfe32b94d1ed672e6fe1638cd68 upstream. + +When changing a file's acl mask, btrfs_set_acl() will first set the +group bits of i_mode to the value of the mask, and only then set the +actual extended attribute representing the new acl. + +If the second part fails (due to lack of space, for example) and the +file had no acl attribute to begin with, the system will from now on +assume that the mask permission bits are actual group permission bits, +potentially granting access to the wrong users. + +Prevent this by restoring the original mode bits if __btrfs_set_acl +fails. + +Signed-off-by: Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com> +Reviewed-by: David Sterba <dsterba@suse.com> +Signed-off-by: David Sterba <dsterba@suse.com> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/fs/btrfs/acl.c ++++ b/fs/btrfs/acl.c +@@ -156,6 +156,7 @@ static int btrfs_xattr_acl_set(struct de + int ret; + struct posix_acl *acl = NULL; + struct inode *inode = dentry->d_inode; ++ umode_t old_mode = inode->i_mode; + + if (!inode_owner_or_capable(inode)) + return -EPERM; +@@ -181,6 +182,8 @@ static int btrfs_xattr_acl_set(struct de + goto out; + } + ret = btrfs_set_acl(NULL, inode, acl, type); ++ if (ret) ++ inode->i_mode = old_mode; + out: + posix_acl_release(acl); + diff --git a/releases/3.2.94/cfg80211-check-if-pmkid-attribute-is-of-expected-size.patch b/releases/3.2.94/cfg80211-check-if-pmkid-attribute-is-of-expected-size.patch new file mode 100644 index 00000000..e3b1bcee --- /dev/null +++ b/releases/3.2.94/cfg80211-check-if-pmkid-attribute-is-of-expected-size.patch @@ -0,0 +1,38 @@ +From: Srinivas Dasari <dasaris@qti.qualcomm.com> +Date: Fri, 7 Jul 2017 01:43:39 +0300 +Subject: cfg80211: Check if PMKID attribute is of expected size + +commit 9361df14d1cbf966409d5d6f48bb334384fbe138 upstream. + +nla policy checks for only maximum length of the attribute data +when the attribute type is NLA_BINARY. If userspace sends less +data than specified, the wireless drivers may access illegal +memory. When type is NLA_UNSPEC, nla policy check ensures that +userspace sends minimum specified length number of bytes. + +Remove type assignment to NLA_BINARY from nla_policy of +NL80211_ATTR_PMKID to make this NLA_UNSPEC and to make sure minimum +WLAN_PMKID_LEN bytes are received from userspace with +NL80211_ATTR_PMKID. + +Fixes: 67fbb16be69d ("nl80211: PMKSA caching support") +Signed-off-by: Srinivas Dasari <dasaris@qti.qualcomm.com> +Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/wireless/nl80211.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -158,8 +158,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, + [NL80211_ATTR_PID] = { .type = NLA_U32 }, + [NL80211_ATTR_4ADDR] = { .type = NLA_U8 }, +- [NL80211_ATTR_PMKID] = { .type = NLA_BINARY, +- .len = WLAN_PMKID_LEN }, ++ [NL80211_ATTR_PMKID] = { .len = WLAN_PMKID_LEN }, + [NL80211_ATTR_DURATION] = { .type = NLA_U32 }, + [NL80211_ATTR_COOKIE] = { .type = NLA_U64 }, + [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED }, diff --git a/releases/3.2.94/cfg80211-validate-frequencies-nested-in.patch b/releases/3.2.94/cfg80211-validate-frequencies-nested-in.patch new file mode 100644 index 00000000..9eba8b66 --- /dev/null +++ b/releases/3.2.94/cfg80211-validate-frequencies-nested-in.patch @@ -0,0 +1,38 @@ +From: Srinivas Dasari <dasaris@qti.qualcomm.com> +Date: Fri, 7 Jul 2017 01:43:42 +0300 +Subject: cfg80211: Validate frequencies nested in + NL80211_ATTR_SCAN_FREQUENCIES + +commit d7f13f7450369281a5d0ea463cc69890a15923ae upstream. + +validate_scan_freqs() retrieves frequencies from attributes +nested in the attribute NL80211_ATTR_SCAN_FREQUENCIES with +nla_get_u32(), which reads 4 bytes from each attribute +without validating the size of data received. Attributes +nested in NL80211_ATTR_SCAN_FREQUENCIES don't have an nla policy. + +Validate size of each attribute before parsing to avoid potential buffer +overread. + +Fixes: 2a519311926 ("cfg80211/nl80211: scanning (and mac80211 update to use it)") +Signed-off-by: Srinivas Dasari <dasaris@qti.qualcomm.com> +Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/wireless/nl80211.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3499,6 +3499,10 @@ static int validate_scan_freqs(struct nl + struct nlattr *attr1, *attr2; + int n_channels = 0, tmp1, tmp2; + ++ nla_for_each_nested(attr1, freqs, tmp1) ++ if (nla_len(attr1) != sizeof(u32)) ++ return 0; ++ + nla_for_each_nested(attr1, freqs, tmp1) { + n_channels++; + /* diff --git a/releases/3.2.94/cpuset-pf_spread_page-and-pf_spread_slab-should-be-atomic-flags.patch b/releases/3.2.94/cpuset-pf_spread_page-and-pf_spread_slab-should-be-atomic-flags.patch new file mode 100644 index 00000000..f24fee9e --- /dev/null +++ b/releases/3.2.94/cpuset-pf_spread_page-and-pf_spread_slab-should-be-atomic-flags.patch @@ -0,0 +1,158 @@ +From: Zefan Li <lizefan@huawei.com> +Date: Thu, 25 Sep 2014 09:41:02 +0800 +Subject: cpuset: PF_SPREAD_PAGE and PF_SPREAD_SLAB should be atomic flags + +commit 2ad654bc5e2b211e92f66da1d819e47d79a866f0 upstream. + +When we change cpuset.memory_spread_{page,slab}, cpuset will flip +PF_SPREAD_{PAGE,SLAB} bit of tsk->flags for each task in that cpuset. +This should be done using atomic bitops, but currently we don't, +which is broken. + +Tetsuo reported a hard-to-reproduce kernel crash on RHEL6, which happened +when one thread tried to clear PF_USED_MATH while at the same time another +thread tried to flip PF_SPREAD_PAGE/PF_SPREAD_SLAB. They both operate on +the same task. + +Here's the full report: +https://lkml.org/lkml/2014/9/19/230 + +To fix this, we make PF_SPREAD_PAGE and PF_SPREAD_SLAB atomic flags. + +v4: +- updated mm/slab.c. (Fengguang Wu) +- updated Documentation. + +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Ingo Molnar <mingo@kernel.org> +Cc: Miao Xie <miaox@cn.fujitsu.com> +Cc: Kees Cook <keescook@chromium.org> +Fixes: 950592f7b991 ("cpusets: update tasks' page/slab spread flags in time") +Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Signed-off-by: Zefan Li <lizefan@huawei.com> +Signed-off-by: Tejun Heo <tj@kernel.org> +[lizf: Backported to 3.4: + - adjust context + - check current->flags & PF_MEMPOLICY rather than current->mempolicy] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + Documentation/cgroups/cpusets.txt | 6 +++--- + include/linux/cpuset.h | 4 ++-- + include/linux/sched.h | 12 ++++++++++-- + kernel/cpuset.c | 9 +++++---- + mm/slab.c | 4 ++-- + 5 files changed, 22 insertions(+), 13 deletions(-) + +--- a/Documentation/cgroups/cpusets.txt ++++ b/Documentation/cgroups/cpusets.txt +@@ -345,14 +345,14 @@ the named feature on. + The implementation is simple. + + Setting the flag 'cpuset.memory_spread_page' turns on a per-process flag +-PF_SPREAD_PAGE for each task that is in that cpuset or subsequently ++PFA_SPREAD_PAGE for each task that is in that cpuset or subsequently + joins that cpuset. The page allocation calls for the page cache +-is modified to perform an inline check for this PF_SPREAD_PAGE task ++is modified to perform an inline check for this PFA_SPREAD_PAGE task + flag, and if set, a call to a new routine cpuset_mem_spread_node() + returns the node to prefer for the allocation. + + Similarly, setting 'cpuset.memory_spread_slab' turns on the flag +-PF_SPREAD_SLAB, and appropriately marked slab caches will allocate ++PFA_SPREAD_SLAB, and appropriately marked slab caches will allocate + pages from the node returned by cpuset_mem_spread_node(). + + The cpuset_mem_spread_node() routine is also simple. It uses the +--- a/include/linux/cpuset.h ++++ b/include/linux/cpuset.h +@@ -74,12 +74,12 @@ extern int cpuset_slab_spread_node(void) + + static inline int cpuset_do_page_mem_spread(void) + { +- return current->flags & PF_SPREAD_PAGE; ++ return task_spread_page(current); + } + + static inline int cpuset_do_slab_mem_spread(void) + { +- return current->flags & PF_SPREAD_SLAB; ++ return task_spread_slab(current); + } + + extern int current_cpuset_is_being_rebound(void); +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1812,8 +1812,6 @@ extern void thread_group_times(struct ta + #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ + #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ + #define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ +-#define PF_SPREAD_PAGE 0x01000000 /* Spread page cache over cpuset */ +-#define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */ + #define PF_THREAD_BOUND 0x04000000 /* Thread bound to specific cpu */ + #define PF_MCE_EARLY 0x08000000 /* Early kill for mce process policy */ + #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ +@@ -1847,6 +1845,8 @@ extern void thread_group_times(struct ta + #define used_math() tsk_used_math(current) + + /* Per-process atomic flags. */ ++#define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */ ++#define PFA_SPREAD_SLAB 2 /* Spread some slab caches over cpuset */ + + #define TASK_PFA_TEST(name, func) \ + static inline bool task_##func(struct task_struct *p) \ +@@ -1950,6 +1950,14 @@ static inline int set_cpus_allowed(struc + } + #endif + ++TASK_PFA_TEST(SPREAD_PAGE, spread_page) ++TASK_PFA_SET(SPREAD_PAGE, spread_page) ++TASK_PFA_CLEAR(SPREAD_PAGE, spread_page) ++ ++TASK_PFA_TEST(SPREAD_SLAB, spread_slab) ++TASK_PFA_SET(SPREAD_SLAB, spread_slab) ++TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab) ++ + /* + * Do not use outside of architecture code which knows its limitations. + * +--- a/kernel/cpuset.c ++++ b/kernel/cpuset.c +@@ -326,13 +326,14 @@ static void cpuset_update_task_spread_fl + struct task_struct *tsk) + { + if (is_spread_page(cs)) +- tsk->flags |= PF_SPREAD_PAGE; ++ task_set_spread_page(tsk); + else +- tsk->flags &= ~PF_SPREAD_PAGE; ++ task_clear_spread_page(tsk); ++ + if (is_spread_slab(cs)) +- tsk->flags |= PF_SPREAD_SLAB; ++ task_set_spread_slab(tsk); + else +- tsk->flags &= ~PF_SPREAD_SLAB; ++ task_clear_spread_slab(tsk); + } + + /* +--- a/mm/slab.c ++++ b/mm/slab.c +@@ -3255,7 +3255,7 @@ static inline void *____cache_alloc(stru + + #ifdef CONFIG_NUMA + /* +- * Try allocating on another node if PF_SPREAD_SLAB|PF_MEMPOLICY. ++ * Try allocating on another node if PFA_SPREAD_SLAB|PF_MEMPOLICY. + * + * If we are in_interrupt, then process context, including cpusets and + * mempolicy, may not apply and should not be used for allocation policy. +@@ -3496,7 +3496,7 @@ __do_cache_alloc(struct kmem_cache *cach + { + void *objp; + +- if (unlikely(current->flags & (PF_SPREAD_SLAB | PF_MEMPOLICY))) { ++ if (unlikely((current->flags & PF_MEMPOLICY) || cpuset_do_slab_mem_spread())) { + objp = alternate_node_alloc(cache, flags); + if (objp) + goto out; diff --git a/releases/3.2.94/drm-i915-disable-msi-for-all-pre-gen5.patch b/releases/3.2.94/drm-i915-disable-msi-for-all-pre-gen5.patch new file mode 100644 index 00000000..03660bf2 --- /dev/null +++ b/releases/3.2.94/drm-i915-disable-msi-for-all-pre-gen5.patch @@ -0,0 +1,69 @@ +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> +Date: Mon, 26 Jun 2017 23:30:51 +0300 +Subject: drm/i915: Disable MSI for all pre-gen5 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit ce3f7163e4ce8fd583dcb36b6ee6b81fd1b419ae upstream. + +We have pretty clear evidence that MSIs are getting lost on g4x and +somehow the interrupt logic doesn't seem to recover from that state +even if we try hard to clear the IIR. + +Disabling IER around the normal IIR clearing in the irq handler isn't +sufficient to avoid this, so the problem really seems to be further +up the interrupt chain. This should guarantee that there's always +an edge if any IIR bits are set after the interrupt handler is done, +which should normally guarantee that the CPU interrupt is generated. +That approach seems to work perfectly on VLV/CHV, but apparently +not on g4x. + +MSI is documented to be broken on 965gm at least. The chipset spec +says MSI is defeatured because interrupts can be delayed or lost, +which fits well with what we're seeing on g4x. Previously we've +already disabled GMBUS interrupts on g4x because somehow GMBUS +manages to raise legacy interrupts even when MSI is enabled. + +Since there's such widespread MSI breakahge all over in the pre-gen5 +land let's just give up on MSI on these platforms. + +Seqno reporting might be negatively affected by this since the legcy +interrupts aren't guaranteed to be ordered with the seqno writes, +whereas MSI interrupts may be? But an occasioanlly missed seqno +seems like a small price to pay for generally working interrupts. + +Cc: Diego Viola <diego.viola@gmail.com> +Tested-by: Diego Viola <diego.viola@gmail.com> +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101261 +Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/20170626203051.28480-1-ville.syrjala@linux.intel.com +Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> +(cherry picked from commit e38c2da01f76cca82b59ca612529b81df82a7cc7) +Signed-off-by: Jani Nikula <jani.nikula@intel.com> +[bwh: Backported to 3.2: + - Open-code INTEL_GEN() + - Adjust filename, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/gpu/drm/i915/i915_dma.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -2059,10 +2059,12 @@ int i915_driver_load(struct drm_device * + * and the registers being closely associated. + * + * According to chipset errata, on the 965GM, MSI interrupts may +- * be lost or delayed, but we use them anyways to avoid +- * stuck interrupts on some machines. ++ * be lost or delayed, and was defeatured. MSI interrupts seem to ++ * get lost on g4x as well, and interrupt delivery seems to stay ++ * properly dead afterwards. So we'll just disable them for all ++ * pre-gen5 chipsets. + */ +- if (!IS_I945G(dev) && !IS_I945GM(dev)) ++ if (INTEL_INFO(dev)->gen >= 5) + pci_enable_msi(dev->pdev); + + spin_lock_init(&dev_priv->gt_lock); diff --git a/releases/3.2.94/ext2-don-t-clear-sgid-when-inheriting-acls.patch b/releases/3.2.94/ext2-don-t-clear-sgid-when-inheriting-acls.patch new file mode 100644 index 00000000..360429cd --- /dev/null +++ b/releases/3.2.94/ext2-don-t-clear-sgid-when-inheriting-acls.patch @@ -0,0 +1,119 @@ +From: Jan Kara <jack@suse.cz> +Date: Wed, 21 Jun 2017 14:34:15 +0200 +Subject: ext2: Don't clear SGID when inheriting ACLs + +commit a992f2d38e4ce17b8c7d1f7f67b2de0eebdea069 upstream. + +When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit +set, DIR1 is expected to have SGID bit set (and owning group equal to +the owning group of 'DIR0'). However when 'DIR0' also has some default +ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on +'DIR1' to get cleared if user is not member of the owning group. + +Fix the problem by creating __ext2_set_acl() function that does not call +posix_acl_update_mode() and use it when inheriting ACLs. That prevents +SGID bit clearing and the mode has been properly set by +posix_acl_create() anyway. + +Fixes: 073931017b49d9458aa351605b43a7e34598caef +CC: linux-ext4@vger.kernel.org +Signed-off-by: Jan Kara <jack@suse.cz> +[bwh: Backported to 3.2: + - Keep using CURRENT_TIME_SEC + - Change parameter order of ext2_set_acl() to match upstream + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext2/acl.c | 36 ++++++++++++++++++++++-------------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +--- a/fs/ext2/acl.c ++++ b/fs/ext2/acl.c +@@ -174,11 +174,8 @@ ext2_get_acl(struct inode *inode, int ty + return acl; + } + +-/* +- * inode->i_mutex: down +- */ + static int +-ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) ++__ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type) + { + int name_index; + void *value = NULL; +@@ -193,13 +190,6 @@ ext2_set_acl(struct inode *inode, int ty + switch(type) { + case ACL_TYPE_ACCESS: + name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; +- if (acl) { +- error = posix_acl_update_mode(inode, &inode->i_mode, &acl); +- if (error) +- return error; +- inode->i_ctime = CURRENT_TIME_SEC; +- mark_inode_dirty(inode); +- } + break; + + case ACL_TYPE_DEFAULT: +@@ -226,6 +216,24 @@ ext2_set_acl(struct inode *inode, int ty + } + + /* ++ * inode->i_mutex: down ++ */ ++static int ++ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type) ++{ ++ int error; ++ ++ if (type == ACL_TYPE_ACCESS && acl) { ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) ++ return error; ++ inode->i_ctime = CURRENT_TIME_SEC; ++ mark_inode_dirty(inode); ++ } ++ return __ext2_set_acl(inode, acl, type); ++} ++ ++/* + * Initialize the ACLs of a new inode. Called from ext2_new_inode. + * + * dir->i_mutex: down +@@ -248,7 +256,7 @@ ext2_init_acl(struct inode *inode, struc + } + if (test_opt(inode->i_sb, POSIX_ACL) && acl) { + if (S_ISDIR(inode->i_mode)) { +- error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl); ++ error = __ext2_set_acl(inode, acl, ACL_TYPE_DEFAULT); + if (error) + goto cleanup; + } +@@ -257,7 +265,7 @@ ext2_init_acl(struct inode *inode, struc + return error; + if (error > 0) { + /* This is an extended ACL */ +- error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl); ++ error = __ext2_set_acl(inode, acl, ACL_TYPE_ACCESS); + } + } + cleanup: +@@ -295,7 +303,7 @@ ext2_acl_chmod(struct inode *inode) + error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (error) + return error; +- error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl); ++ error = ext2_set_acl(inode, acl, ACL_TYPE_ACCESS); + posix_acl_release(acl); + return error; + } +@@ -378,7 +386,7 @@ ext2_xattr_set_acl(struct dentry *dentry + } else + acl = NULL; + +- error = ext2_set_acl(dentry->d_inode, type, acl); ++ error = ext2_set_acl(dentry->d_inode, acl, type); + + release_and_out: + posix_acl_release(acl); diff --git a/releases/3.2.94/ext2-preserve-i_mode-if-ext2_set_acl-fails.patch b/releases/3.2.94/ext2-preserve-i_mode-if-ext2_set_acl-fails.patch new file mode 100644 index 00000000..36fdb229 --- /dev/null +++ b/releases/3.2.94/ext2-preserve-i_mode-if-ext2_set_acl-fails.patch @@ -0,0 +1,57 @@ +From: =?UTF-8?q?Ernesto=20A=2E=20Fern=C3=A1ndez?= + <ernesto.mnd.fernandez@gmail.com> +Date: Wed, 12 Jul 2017 06:54:19 -0300 +Subject: ext2: preserve i_mode if ext2_set_acl() fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit fe26569eb9197d845d73abe7dd20f603d79eb031 upstream. + +When changing a file's acl mask, ext2_set_acl() will first set the group +bits of i_mode to the value of the mask, and only then set the actual +extended attribute representing the new acl. + +If the second part fails (due to lack of space, for example) and the file +had no acl attribute to begin with, the system will from now on assume +that the mask permission bits are actual group permission bits, potentially +granting access to the wrong users. + +Prevent this by only changing the inode mode after the acl has been set. + +[JK: Rebased on top of "ext2: Don't clear SGID when inheriting ACLs"] +Signed-off-by: Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com> +Signed-off-by: Jan Kara <jack@suse.cz> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext2/acl.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/fs/ext2/acl.c ++++ b/fs/ext2/acl.c +@@ -222,15 +222,22 @@ static int + ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type) + { + int error; ++ int update_mode = 0; ++ umode_t mode = inode->i_mode; + + if (type == ACL_TYPE_ACCESS && acl) { +- error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ error = posix_acl_update_mode(inode, &mode, &acl); + if (error) + return error; ++ update_mode = 1; ++ } ++ error = __ext2_set_acl(inode, acl, type); ++ if (!error && update_mode) { ++ inode->i_mode = mode; + inode->i_ctime = CURRENT_TIME_SEC; + mark_inode_dirty(inode); + } +- return __ext2_set_acl(inode, acl, type); ++ return error; + } + + /* diff --git a/releases/3.2.94/ext3-don-t-clear-sgid-when-inheriting-acls.patch b/releases/3.2.94/ext3-don-t-clear-sgid-when-inheriting-acls.patch new file mode 100644 index 00000000..087cd53b --- /dev/null +++ b/releases/3.2.94/ext3-don-t-clear-sgid-when-inheriting-acls.patch @@ -0,0 +1,107 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 06 Oct 2017 03:18:40 +0100 +Subject: ext3: Don't clear SGID when inheriting ACLs + +Based on Jan Kara's fix for ext2 (commit a992f2d38e4c), from which the +following description is taken: + +> When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit +> set, DIR1 is expected to have SGID bit set (and owning group equal to +> the owning group of 'DIR0'). However when 'DIR0' also has some default +> ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on +> 'DIR1' to get cleared if user is not member of the owning group. +> +> Fix the problem by creating __ext2_set_acl() function that does not call +> posix_acl_update_mode() and use it when inheriting ACLs. That prevents +> SGID bit clearing and the mode has been properly set by +> posix_acl_create() anyway. + +Fixes: 073931017b49 ("posix_acl: Clear SGID bit when setting file permissions") +Cc: linux-ext4@vger.kernel.org +Cc: Jan Kara <jack@suse.cz> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext3/acl.c | 36 ++++++++++++++++++++++-------------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +--- a/fs/ext3/acl.c ++++ b/fs/ext3/acl.c +@@ -178,14 +178,9 @@ ext3_get_acl(struct inode *inode, int ty + return acl; + } + +-/* +- * Set the access or default ACL of an inode. +- * +- * inode->i_mutex: down unless called from ext3_new_inode +- */ + static int +-ext3_set_acl(handle_t *handle, struct inode *inode, int type, +- struct posix_acl *acl) ++__ext3_set_acl(handle_t *handle, struct inode *inode, int type, ++ struct posix_acl *acl) + { + int name_index; + void *value = NULL; +@@ -198,13 +193,6 @@ ext3_set_acl(handle_t *handle, struct in + switch(type) { + case ACL_TYPE_ACCESS: + name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; +- if (acl) { +- error = posix_acl_update_mode(inode, &inode->i_mode, &acl); +- if (error) +- return error; +- inode->i_ctime = CURRENT_TIME_SEC; +- ext3_mark_inode_dirty(handle, inode); +- } + break; + + case ACL_TYPE_DEFAULT: +@@ -234,6 +222,27 @@ ext3_set_acl(handle_t *handle, struct in + } + + /* ++ * Set the access or default ACL of an inode. ++ * ++ * inode->i_mutex: down ++ */ ++static int ++ext3_set_acl(handle_t *handle, struct inode *inode, int type, ++ struct posix_acl *acl) ++{ ++ int error; ++ ++ if (type == ACL_TYPE_ACCESS && acl) { ++ error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ if (error) ++ return error; ++ inode->i_ctime = CURRENT_TIME_SEC; ++ ext3_mark_inode_dirty(handle, inode); ++ } ++ return __ext3_set_acl(handle, inode, type, acl); ++} ++ ++/* + * Initialize the ACLs of a new inode. Called from ext3_new_inode. + * + * dir->i_mutex: down +@@ -256,8 +265,8 @@ ext3_init_acl(handle_t *handle, struct i + } + if (test_opt(inode->i_sb, POSIX_ACL) && acl) { + if (S_ISDIR(inode->i_mode)) { +- error = ext3_set_acl(handle, inode, +- ACL_TYPE_DEFAULT, acl); ++ error = __ext3_set_acl(handle, inode, ++ ACL_TYPE_DEFAULT, acl); + if (error) + goto cleanup; + } +@@ -267,7 +276,7 @@ ext3_init_acl(handle_t *handle, struct i + + if (error > 0) { + /* This is an extended ACL */ +- error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); ++ error = __ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); + } + } + cleanup: diff --git a/releases/3.2.94/ext3-preserve-i_mode-if-ext3_set_acl-fails.patch b/releases/3.2.94/ext3-preserve-i_mode-if-ext3_set_acl-fails.patch new file mode 100644 index 00000000..eb59477c --- /dev/null +++ b/releases/3.2.94/ext3-preserve-i_mode-if-ext3_set_acl-fails.patch @@ -0,0 +1,52 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 08 Oct 2017 14:48:44 +0100 +Subject: ext3: preserve i_mode if ext2_set_acl() fails + +Based on Ernesto A. Fernández's fix for ext2 (commit fe26569eb919), from +which the following description is taken: + +> When changing a file's acl mask, ext2_set_acl() will first set the group +> bits of i_mode to the value of the mask, and only then set the actual +> extended attribute representing the new acl. +> +> If the second part fails (due to lack of space, for example) and the file +> had no acl attribute to begin with, the system will from now on assume +> that the mask permission bits are actual group permission bits, potentially +> granting access to the wrong users. +> +> Prevent this by only changing the inode mode after the acl has been set. + +Cc: Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com> +Cc: Jan Kara <jack@suse.cz> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext3/acl.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/fs/ext3/acl.c ++++ b/fs/ext3/acl.c +@@ -231,15 +231,22 @@ ext3_set_acl(handle_t *handle, struct in + struct posix_acl *acl) + { + int error; ++ int update_mode = 0; ++ umode_t mode = inode->i_mode; + + if (type == ACL_TYPE_ACCESS && acl) { +- error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ error = posix_acl_update_mode(inode, &mode, &acl); + if (error) + return error; ++ update_mode = 1; ++ } ++ error = __ext3_set_acl(handle, inode, type, acl); ++ if (!error && update_mode) { ++ inode->i_mode = mode; + inode->i_ctime = CURRENT_TIME_SEC; + ext3_mark_inode_dirty(handle, inode); + } +- return __ext3_set_acl(handle, inode, type, acl); ++ return error; + } + + /* diff --git a/releases/3.2.94/ext4-don-t-clear-sgid-when-inheriting-acls.patch b/releases/3.2.94/ext4-don-t-clear-sgid-when-inheriting-acls.patch new file mode 100644 index 00000000..3e50a289 --- /dev/null +++ b/releases/3.2.94/ext4-don-t-clear-sgid-when-inheriting-acls.patch @@ -0,0 +1,119 @@ +From: Jan Kara <jack@suse.cz> +Date: Sun, 30 Jul 2017 23:33:01 -0400 +Subject: ext4: Don't clear SGID when inheriting ACLs + +commit a3bb2d5587521eea6dab2d05326abb0afb460abd upstream. + +When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit +set, DIR1 is expected to have SGID bit set (and owning group equal to +the owning group of 'DIR0'). However when 'DIR0' also has some default +ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on +'DIR1' to get cleared if user is not member of the owning group. + +Fix the problem by moving posix_acl_update_mode() out of +__ext4_set_acl() into ext4_set_acl(). That way the function will not be +called when inheriting ACLs which is what we want as it prevents SGID +bit clearing and the mode has been properly set by posix_acl_create() +anyway. + +Fixes: 073931017b49d9458aa351605b43a7e34598caef +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Signed-off-by: Jan Kara <jack@suse.cz> +Reviewed-by: Andreas Gruenbacher <agruenba@redhat.com> +[bwh: Backported to 3.2: the __ext4_set_acl() function didn't exist, + so added it] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/acl.c | 28 +++++++++++++++------------- + 1 file changed, 15 insertions(+), 13 deletions(-) + +--- a/fs/ext4/acl.c ++++ b/fs/ext4/acl.c +@@ -183,15 +183,13 @@ ext4_get_acl(struct inode *inode, int ty + * inode->i_mutex: down unless called from ext4_new_inode + */ + static int +-ext4_set_acl(handle_t *handle, struct inode *inode, int type, +- struct posix_acl *acl) ++__ext4_set_acl(handle_t *handle, struct inode *inode, int type, ++ struct posix_acl *acl) + { + int name_index; + void *value = NULL; + size_t size = 0; + int error; +- int update_mode = 0; +- umode_t mode = inode->i_mode; + + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; +@@ -199,12 +197,6 @@ ext4_set_acl(handle_t *handle, struct in + switch (type) { + case ACL_TYPE_ACCESS: + name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; +- if (acl) { +- error = posix_acl_update_mode(inode, &mode, &acl); +- if (error) +- return error; +- update_mode = 1; +- } + break; + + case ACL_TYPE_DEFAULT: +@@ -228,11 +220,31 @@ ext4_set_acl(handle_t *handle, struct in + kfree(value); + if (!error) { + set_cached_acl(inode, type, acl); +- if (update_mode) { +- inode->i_mode = mode; +- inode->i_ctime = ext4_current_time(inode); +- ext4_mark_inode_dirty(handle, inode); +- } ++ } ++ ++ return error; ++} ++ ++static int ++ext4_set_acl(handle_t *handle, struct inode *inode, int type, ++ struct posix_acl *acl) ++{ ++ umode_t mode = inode->i_mode; ++ int update_mode = 0; ++ int error; ++ ++ if ((type == ACL_TYPE_ACCESS) && acl) { ++ error = posix_acl_update_mode(inode, &mode, &acl); ++ if (error) ++ return error; ++ update_mode = 1; ++ } ++ ++ error = __ext4_set_acl(handle, inode, type, acl); ++ if (!error && update_mode) { ++ inode->i_mode = mode; ++ inode->i_ctime = ext4_current_time(inode); ++ ext4_mark_inode_dirty(handle, inode); + } + + return error; +@@ -261,8 +273,8 @@ ext4_init_acl(handle_t *handle, struct i + } + if (test_opt(inode->i_sb, POSIX_ACL) && acl) { + if (S_ISDIR(inode->i_mode)) { +- error = ext4_set_acl(handle, inode, +- ACL_TYPE_DEFAULT, acl); ++ error = __ext4_set_acl(handle, inode, ++ ACL_TYPE_DEFAULT, acl); + if (error) + goto cleanup; + } +@@ -272,7 +284,7 @@ ext4_init_acl(handle_t *handle, struct i + + if (error > 0) { + /* This is an extended ACL */ +- error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); ++ error = __ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); + } + } + cleanup: diff --git a/releases/3.2.94/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch b/releases/3.2.94/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch new file mode 100644 index 00000000..4461a1b7 --- /dev/null +++ b/releases/3.2.94/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch @@ -0,0 +1,71 @@ +From: =?UTF-8?q?Ernesto=20A=2E=20Fern=C3=A1ndez?= + <ernesto.mnd.fernandez@gmail.com> +Date: Sun, 30 Jul 2017 22:43:41 -0400 +Subject: ext4: preserve i_mode if __ext4_set_acl() fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 397e434176bb62bc6068d2210af1d876c6212a7e upstream. + +When changing a file's acl mask, __ext4_set_acl() will first set the group +bits of i_mode to the value of the mask, and only then set the actual +extended attribute representing the new acl. + +If the second part fails (due to lack of space, for example) and the file +had no acl attribute to begin with, the system will from now on assume +that the mask permission bits are actual group permission bits, potentially +granting access to the wrong users. + +Prevent this by only changing the inode mode after the acl has been set. + +Signed-off-by: Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Reviewed-by: Jan Kara <jack@suse.cz> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/acl.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/fs/ext4/acl.c ++++ b/fs/ext4/acl.c +@@ -190,6 +190,8 @@ ext4_set_acl(handle_t *handle, struct in + void *value = NULL; + size_t size = 0; + int error; ++ int update_mode = 0; ++ umode_t mode = inode->i_mode; + + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; +@@ -198,11 +200,10 @@ ext4_set_acl(handle_t *handle, struct in + case ACL_TYPE_ACCESS: + name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; + if (acl) { +- error = posix_acl_update_mode(inode, &inode->i_mode, &acl); ++ error = posix_acl_update_mode(inode, &mode, &acl); + if (error) + return error; +- inode->i_ctime = ext4_current_time(inode); +- ext4_mark_inode_dirty(handle, inode); ++ update_mode = 1; + } + break; + +@@ -225,8 +226,14 @@ ext4_set_acl(handle_t *handle, struct in + value, size, 0); + + kfree(value); +- if (!error) ++ if (!error) { + set_cached_acl(inode, type, acl); ++ if (update_mode) { ++ inode->i_mode = mode; ++ inode->i_ctime = ext4_current_time(inode); ++ ext4_mark_inode_dirty(handle, inode); ++ } ++ } + + return error; + } diff --git a/releases/3.2.94/fs-dcache.c-fix-spin-lockup-issue-on-nlru-lock.patch b/releases/3.2.94/fs-dcache.c-fix-spin-lockup-issue-on-nlru-lock.patch new file mode 100644 index 00000000..b78695e5 --- /dev/null +++ b/releases/3.2.94/fs-dcache.c-fix-spin-lockup-issue-on-nlru-lock.patch @@ -0,0 +1,71 @@ +From: Sahitya Tummala <stummala@codeaurora.org> +Date: Mon, 10 Jul 2017 15:50:00 -0700 +Subject: fs/dcache.c: fix spin lockup issue on nlru->lock + +commit b17c070fb624cf10162cf92ea5e1ec25cd8ac176 upstream. + +__list_lru_walk_one() acquires nlru spin lock (nlru->lock) for longer +duration if there are more number of items in the lru list. As per the +current code, it can hold the spin lock for upto maximum UINT_MAX +entries at a time. So if there are more number of items in the lru +list, then "BUG: spinlock lockup suspected" is observed in the below +path: + + spin_bug+0x90 + do_raw_spin_lock+0xfc + _raw_spin_lock+0x28 + list_lru_add+0x28 + dput+0x1c8 + path_put+0x20 + terminate_walk+0x3c + path_lookupat+0x100 + filename_lookup+0x6c + user_path_at_empty+0x54 + SyS_faccessat+0xd0 + el0_svc_naked+0x24 + +This nlru->lock is acquired by another CPU in this path - + + d_lru_shrink_move+0x34 + dentry_lru_isolate_shrink+0x48 + __list_lru_walk_one.isra.10+0x94 + list_lru_walk_node+0x40 + shrink_dcache_sb+0x60 + do_remount_sb+0xbc + do_emergency_remount+0xb0 + process_one_work+0x228 + worker_thread+0x2e0 + kthread+0xf4 + ret_from_fork+0x10 + +Fix this lockup by reducing the number of entries to be shrinked from +the lru list to 1024 at once. Also, add cond_resched() before +processing the lru list again. + +Link: http://marc.info/?t=149722864900001&r=1&w=2 +Link: http://lkml.kernel.org/r/1498707575-2472-1-git-send-email-stummala@codeaurora.org +Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> +Suggested-by: Jan Kara <jack@suse.cz> +Suggested-by: Vladimir Davydov <vdavydov.dev@gmail.com> +Acked-by: Vladimir Davydov <vdavydov.dev@gmail.com> +Cc: Alexander Polakov <apolyakov@beget.ru> +Cc: Al Viro <viro@zeniv.linux.org.uk> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.2: we don't hold the spin-lock for long, but adding + cond_resched() looks like a good idea] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/dcache.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -836,6 +836,7 @@ void shrink_dcache_sb(struct super_block + list_splice_init(&sb->s_dentry_lru, &tmp); + spin_unlock(&dcache_lru_lock); + shrink_dentry_list(&tmp); ++ cond_resched(); + spin_lock(&dcache_lru_lock); + } + spin_unlock(&dcache_lru_lock); diff --git a/releases/3.2.94/ib-core-add-inline-function-to-validate-port.patch b/releases/3.2.94/ib-core-add-inline-function-to-validate-port.patch new file mode 100644 index 00000000..fcbdbb68 --- /dev/null +++ b/releases/3.2.94/ib-core-add-inline-function-to-validate-port.patch @@ -0,0 +1,88 @@ +From: Yuval Shaia <yuval.shaia@oracle.com> +Date: Wed, 25 Jan 2017 18:41:37 +0200 +Subject: IB/core: Add inline function to validate port + +commit 24dc831b77eca9361cf835be59fa69ea0e471afc upstream. + +Signed-off-by: Yuval Shaia <yuval.shaia@oracle.com> +Reviewed-by: Leon Romanovsky <leonro@mellanox.com> +Signed-off-by: Doug Ledford <dledford@redhat.com> +[bwh: Backported to 3.2: + - Drop inapplicable changes + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/infiniband/core/cache.c ++++ b/drivers/infiniband/core/cache.c +@@ -67,7 +67,7 @@ int ib_get_cached_gid(struct ib_device * + unsigned long flags; + int ret = 0; + +- if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) ++ if (!rdma_is_port_valid(device, port_num)) + return -EINVAL; + + read_lock_irqsave(&device->cache.lock, flags); +@@ -129,7 +129,7 @@ int ib_get_cached_pkey(struct ib_device + unsigned long flags; + int ret = 0; + +- if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) ++ if (!rdma_is_port_valid(device, port_num)) + return -EINVAL; + + read_lock_irqsave(&device->cache.lock, flags); +@@ -157,7 +157,7 @@ int ib_find_cached_pkey(struct ib_device + int i; + int ret = -ENOENT; + +- if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) ++ if (!rdma_is_port_valid(device, port_num)) + return -EINVAL; + + read_lock_irqsave(&device->cache.lock, flags); +@@ -186,7 +186,7 @@ int ib_get_cached_lmc(struct ib_device * + unsigned long flags; + int ret = 0; + +- if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) ++ if (!rdma_is_port_valid(device, port_num)) + return -EINVAL; + + read_lock_irqsave(&device->cache.lock, flags); +--- a/drivers/infiniband/core/device.c ++++ b/drivers/infiniband/core/device.c +@@ -563,7 +563,7 @@ int ib_query_port(struct ib_device *devi + u8 port_num, + struct ib_port_attr *port_attr) + { +- if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) ++ if (!rdma_is_port_valid(device, port_num)) + return -EINVAL; + + return device->query_port(device, port_num, port_attr); +@@ -641,7 +641,7 @@ int ib_modify_port(struct ib_device *dev + if (!device->modify_port) + return -ENOSYS; + +- if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) ++ if (!rdma_is_port_valid(device, port_num)) + return -EINVAL; + + return device->modify_port(device, port_num, port_modify_mask, +--- a/include/rdma/ib_verbs.h ++++ b/include/rdma/ib_verbs.h +@@ -1335,6 +1335,13 @@ static inline u8 rdma_end_port(const str + 0 : device->phys_port_cnt; + } + ++static inline int rdma_is_port_valid(const struct ib_device *device, ++ unsigned int port) ++{ ++ return (port >= rdma_start_port(device) && ++ port <= rdma_end_port(device)); ++} ++ + int ib_query_gid(struct ib_device *device, + u8 port_num, int index, union ib_gid *gid); + diff --git a/releases/3.2.94/ib-core-create-common-start-end-port-functions.patch b/releases/3.2.94/ib-core-create-common-start-end-port-functions.patch new file mode 100644 index 00000000..728471bf --- /dev/null +++ b/releases/3.2.94/ib-core-create-common-start-end-port-functions.patch @@ -0,0 +1,292 @@ +From: Ira Weiny <ira.weiny@intel.com> +Date: Wed, 13 May 2015 20:02:55 -0400 +Subject: IB/core: Create common start/end port functions + +commit 0cf18d7723055709faf51b50f5a33253b480637f upstream. + +Previously start_port and end_port were defined in 2 places, cache.c and +device.c and this prevented their use in other modules. + +Make these common functions, change the name to reflect the rdma +name space, and update existing users. + +Signed-off-by: Ira Weiny <ira.weiny@intel.com> +Signed-off-by: Doug Ledford <dledford@redhat.com> +[bwh: Backported to 3.2: drop one inapplicable change] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/infiniband/core/cache.c ++++ b/drivers/infiniband/core/cache.c +@@ -58,17 +58,6 @@ struct ib_update_work { + u8 port_num; + }; + +-static inline int start_port(struct ib_device *device) +-{ +- return (device->node_type == RDMA_NODE_IB_SWITCH) ? 0 : 1; +-} +- +-static inline int end_port(struct ib_device *device) +-{ +- return (device->node_type == RDMA_NODE_IB_SWITCH) ? +- 0 : device->phys_port_cnt; +-} +- + int ib_get_cached_gid(struct ib_device *device, + u8 port_num, + int index, +@@ -78,12 +67,12 @@ int ib_get_cached_gid(struct ib_device * + unsigned long flags; + int ret = 0; + +- if (port_num < start_port(device) || port_num > end_port(device)) ++ if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) + return -EINVAL; + + read_lock_irqsave(&device->cache.lock, flags); + +- cache = device->cache.gid_cache[port_num - start_port(device)]; ++ cache = device->cache.gid_cache[port_num - rdma_start_port(device)]; + + if (index < 0 || index >= cache->table_len) + ret = -EINVAL; +@@ -112,11 +101,11 @@ int ib_find_cached_gid(struct ib_device + + read_lock_irqsave(&device->cache.lock, flags); + +- for (p = 0; p <= end_port(device) - start_port(device); ++p) { ++ for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p) { + cache = device->cache.gid_cache[p]; + for (i = 0; i < cache->table_len; ++i) { + if (!memcmp(gid, &cache->table[i], sizeof *gid)) { +- *port_num = p + start_port(device); ++ *port_num = p + rdma_start_port(device); + if (index) + *index = i; + ret = 0; +@@ -140,12 +129,12 @@ int ib_get_cached_pkey(struct ib_device + unsigned long flags; + int ret = 0; + +- if (port_num < start_port(device) || port_num > end_port(device)) ++ if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) + return -EINVAL; + + read_lock_irqsave(&device->cache.lock, flags); + +- cache = device->cache.pkey_cache[port_num - start_port(device)]; ++ cache = device->cache.pkey_cache[port_num - rdma_start_port(device)]; + + if (index < 0 || index >= cache->table_len) + ret = -EINVAL; +@@ -168,12 +157,12 @@ int ib_find_cached_pkey(struct ib_device + int i; + int ret = -ENOENT; + +- if (port_num < start_port(device) || port_num > end_port(device)) ++ if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) + return -EINVAL; + + read_lock_irqsave(&device->cache.lock, flags); + +- cache = device->cache.pkey_cache[port_num - start_port(device)]; ++ cache = device->cache.pkey_cache[port_num - rdma_start_port(device)]; + + *index = -1; + +@@ -197,11 +186,11 @@ int ib_get_cached_lmc(struct ib_device * + unsigned long flags; + int ret = 0; + +- if (port_num < start_port(device) || port_num > end_port(device)) ++ if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) + return -EINVAL; + + read_lock_irqsave(&device->cache.lock, flags); +- *lmc = device->cache.lmc_cache[port_num - start_port(device)]; ++ *lmc = device->cache.lmc_cache[port_num - rdma_start_port(device)]; + read_unlock_irqrestore(&device->cache.lock, flags); + + return ret; +@@ -262,13 +251,13 @@ static void ib_cache_update(struct ib_de + + write_lock_irq(&device->cache.lock); + +- old_pkey_cache = device->cache.pkey_cache[port - start_port(device)]; +- old_gid_cache = device->cache.gid_cache [port - start_port(device)]; ++ old_pkey_cache = device->cache.pkey_cache[port - rdma_start_port(device)]; ++ old_gid_cache = device->cache.gid_cache [port - rdma_start_port(device)]; + +- device->cache.pkey_cache[port - start_port(device)] = pkey_cache; +- device->cache.gid_cache [port - start_port(device)] = gid_cache; ++ device->cache.pkey_cache[port - rdma_start_port(device)] = pkey_cache; ++ device->cache.gid_cache [port - rdma_start_port(device)] = gid_cache; + +- device->cache.lmc_cache[port - start_port(device)] = tprops->lmc; ++ device->cache.lmc_cache[port - rdma_start_port(device)] = tprops->lmc; + + write_unlock_irq(&device->cache.lock); + +@@ -322,14 +311,14 @@ static void ib_cache_setup_one(struct ib + + device->cache.pkey_cache = + kmalloc(sizeof *device->cache.pkey_cache * +- (end_port(device) - start_port(device) + 1), GFP_KERNEL); ++ (rdma_end_port(device) - rdma_start_port(device) + 1), GFP_KERNEL); + device->cache.gid_cache = + kmalloc(sizeof *device->cache.gid_cache * +- (end_port(device) - start_port(device) + 1), GFP_KERNEL); ++ (rdma_end_port(device) - rdma_start_port(device) + 1), GFP_KERNEL); + + device->cache.lmc_cache = kmalloc(sizeof *device->cache.lmc_cache * +- (end_port(device) - +- start_port(device) + 1), ++ (rdma_end_port(device) - ++ rdma_start_port(device) + 1), + GFP_KERNEL); + + if (!device->cache.pkey_cache || !device->cache.gid_cache || +@@ -339,10 +328,10 @@ static void ib_cache_setup_one(struct ib + goto err; + } + +- for (p = 0; p <= end_port(device) - start_port(device); ++p) { ++ for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p) { + device->cache.pkey_cache[p] = NULL; + device->cache.gid_cache [p] = NULL; +- ib_cache_update(device, p + start_port(device)); ++ ib_cache_update(device, p + rdma_start_port(device)); + } + + INIT_IB_EVENT_HANDLER(&device->cache.event_handler, +@@ -353,7 +342,7 @@ static void ib_cache_setup_one(struct ib + return; + + err_cache: +- for (p = 0; p <= end_port(device) - start_port(device); ++p) { ++ for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p) { + kfree(device->cache.pkey_cache[p]); + kfree(device->cache.gid_cache[p]); + } +@@ -371,7 +360,7 @@ static void ib_cache_cleanup_one(struct + ib_unregister_event_handler(&device->cache.event_handler); + flush_workqueue(ib_wq); + +- for (p = 0; p <= end_port(device) - start_port(device); ++p) { ++ for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p) { + kfree(device->cache.pkey_cache[p]); + kfree(device->cache.gid_cache[p]); + } +--- a/drivers/infiniband/core/device.c ++++ b/drivers/infiniband/core/device.c +@@ -151,18 +151,6 @@ static int alloc_name(char *name) + return 0; + } + +-static int start_port(struct ib_device *device) +-{ +- return (device->node_type == RDMA_NODE_IB_SWITCH) ? 0 : 1; +-} +- +- +-static int end_port(struct ib_device *device) +-{ +- return (device->node_type == RDMA_NODE_IB_SWITCH) ? +- 0 : device->phys_port_cnt; +-} +- + /** + * ib_alloc_device - allocate an IB device struct + * @size:size of structure to allocate +@@ -232,7 +220,7 @@ static int read_port_table_lengths(struc + if (!tprops) + goto out; + +- num_ports = end_port(device) - start_port(device) + 1; ++ num_ports = rdma_end_port(device) - rdma_start_port(device) + 1; + + device->pkey_tbl_len = kmalloc(sizeof *device->pkey_tbl_len * num_ports, + GFP_KERNEL); +@@ -242,7 +230,7 @@ static int read_port_table_lengths(struc + goto err; + + for (port_index = 0; port_index < num_ports; ++port_index) { +- ret = ib_query_port(device, port_index + start_port(device), ++ ret = ib_query_port(device, port_index + rdma_start_port(device), + tprops); + if (ret) + goto err; +@@ -575,7 +563,7 @@ int ib_query_port(struct ib_device *devi + u8 port_num, + struct ib_port_attr *port_attr) + { +- if (port_num < start_port(device) || port_num > end_port(device)) ++ if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) + return -EINVAL; + + return device->query_port(device, port_num, port_attr); +@@ -653,7 +641,7 @@ int ib_modify_port(struct ib_device *dev + if (!device->modify_port) + return -ENOSYS; + +- if (port_num < start_port(device) || port_num > end_port(device)) ++ if (port_num < rdma_start_port(device) || port_num > rdma_end_port(device)) + return -EINVAL; + + return device->modify_port(device, port_num, port_modify_mask, +@@ -676,8 +664,8 @@ int ib_find_gid(struct ib_device *device + union ib_gid tmp_gid; + int ret, port, i; + +- for (port = start_port(device); port <= end_port(device); ++port) { +- for (i = 0; i < device->gid_tbl_len[port - start_port(device)]; ++i) { ++ for (port = rdma_start_port(device); port <= rdma_end_port(device); ++port) { ++ for (i = 0; i < device->gid_tbl_len[port - rdma_start_port(device)]; ++i) { + ret = ib_query_gid(device, port, i, &tmp_gid); + if (ret) + return ret; +@@ -708,7 +696,7 @@ int ib_find_pkey(struct ib_device *devic + int ret, i; + u16 tmp_pkey; + +- for (i = 0; i < device->pkey_tbl_len[port_num - start_port(device)]; ++i) { ++ for (i = 0; i < device->pkey_tbl_len[port_num - rdma_start_port(device)]; ++i) { + ret = ib_query_pkey(device, port_num, i, &tmp_pkey); + if (ret) + return ret; +--- a/include/rdma/ib_verbs.h ++++ b/include/rdma/ib_verbs.h +@@ -1308,6 +1308,33 @@ int ib_query_port(struct ib_device *devi + enum rdma_link_layer rdma_port_get_link_layer(struct ib_device *device, + u8 port_num); + ++/** ++ * rdma_start_port - Return the first valid port number for the device ++ * specified ++ * ++ * @device: Device to be checked ++ * ++ * Return start port number ++ */ ++static inline u8 rdma_start_port(const struct ib_device *device) ++{ ++ return (device->node_type == RDMA_NODE_IB_SWITCH) ? 0 : 1; ++} ++ ++/** ++ * rdma_end_port - Return the last valid port number for the device ++ * specified ++ * ++ * @device: Device to be checked ++ * ++ * Return last port number ++ */ ++static inline u8 rdma_end_port(const struct ib_device *device) ++{ ++ return (device->node_type == RDMA_NODE_IB_SWITCH) ? ++ 0 : device->phys_port_cnt; ++} ++ + int ib_query_gid(struct ib_device *device, + u8 port_num, int index, union ib_gid *gid); + diff --git a/releases/3.2.94/input-i8042-fix-crash-at-boot-time.patch b/releases/3.2.94/input-i8042-fix-crash-at-boot-time.patch new file mode 100644 index 00000000..0a52ea9f --- /dev/null +++ b/releases/3.2.94/input-i8042-fix-crash-at-boot-time.patch @@ -0,0 +1,117 @@ +From: Chen Hong <chenhong3@huawei.com> +Date: Sun, 2 Jul 2017 15:11:10 -0700 +Subject: Input: i8042 - fix crash at boot time + +commit 340d394a789518018f834ff70f7534fc463d3226 upstream. + +The driver checks port->exists twice in i8042_interrupt(), first when +trying to assign temporary "serio" variable, and second time when deciding +whether it should call serio_interrupt(). The value of port->exists may +change between the 2 checks, and we may end up calling serio_interrupt() +with a NULL pointer: + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000050 +IP: [<ffffffff8150feaf>] _spin_lock_irqsave+0x1f/0x40 +PGD 0 +Oops: 0002 [#1] SMP +last sysfs file: +CPU 0 +Modules linked in: + +Pid: 1, comm: swapper Not tainted 2.6.32-358.el6.x86_64 #1 QEMU Standard PC (i440FX + PIIX, 1996) +RIP: 0010:[<ffffffff8150feaf>] [<ffffffff8150feaf>] _spin_lock_irqsave+0x1f/0x40 +RSP: 0018:ffff880028203cc0 EFLAGS: 00010082 +RAX: 0000000000010000 RBX: 0000000000000000 RCX: 0000000000000000 +RDX: 0000000000000282 RSI: 0000000000000098 RDI: 0000000000000050 +RBP: ffff880028203cc0 R08: ffff88013e79c000 R09: ffff880028203ee0 +R10: 0000000000000298 R11: 0000000000000282 R12: 0000000000000050 +R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000098 +FS: 0000000000000000(0000) GS:ffff880028200000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b +CR2: 0000000000000050 CR3: 0000000001a85000 CR4: 00000000001407f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +Process swapper (pid: 1, threadinfo ffff88013e79c000, task ffff88013e79b500) +Stack: +ffff880028203d00 ffffffff813de186 ffffffffffffff02 0000000000000000 +<d> 0000000000000000 0000000000000000 0000000000000000 0000000000000098 +<d> ffff880028203d70 ffffffff813e0162 ffff880028203d20 ffffffff8103b8ac +Call Trace: +<IRQ> + [<ffffffff813de186>] serio_interrupt+0x36/0xa0 +[<ffffffff813e0162>] i8042_interrupt+0x132/0x3a0 +[<ffffffff8103b8ac>] ? kvm_clock_read+0x1c/0x20 +[<ffffffff8103b8b9>] ? kvm_clock_get_cycles+0x9/0x10 +[<ffffffff810e1640>] handle_IRQ_event+0x60/0x170 +[<ffffffff8103b154>] ? kvm_guest_apic_eoi_write+0x44/0x50 +[<ffffffff810e3d8e>] handle_edge_irq+0xde/0x180 +[<ffffffff8100de89>] handle_irq+0x49/0xa0 +[<ffffffff81516c8c>] do_IRQ+0x6c/0xf0 +[<ffffffff8100b9d3>] ret_from_intr+0x0/0x11 +[<ffffffff81076f63>] ? __do_softirq+0x73/0x1e0 +[<ffffffff8109b75b>] ? hrtimer_interrupt+0x14b/0x260 +[<ffffffff8100c1cc>] ? call_softirq+0x1c/0x30 +[<ffffffff8100de05>] ? do_softirq+0x65/0xa0 +[<ffffffff81076d95>] ? irq_exit+0x85/0x90 +[<ffffffff81516d80>] ? smp_apic_timer_interrupt+0x70/0x9b +[<ffffffff8100bb93>] ? apic_timer_interrupt+0x13/0x20 + +To avoid the issue let's change the second check to test whether serio is +NULL or not. + +Also, let's take i8042_lock in i8042_start() and i8042_stop() instead of +trying to be overly smart and using memory barriers. + +Signed-off-by: Chen Hong <chenhong3@huawei.com> +[dtor: take lock in i8042_start()/i8042_stop()] +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/input/serio/i8042.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/drivers/input/serio/i8042.c ++++ b/drivers/input/serio/i8042.c +@@ -390,8 +390,10 @@ static int i8042_start(struct serio *ser + { + struct i8042_port *port = serio->port_data; + ++ spin_lock_irq(&i8042_lock); + port->exists = true; +- mb(); ++ spin_unlock_irq(&i8042_lock); ++ + return 0; + } + +@@ -404,16 +406,20 @@ static void i8042_stop(struct serio *ser + { + struct i8042_port *port = serio->port_data; + ++ spin_lock_irq(&i8042_lock); + port->exists = false; ++ port->serio = NULL; ++ spin_unlock_irq(&i8042_lock); + + /* ++ * We need to make sure that interrupt handler finishes using ++ * our serio port before we return from this function. + * We synchronize with both AUX and KBD IRQs because there is + * a (very unlikely) chance that AUX IRQ is raised for KBD port + * and vice versa. + */ + synchronize_irq(I8042_AUX_IRQ); + synchronize_irq(I8042_KBD_IRQ); +- port->serio = NULL; + } + + /* +@@ -530,7 +536,7 @@ static irqreturn_t i8042_interrupt(int i + + spin_unlock_irqrestore(&i8042_lock, flags); + +- if (likely(port->exists && !filtered)) ++ if (likely(serio && !filtered)) + serio_interrupt(serio, data, dfl); + + out: diff --git a/releases/3.2.94/ipv6-always-add-flag-an-address-that-failed-dad-with-dadfailed.patch b/releases/3.2.94/ipv6-always-add-flag-an-address-that-failed-dad-with-dadfailed.patch new file mode 100644 index 00000000..100d2a34 --- /dev/null +++ b/releases/3.2.94/ipv6-always-add-flag-an-address-that-failed-dad-with-dadfailed.patch @@ -0,0 +1,40 @@ +From: Lubomir Rintel <lkundrak@v3.sk> +Date: Fri, 8 Jan 2016 13:47:23 +0100 +Subject: ipv6: always add flag an address that failed DAD with DADFAILED + +commit 3d171f3907329d4b1ce31d5ec9c852c5f0269578 upstream. + +The userspace needs to know why is the address being removed so that it can +perhaps obtain a new address. + +Without the DADFAILED flag it's impossible to distinguish removal of a +temporary and tentative address due to DAD failure from other reasons (device +removed, manual address removal). + +Signed-off-by: Lubomir Rintel <lkundrak@v3.sk> +Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/ipv6/addrconf.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1382,12 +1382,13 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str + + static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed) + { ++ if (dad_failed) ++ ifp->flags |= IFA_F_DADFAILED; ++ + if (ifp->flags&IFA_F_PERMANENT) { + spin_lock_bh(&ifp->lock); + addrconf_del_timer(ifp); + ifp->flags |= IFA_F_TENTATIVE; +- if (dad_failed) +- ifp->flags |= IFA_F_DADFAILED; + spin_unlock_bh(&ifp->lock); + if (dad_failed) + ipv6_ifa_notify(0, ifp); diff --git a/releases/3.2.94/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch b/releases/3.2.94/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch new file mode 100644 index 00000000..86dcb986 --- /dev/null +++ b/releases/3.2.94/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch @@ -0,0 +1,76 @@ +From: Sabrina Dubroca <sd@queasysnail.net> +Date: Thu, 29 Jun 2017 16:56:54 +0200 +Subject: ipv6: dad: don't remove dynamic addresses if link is down + +commit ec8add2a4c9df723c94a863b8fcd6d93c472deed upstream. + +Currently, when the link for $DEV is down, this command succeeds but the +address is removed immediately by DAD (1): + + ip addr add 1111::12/64 dev $DEV valid_lft 3600 preferred_lft 1800 + +In the same situation, this will succeed and not remove the address (2): + + ip addr add 1111::12/64 dev $DEV + ip addr change 1111::12/64 dev $DEV valid_lft 3600 preferred_lft 1800 + +The comment in addrconf_dad_begin() when !IF_READY makes it look like +this is the intended behavior, but doesn't explain why: + + * If the device is not ready: + * - keep it tentative if it is a permanent address. + * - otherwise, kill it. + +We clearly cannot prevent userspace from doing (2), but we can make (1) +work consistently with (2). + +addrconf_dad_stop() is only called in two cases: if DAD failed, or to +skip DAD when the link is down. In that second case, the fix is to avoid +deleting the address, like we already do for permanent addresses. + +Fixes: 3c21edbd1137 ("[IPV6]: Defer IPv6 device initialization until the link becomes ready.") +Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/ipv6/addrconf.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1385,16 +1385,8 @@ static void addrconf_dad_stop(struct ine + if (dad_failed) + ifp->flags |= IFA_F_DADFAILED; + +- if (ifp->flags&IFA_F_PERMANENT) { +- spin_lock_bh(&ifp->lock); +- addrconf_del_timer(ifp); +- ifp->flags |= IFA_F_TENTATIVE; +- spin_unlock_bh(&ifp->lock); +- if (dad_failed) +- ipv6_ifa_notify(0, ifp); +- in6_ifa_put(ifp); + #ifdef CONFIG_IPV6_PRIVACY +- } else if (ifp->flags&IFA_F_TEMPORARY) { ++ if (ifp->flags&IFA_F_TEMPORARY) { + struct inet6_ifaddr *ifpub; + spin_lock_bh(&ifp->lock); + ifpub = ifp->ifpub; +@@ -1407,7 +1399,16 @@ static void addrconf_dad_stop(struct ine + spin_unlock_bh(&ifp->lock); + } + ipv6_del_addr(ifp); ++ } else + #endif ++ if (ifp->flags&IFA_F_PERMANENT || !dad_failed) { ++ spin_lock_bh(&ifp->lock); ++ addrconf_del_timer(ifp); ++ ifp->flags |= IFA_F_TENTATIVE; ++ spin_unlock_bh(&ifp->lock); ++ if (dad_failed) ++ ipv6_ifa_notify(0, ifp); ++ in6_ifa_put(ifp); + } else + ipv6_del_addr(ifp); + } diff --git a/releases/3.2.94/kvm-nvmx-don-t-allow-l2-to-access-the-hardware-cr8.patch b/releases/3.2.94/kvm-nvmx-don-t-allow-l2-to-access-the-hardware-cr8.patch new file mode 100644 index 00000000..37d16117 --- /dev/null +++ b/releases/3.2.94/kvm-nvmx-don-t-allow-l2-to-access-the-hardware-cr8.patch @@ -0,0 +1,36 @@ +From: Jim Mattson <jmattson@google.com> +Date: Tue, 12 Sep 2017 13:02:54 -0700 +Subject: kvm: nVMX: Don't allow L2 to access the hardware CR8 + +commit 51aa68e7d57e3217192d88ce90fd5b8ef29ec94f upstream. + +If L1 does not specify the "use TPR shadow" VM-execution control in +vmcs12, then L0 must specify the "CR8-load exiting" and "CR8-store +exiting" VM-execution controls in vmcs02. Failure to do so will give +the L2 VM unrestricted read/write access to the hardware CR8. + +This fixes CVE-2017-12154. + +Signed-off-by: Jim Mattson <jmattson@google.com> +Reviewed-by: David Hildenbrand <david@redhat.com> +Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -6671,6 +6671,14 @@ static void prepare_vmcs02(struct kvm_vc + exec_control &= ~CPU_BASED_VIRTUAL_NMI_PENDING; + exec_control &= ~CPU_BASED_TPR_SHADOW; + exec_control |= vmcs12->cpu_based_vm_exec_control; ++ ++ if (!(exec_control & CPU_BASED_TPR_SHADOW)) { ++#ifdef CONFIG_X86_64 ++ exec_control |= CPU_BASED_CR8_LOAD_EXITING | ++ CPU_BASED_CR8_STORE_EXITING; ++#endif ++ } ++ + /* + * Merging of IO and MSR bitmaps not currently supported. + * Rather, exit every time. diff --git a/releases/3.2.94/l2tp-avoid-use-after-free-caused-by-l2tp_ip_backlog_recv.patch b/releases/3.2.94/l2tp-avoid-use-after-free-caused-by-l2tp_ip_backlog_recv.patch new file mode 100644 index 00000000..b832e5af --- /dev/null +++ b/releases/3.2.94/l2tp-avoid-use-after-free-caused-by-l2tp_ip_backlog_recv.patch @@ -0,0 +1,31 @@ +From: =?UTF-8?q?Paul=20H=C3=BCber?= <phueber@kernsp.in> +Date: Sun, 26 Feb 2017 17:58:19 +0100 +Subject: l2tp: avoid use-after-free caused by l2tp_ip_backlog_recv +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 51fb60eb162ab84c5edf2ae9c63cf0b878e5547e upstream. + +l2tp_ip_backlog_recv may not return -1 if the packet gets dropped. +The return value is passed up to ip_local_deliver_finish, which treats +negative values as an IP protocol number for resubmission. + +Signed-off-by: Paul Hüber <phueber@kernsp.in> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/l2tp/l2tp_ip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -432,7 +432,7 @@ static int l2tp_ip_backlog_recv(struct s + drop: + IP_INC_STATS(&init_net, IPSTATS_MIB_INDISCARDS); + kfree_skb(skb); +- return -1; ++ return 0; + } + + /* Userspace will call sendmsg() on the tunnel socket to send L2TP diff --git a/releases/3.2.94/m32r-add-definition-of-ioremap_wc-to-io.h.patch b/releases/3.2.94/m32r-add-definition-of-ioremap_wc-to-io.h.patch new file mode 100644 index 00000000..0e6d9c29 --- /dev/null +++ b/releases/3.2.94/m32r-add-definition-of-ioremap_wc-to-io.h.patch @@ -0,0 +1,28 @@ +From: Abhilash Kesavan <a.kesavan@samsung.com> +Date: Fri, 6 Feb 2015 19:15:26 +0530 +Subject: m32r: add definition of ioremap_wc to io.h + +commit 71a49d16f06de2ccdf52ca247d496a2bb1ca36fe upstream. + +Before adding a resource managed ioremap_wc function, we need +to have ioremap_wc defined for m32r to prevent build errors. + +Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> +Acked-by: Catalin Marinas <catalin.marinas@arm.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: Sudip Mukherjee <sudipm.mukherjee@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/m32r/include/asm/io.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/m32r/include/asm/io.h ++++ b/arch/m32r/include/asm/io.h +@@ -67,6 +67,7 @@ static inline void __iomem *ioremap(unsi + + extern void iounmap(volatile void __iomem *addr); + #define ioremap_nocache(off,size) ioremap(off,size) ++#define ioremap_wc ioremap_nocache + + /* + * IO bus memory addresses are also 1:1 with the physical address diff --git a/releases/3.2.94/m32r-add-io-_rep-helpers.patch b/releases/3.2.94/m32r-add-io-_rep-helpers.patch new file mode 100644 index 00000000..f9158bc0 --- /dev/null +++ b/releases/3.2.94/m32r-add-io-_rep-helpers.patch @@ -0,0 +1,49 @@ +From: Sudip Mukherjee <sudipm.mukherjee@gmail.com> +Date: Tue, 29 Dec 2015 14:54:19 -0800 +Subject: m32r: add io*_rep helpers + +commit 92a8ed4c7643809123ef0a65424569eaacc5c6b0 upstream. + +m32r allmodconfig was failing with the error: + + error: implicit declaration of function 'read' + +On checking io.h it turned out that 'read' is not defined but 'readb' is +defined and 'ioread8' will then obviously mean 'readb'. + +At the same time some of the helper functions ioreadN_rep() and +iowriteN_rep() were missing which also led to the build failure. + +Signed-off-by: Sudip Mukherjee <sudip@vectorindia.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/m32r/include/asm/io.h | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/arch/m32r/include/asm/io.h ++++ b/arch/m32r/include/asm/io.h +@@ -163,13 +163,21 @@ static inline void _writel(unsigned long + #define __raw_writew writew + #define __raw_writel writel + +-#define ioread8 read ++#define ioread8 readb + #define ioread16 readw + #define ioread32 readl + #define iowrite8 writeb + #define iowrite16 writew + #define iowrite32 writel + ++#define ioread8_rep(p, dst, count) insb((unsigned long)(p), (dst), (count)) ++#define ioread16_rep(p, dst, count) insw((unsigned long)(p), (dst), (count)) ++#define ioread32_rep(p, dst, count) insl((unsigned long)(p), (dst), (count)) ++ ++#define iowrite8_rep(p, src, count) outsb((unsigned long)(p), (src), (count)) ++#define iowrite16_rep(p, src, count) outsw((unsigned long)(p), (src), (count)) ++#define iowrite32_rep(p, src, count) outsl((unsigned long)(p), (src), (count)) ++ + #define mmiowb() + + #define flush_write_buffers() do { } while (0) /* M32R_FIXME */ diff --git a/releases/3.2.94/mceusb-fix-memory-leaks-in-error-path.patch b/releases/3.2.94/mceusb-fix-memory-leaks-in-error-path.patch new file mode 100644 index 00000000..8d40ffbf --- /dev/null +++ b/releases/3.2.94/mceusb-fix-memory-leaks-in-error-path.patch @@ -0,0 +1,41 @@ +From: Johan Hovold <johan@kernel.org> +Date: Thu, 1 Jun 2017 04:45:59 -0300 +Subject: [media] mceusb: fix memory leaks in error path + +commit 2d5a6ce71c72d98d4f7948672842e3e8c265a8b7 upstream. + +Fix urb and transfer-buffer leaks in an urb-submission error path which +may be hit when a device is disconnected. + +Fixes: 66e89522aff7 ("V4L/DVB: IR: add mceusb IR receiver driver") + +Cc: Jarod Wilson <jarod@redhat.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Sean Young <sean@mess.org> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> +[bwh: Backported to 3.2: + - Add check on urb_type, as async_buf and async_urb aren't always allocated + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/media/rc/mceusb.c ++++ b/drivers/media/rc/mceusb.c +@@ -739,6 +739,7 @@ static void mce_request_packet(struct mc + } else if (urb_type == MCEUSB_RX) { + /* standard request */ + async_urb = ir->urb_in; ++ async_buf = NULL; + ir->send_flags = RECV_FLAG_IN_PROGRESS; + + } else { +@@ -754,6 +755,10 @@ static void mce_request_packet(struct mc + res = usb_submit_urb(async_urb, GFP_ATOMIC); + if (res) { + mce_dbg(dev, "receive request FAILED! (res=%d)\n", res); ++ if (urb_type == MCEUSB_TX) { ++ kfree(async_buf); ++ usb_free_urb(async_urb); ++ } + return; + } + mce_dbg(dev, "receive request complete (res=%d)\n", res); diff --git a/releases/3.2.94/md-don-t-use-flush_signals-in-userspace-processes.patch b/releases/3.2.94/md-don-t-use-flush_signals-in-userspace-processes.patch new file mode 100644 index 00000000..7830284c --- /dev/null +++ b/releases/3.2.94/md-don-t-use-flush_signals-in-userspace-processes.patch @@ -0,0 +1,65 @@ +From: Mikulas Patocka <mpatocka@redhat.com> +Date: Wed, 7 Jun 2017 19:05:31 -0400 +Subject: md: don't use flush_signals in userspace processes + +commit f9c79bc05a2a91f4fba8bfd653579e066714b1ec upstream. + +The function flush_signals clears all pending signals for the process. It +may be used by kernel threads when we need to prepare a kernel thread for +responding to signals. However using this function for an userspaces +processes is incorrect - clearing signals without the program expecting it +can cause misbehavior. + +The raid1 and raid5 code uses flush_signals in its request routine because +it wants to prepare for an interruptible wait. This patch drops +flush_signals and uses sigprocmask instead to block all signals (including +SIGKILL) around the schedule() call. The signals are not lost, but the +schedule() call won't respond to them. + +Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> +Acked-by: NeilBrown <neilb@suse.com> +Signed-off-by: Shaohua Li <shli@fb.com> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -875,13 +875,16 @@ static void make_request(struct mddev *m + */ + DEFINE_WAIT(w); + for (;;) { +- flush_signals(current); ++ sigset_t full, old; + prepare_to_wait(&conf->wait_barrier, + &w, TASK_INTERRUPTIBLE); + if (bio->bi_sector + bio->bi_size/512 <= mddev->suspend_lo || + bio->bi_sector >= mddev->suspend_hi) + break; ++ sigfillset(&full); ++ sigprocmask(SIG_BLOCK, &full, &old); + schedule(); ++ sigprocmask(SIG_SETMASK, &old, NULL); + } + finish_wait(&conf->wait_barrier, &w); + } +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -3823,12 +3823,16 @@ static void make_request(struct mddev *m + * userspace, we want an interruptible + * wait. + */ +- flush_signals(current); + prepare_to_wait(&conf->wait_for_overlap, + &w, TASK_INTERRUPTIBLE); + if (logical_sector >= mddev->suspend_lo && +- logical_sector < mddev->suspend_hi) ++ logical_sector < mddev->suspend_hi) { ++ sigset_t full, old; ++ sigfillset(&full); ++ sigprocmask(SIG_BLOCK, &full, &old); + schedule(); ++ sigprocmask(SIG_SETMASK, &old, NULL); ++ } + goto retry; + } + diff --git a/releases/3.2.94/mips-fix-mips_atomic_set-retry-condition.patch b/releases/3.2.94/mips-fix-mips_atomic_set-retry-condition.patch new file mode 100644 index 00000000..555ba12c --- /dev/null +++ b/releases/3.2.94/mips-fix-mips_atomic_set-retry-condition.patch @@ -0,0 +1,36 @@ +From: James Hogan <james.hogan@imgtec.com> +Date: Wed, 31 May 2017 16:19:47 +0100 +Subject: MIPS: Fix mips_atomic_set() retry condition + +commit 2ec420b26f7b6ff332393f0bb5a7d245f7ad87f0 upstream. + +The inline asm retry check in the MIPS_ATOMIC_SET operation of the +sysmips system call has been backwards since commit f1e39a4a616c ("MIPS: +Rewrite sysmips(MIPS_ATOMIC_SET, ...) in C with inline assembler") +merged in v2.6.32, resulting in the non R10000_LLSC_WAR case retrying +until the operation was inatomic, before returning the new value that +was probably just written multiple times instead of the old value. + +Invert the branch condition to fix that particular issue. + +Fixes: f1e39a4a616c ("MIPS: Rewrite sysmips(MIPS_ATOMIC_SET, ...) in C with inline assembler") +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/16148/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/mips/kernel/syscall.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/mips/kernel/syscall.c ++++ b/arch/mips/kernel/syscall.c +@@ -203,7 +203,7 @@ static inline int mips_atomic_set(struct + "1: ll %[old], (%[addr]) \n" + " move %[tmp], %[new] \n" + "2: sc %[tmp], (%[addr]) \n" +- " bnez %[tmp], 4f \n" ++ " beqz %[tmp], 4f \n" + "3: \n" + " .subsection 2 \n" + "4: b 1b \n" diff --git a/releases/3.2.94/mips-refactor-clear_page-and-copy_page-functions.patch b/releases/3.2.94/mips-refactor-clear_page-and-copy_page-functions.patch new file mode 100644 index 00000000..fde336f0 --- /dev/null +++ b/releases/3.2.94/mips-refactor-clear_page-and-copy_page-functions.patch @@ -0,0 +1,253 @@ +From: "Steven J. Hill" <sjhill@mips.com> +Date: Fri, 6 Jul 2012 21:56:01 +0200 +Subject: MIPS: Refactor 'clear_page' and 'copy_page' functions. + +commit c022630633624a75b3b58f43dd3c6cc896a56cff upstream. + +Remove usage of the '__attribute__((alias("...")))' hack that aliased +to integer arrays containing micro-assembled instructions. This hack +breaks when building a microMIPS kernel. It also makes the code much +easier to understand. + +[ralf@linux-mips.org: Added back export of the clear_page and copy_page +symbols so certain modules will work again. Also fixed build with +CONFIG_SIBYTE_DMA_PAGEOPS enabled.] + +Signed-off-by: Steven J. Hill <sjhill@mips.com> +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3866/ +Acked-by: David Daney <david.daney@cavium.com> +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +[bwh: Backported to 3.2: adjust context] +Cc: Guenter Roeck <linux@roeck-us.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/mips/kernel/mips_ksyms.c | 8 +++++- + arch/mips/mm/Makefile | 4 +-- + arch/mips/mm/page-funcs.S | 50 ++++++++++++++++++++++++++++++++ + arch/mips/mm/page.c | 67 ++++++++++++------------------------------- + 4 files changed, 77 insertions(+), 52 deletions(-) + create mode 100644 arch/mips/mm/page-funcs.S + +--- a/arch/mips/kernel/mips_ksyms.c ++++ b/arch/mips/kernel/mips_ksyms.c +@@ -5,7 +5,7 @@ + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * +- * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05 by Ralf Baechle ++ * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05, 12 by Ralf Baechle + * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. + */ + #include <linux/interrupt.h> +@@ -35,6 +35,12 @@ EXPORT_SYMBOL(memmove); + EXPORT_SYMBOL(kernel_thread); + + /* ++ * Functions that operate on entire pages. Mostly used by memory management. ++ */ ++EXPORT_SYMBOL(clear_page); ++EXPORT_SYMBOL(copy_page); ++ ++/* + * Userspace access stuff. + */ + EXPORT_SYMBOL(__copy_user); +--- a/arch/mips/mm/Makefile ++++ b/arch/mips/mm/Makefile +@@ -3,8 +3,8 @@ + # + + obj-y += cache.o dma-default.o extable.o fault.o \ +- init.o mmap.o tlbex.o tlbex-fault.o uasm.o \ +- page.o ++ init.o mmap.o page.o page-funcs.o \ ++ tlbex.o tlbex-fault.o uasm.o + + obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o + obj-$(CONFIG_64BIT) += pgtable-64.o +--- /dev/null ++++ b/arch/mips/mm/page-funcs.S +@@ -0,0 +1,50 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Micro-assembler generated clear_page/copy_page functions. ++ * ++ * Copyright (C) 2012 MIPS Technologies, Inc. ++ * Copyright (C) 2012 Ralf Baechle <ralf@linux-mips.org> ++ */ ++#include <asm/asm.h> ++#include <asm/regdef.h> ++ ++#ifdef CONFIG_SIBYTE_DMA_PAGEOPS ++#define cpu_clear_page_function_name clear_page_cpu ++#define cpu_copy_page_function_name copy_page_cpu ++#else ++#define cpu_clear_page_function_name clear_page ++#define cpu_copy_page_function_name copy_page ++#endif ++ ++/* ++ * Maximum sizes: ++ * ++ * R4000 128 bytes S-cache: 0x058 bytes ++ * R4600 v1.7: 0x05c bytes ++ * R4600 v2.0: 0x060 bytes ++ * With prefetching, 16 word strides 0x120 bytes ++ */ ++EXPORT(__clear_page_start) ++LEAF(cpu_clear_page_function_name) ++1: j 1b /* Dummy, will be replaced. */ ++ .space 288 ++END(cpu_clear_page_function_name) ++EXPORT(__clear_page_end) ++ ++/* ++ * Maximum sizes: ++ * ++ * R4000 128 bytes S-cache: 0x11c bytes ++ * R4600 v1.7: 0x080 bytes ++ * R4600 v2.0: 0x07c bytes ++ * With prefetching, 16 word strides 0x540 bytes ++ */ ++EXPORT(__copy_page_start) ++LEAF(cpu_copy_page_function_name) ++1: j 1b /* Dummy, will be replaced. */ ++ .space 1344 ++END(cpu_copy_page_function_name) ++EXPORT(__copy_page_end) +--- a/arch/mips/mm/page.c ++++ b/arch/mips/mm/page.c +@@ -6,6 +6,7 @@ + * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2007 Maciej W. Rozycki + * Copyright (C) 2008 Thiemo Seufer ++ * Copyright (C) 2012 MIPS Technologies, Inc. + */ + #include <linux/init.h> + #include <linux/kernel.h> +@@ -72,45 +73,6 @@ static struct uasm_reloc __cpuinitdata r + #define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010) + #define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020) + +-/* +- * Maximum sizes: +- * +- * R4000 128 bytes S-cache: 0x058 bytes +- * R4600 v1.7: 0x05c bytes +- * R4600 v2.0: 0x060 bytes +- * With prefetching, 16 word strides 0x120 bytes +- */ +- +-static u32 clear_page_array[0x120 / 4]; +- +-#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +-void clear_page_cpu(void *page) __attribute__((alias("clear_page_array"))); +-#else +-void clear_page(void *page) __attribute__((alias("clear_page_array"))); +-#endif +- +-EXPORT_SYMBOL(clear_page); +- +-/* +- * Maximum sizes: +- * +- * R4000 128 bytes S-cache: 0x11c bytes +- * R4600 v1.7: 0x080 bytes +- * R4600 v2.0: 0x07c bytes +- * With prefetching, 16 word strides 0x540 bytes +- */ +-static u32 copy_page_array[0x540 / 4]; +- +-#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +-void +-copy_page_cpu(void *to, void *from) __attribute__((alias("copy_page_array"))); +-#else +-void copy_page(void *to, void *from) __attribute__((alias("copy_page_array"))); +-#endif +- +-EXPORT_SYMBOL(copy_page); +- +- + static int pref_bias_clear_store __cpuinitdata; + static int pref_bias_copy_load __cpuinitdata; + static int pref_bias_copy_store __cpuinitdata; +@@ -283,10 +245,15 @@ static inline void __cpuinit build_clear + } + } + ++extern u32 __clear_page_start; ++extern u32 __clear_page_end; ++extern u32 __copy_page_start; ++extern u32 __copy_page_end; ++ + void __cpuinit build_clear_page(void) + { + int off; +- u32 *buf = (u32 *)&clear_page_array; ++ u32 *buf = &__clear_page_start; + struct uasm_label *l = labels; + struct uasm_reloc *r = relocs; + int i; +@@ -357,17 +324,17 @@ void __cpuinit build_clear_page(void) + uasm_i_jr(&buf, RA); + uasm_i_nop(&buf); + +- BUG_ON(buf > clear_page_array + ARRAY_SIZE(clear_page_array)); ++ BUG_ON(buf > &__clear_page_end); + + uasm_resolve_relocs(relocs, labels); + + pr_debug("Synthesized clear page handler (%u instructions).\n", +- (u32)(buf - clear_page_array)); ++ (u32)(buf - &__clear_page_start)); + + pr_debug("\t.set push\n"); + pr_debug("\t.set noreorder\n"); +- for (i = 0; i < (buf - clear_page_array); i++) +- pr_debug("\t.word 0x%08x\n", clear_page_array[i]); ++ for (i = 0; i < (buf - &__clear_page_start); i++) ++ pr_debug("\t.word 0x%08x\n", (&__clear_page_start)[i]); + pr_debug("\t.set pop\n"); + } + +@@ -428,7 +395,7 @@ static inline void build_copy_store_pref + void __cpuinit build_copy_page(void) + { + int off; +- u32 *buf = (u32 *)©_page_array; ++ u32 *buf = &__copy_page_start; + struct uasm_label *l = labels; + struct uasm_reloc *r = relocs; + int i; +@@ -596,21 +563,23 @@ void __cpuinit build_copy_page(void) + uasm_i_jr(&buf, RA); + uasm_i_nop(&buf); + +- BUG_ON(buf > copy_page_array + ARRAY_SIZE(copy_page_array)); ++ BUG_ON(buf > &__copy_page_end); + + uasm_resolve_relocs(relocs, labels); + + pr_debug("Synthesized copy page handler (%u instructions).\n", +- (u32)(buf - copy_page_array)); ++ (u32)(buf - &__copy_page_start)); + + pr_debug("\t.set push\n"); + pr_debug("\t.set noreorder\n"); +- for (i = 0; i < (buf - copy_page_array); i++) +- pr_debug("\t.word 0x%08x\n", copy_page_array[i]); ++ for (i = 0; i < (buf - &__copy_page_start); i++) ++ pr_debug("\t.word 0x%08x\n", (&__copy_page_start)[i]); + pr_debug("\t.set pop\n"); + } + + #ifdef CONFIG_SIBYTE_DMA_PAGEOPS ++extern void clear_page_cpu(void *page); ++extern void copy_page_cpu(void *to, void *from); + + /* + * Pad descriptors to cacheline, since each is exclusively owned by a diff --git a/releases/3.2.94/mips-send-sigill-for-bposge32-in-__compute_return_epc_for_insn.patch b/releases/3.2.94/mips-send-sigill-for-bposge32-in-__compute_return_epc_for_insn.patch new file mode 100644 index 00000000..c94f09fb --- /dev/null +++ b/releases/3.2.94/mips-send-sigill-for-bposge32-in-__compute_return_epc_for_insn.patch @@ -0,0 +1,39 @@ +From: "Maciej W. Rozycki" <macro@imgtec.com> +Date: Fri, 16 Jun 2017 00:08:29 +0100 +Subject: MIPS: Send SIGILL for BPOSGE32 in `__compute_return_epc_for_insn' + +commit 7b82c1058ac1f8f8b9f2b8786b1f710a57a870a8 upstream. + +Fix commit e50c0a8fa60d ("Support the MIPS32 / MIPS64 DSP ASE.") and +send SIGILL rather than SIGBUS whenever an unimplemented BPOSGE32 DSP +ASE instruction has been encountered in `__compute_return_epc_for_insn' +as our Reserved Instruction exception handler would in response to an +attempt to actually execute the instruction. Sending SIGBUS only makes +sense for the unaligned PC case, since moved to `__compute_return_epc'. +Adjust function documentation accordingly, correct formatting and use +`pr_info' rather than `printk' as the other exit path already does. + +Fixes: e50c0a8fa60d ("Support the MIPS32 / MIPS64 DSP ASE.") +Signed-off-by: Maciej W. Rozycki <macro@imgtec.com> +Cc: James Hogan <james.hogan@imgtec.com> +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/16396/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +[bwh: Backported to 3.2: + - Drop the comment change + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/arch/mips/kernel/branch.c ++++ b/arch/mips/kernel/branch.c +@@ -247,7 +247,8 @@ unaligned: + return -EFAULT; + + sigill: +- printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm); +- force_sig(SIGBUS, current); ++ pr_info("%s: DSP branch but not DSP ASE - sending SIGILL.\n", ++ current->comm); ++ force_sig(SIGILL, current); + return -EFAULT; + } diff --git a/releases/3.2.94/mm-fix-overflow-check-in-expand_upwards.patch b/releases/3.2.94/mm-fix-overflow-check-in-expand_upwards.patch new file mode 100644 index 00000000..156ff6aa --- /dev/null +++ b/releases/3.2.94/mm-fix-overflow-check-in-expand_upwards.patch @@ -0,0 +1,45 @@ +From: Helge Deller <deller@gmx.de> +Date: Fri, 14 Jul 2017 14:49:38 -0700 +Subject: mm: fix overflow check in expand_upwards() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 37511fb5c91db93d8bd6e3f52f86e5a7ff7cfcdf upstream. + +Jörn Engel noticed that the expand_upwards() function might not return +-ENOMEM in case the requested address is (unsigned long)-PAGE_SIZE and +if the architecture didn't defined TASK_SIZE as multiple of PAGE_SIZE. + +Affected architectures are arm, frv, m68k, blackfin, h8300 and xtensa +which all define TASK_SIZE as 0xffffffff, but since none of those have +an upwards-growing stack we currently have no actual issue. + +Nevertheless let's fix this just in case any of the architectures with +an upward-growing stack (currently parisc, metag and partly ia64) define +TASK_SIZE similar. + +Link: http://lkml.kernel.org/r/20170702192452.GA11868@p100.box +Fixes: bd726c90b6b8 ("Allow stack to grow up to address space limit") +Signed-off-by: Helge Deller <deller@gmx.de> +Reported-by: Jörn Engel <joern@purestorage.com> +Cc: Hugh Dickins <hughd@google.com> +Cc: Oleg Nesterov <oleg@redhat.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/mmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1717,7 +1717,7 @@ int expand_upwards(struct vm_area_struct + + /* Guard against exceeding limits of the address space. */ + address &= PAGE_MASK; +- if (address >= TASK_SIZE) ++ if (address >= (TASK_SIZE & PAGE_MASK)) + return -ENOMEM; + address += PAGE_SIZE; + diff --git a/releases/3.2.94/mm-mmap.c-do-not-blow-on-prot_none-map_fixed-holes-in-the-stack.patch b/releases/3.2.94/mm-mmap.c-do-not-blow-on-prot_none-map_fixed-holes-in-the-stack.patch new file mode 100644 index 00000000..21306996 --- /dev/null +++ b/releases/3.2.94/mm-mmap.c-do-not-blow-on-prot_none-map_fixed-holes-in-the-stack.patch @@ -0,0 +1,59 @@ +From: Michal Hocko <mhocko@suse.com> +Date: Mon, 10 Jul 2017 15:49:51 -0700 +Subject: mm/mmap.c: do not blow on PROT_NONE MAP_FIXED holes in the stack + +commit 561b5e0709e4a248c67d024d4d94b6e31e3edf2f upstream. + +Commit 1be7107fbe18 ("mm: larger stack guard gap, between vmas") has +introduced a regression in some rust and Java environments which are +trying to implement their own stack guard page. They are punching a new +MAP_FIXED mapping inside the existing stack Vma. + +This will confuse expand_{downwards,upwards} into thinking that the +stack expansion would in fact get us too close to an existing non-stack +vma which is a correct behavior wrt safety. It is a real regression on +the other hand. + +Let's work around the problem by considering PROT_NONE mapping as a part +of the stack. This is a gros hack but overflowing to such a mapping +would trap anyway an we only can hope that usespace knows what it is +doing and handle it propely. + +Fixes: 1be7107fbe18 ("mm: larger stack guard gap, between vmas") +Link: http://lkml.kernel.org/r/20170705182849.GA18027@dhcp22.suse.cz +Signed-off-by: Michal Hocko <mhocko@suse.com> +Debugged-by: Vlastimil Babka <vbabka@suse.cz> +Cc: Ben Hutchings <ben@decadent.org.uk> +Cc: Willy Tarreau <w@1wt.eu> +Cc: Oleg Nesterov <oleg@redhat.com> +Cc: Rik van Riel <riel@redhat.com> +Cc: Hugh Dickins <hughd@google.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/mmap.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1729,7 +1729,8 @@ int expand_upwards(struct vm_area_struct + gap_addr = TASK_SIZE; + + next = vma->vm_next; +- if (next && next->vm_start < gap_addr) { ++ if (next && next->vm_start < gap_addr && ++ (next->vm_flags & (VM_WRITE|VM_READ|VM_EXEC))) { + if (!(next->vm_flags & VM_GROWSUP)) + return -ENOMEM; + /* Check that both stack segments have the same anon_vma? */ +@@ -1788,7 +1789,8 @@ int expand_downwards(struct vm_area_stru + if (gap_addr > address) + return -ENOMEM; + prev = vma->vm_prev; +- if (prev && prev->vm_end > gap_addr) { ++ if (prev && prev->vm_end > gap_addr && ++ (prev->vm_flags & (VM_WRITE|VM_READ|VM_EXEC))) { + if (!(prev->vm_flags & VM_GROWSDOWN)) + return -ENOMEM; + /* Check that both stack segments have the same anon_vma? */ diff --git a/releases/3.2.94/mwifiex-fixup-error-cases-in-mwifiex_add_virtual_intf.patch b/releases/3.2.94/mwifiex-fixup-error-cases-in-mwifiex_add_virtual_intf.patch new file mode 100644 index 00000000..756a4d5a --- /dev/null +++ b/releases/3.2.94/mwifiex-fixup-error-cases-in-mwifiex_add_virtual_intf.patch @@ -0,0 +1,108 @@ +From: Brian Norris <briannorris@chromium.org> +Date: Fri, 12 May 2017 09:41:58 -0700 +Subject: mwifiex: fixup error cases in mwifiex_add_virtual_intf() + +commit 8535107aa4ef92520cbb9a4739563b389c5f8e2c upstream. + +If we fail to add an interface in mwifiex_add_virtual_intf(), we might +hit a BUG_ON() in the networking code, because we didn't tear things +down properly. Among the problems: + + (a) when failing to allocate workqueues, we fail to unregister the + netdev before calling free_netdev() + (b) even if we do try to unregister the netdev, we're still holding the + rtnl lock, so the device never properly unregistered; we'll be at + state NETREG_UNREGISTERING, and then hit free_netdev()'s: + BUG_ON(dev->reg_state != NETREG_UNREGISTERED); + (c) we're allocating some dependent resources (e.g., DFS workqueues) + after we've registered the interface; this may or may not cause + problems, but it's good practice to allocate these before registering + (d) we're not even trying to unwind anything when mwifiex_send_cmd() or + mwifiex_sta_init_cmd() fail + +To fix these issues, let's: + + * add a stacked set of error handling labels, to keep error handling + consistent and properly ordered (resolving (a) and (d)) + * move the workqueue allocations before the registration (to resolve + (c); also resolves (b) by avoiding error cases where we have to + unregister) + +[Incidentally, it's pretty easy to interrupt the alloc_workqueue() in, +e.g., the following: + + iw phy phy0 interface add mlan0 type station + +by sending it SIGTERM.] + +This bugfix covers commits like commit 7d652034d1a0 ("mwifiex: channel +switch support for mwifiex"), but parts of this bug exist all the way +back to the introduction of dynamic interface handling in commit +93a1df48d224 ("mwifiex: add cfg80211 handlers add/del_virtual_intf"). + +Signed-off-by: Brian Norris <briannorris@chromium.org> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> +[bwh: Backported to 3.2: + - There is no workqueue allocation or cleanup needed here + - Add 'ret' variable + - Keep logging errors with wiphy_err() + - Adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/net/wireless/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/mwifiex/cfg80211.c +@@ -1176,6 +1176,7 @@ struct net_device *mwifiex_add_virtual_i + struct mwifiex_adapter *adapter; + struct net_device *dev; + void *mdev_priv; ++ int ret; + + if (!priv) + return ERR_PTR(-EFAULT); +@@ -1216,8 +1217,8 @@ struct net_device *mwifiex_add_virtual_i + ether_setup, 1); + if (!dev) { + wiphy_err(wiphy, "no memory available for netdevice\n"); +- priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; +- return ERR_PTR(-ENOMEM); ++ ret = -ENOMEM; ++ goto err_alloc_netdev; + } + + dev_net_set(dev, wiphy_net(wiphy)); +@@ -1239,23 +1240,29 @@ struct net_device *mwifiex_add_virtual_i + + SET_NETDEV_DEV(dev, adapter->dev); + ++ sema_init(&priv->async_sem, 1); ++ priv->scan_pending_on_block = false; ++ + /* Register network device */ + if (register_netdevice(dev)) { + wiphy_err(wiphy, "cannot register virtual network device\n"); +- free_netdev(dev); +- priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; +- return ERR_PTR(-EFAULT); ++ ret = -EFAULT; ++ goto err_reg_netdev; + } + +- sema_init(&priv->async_sem, 1); +- priv->scan_pending_on_block = false; +- + dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name); + + #ifdef CONFIG_DEBUG_FS + mwifiex_dev_debugfs_init(priv); + #endif + return dev; ++ ++err_reg_netdev: ++ free_netdev(dev); ++ priv->netdev = NULL; ++err_alloc_netdev: ++ priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; ++ return ERR_PTR(ret); + } + EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); + diff --git a/releases/3.2.94/net-sched-filters-fix-notification-of-filter-delete-with-proper-handle.patch b/releases/3.2.94/net-sched-filters-fix-notification-of-filter-delete-with-proper-handle.patch new file mode 100644 index 00000000..80fc12de --- /dev/null +++ b/releases/3.2.94/net-sched-filters-fix-notification-of-filter-delete-with-proper-handle.patch @@ -0,0 +1,77 @@ +From: Jamal Hadi Salim <jhs@mojatatu.com> +Date: Mon, 24 Oct 2016 20:18:27 -0400 +Subject: net sched filters: fix notification of filter delete with proper handle + +[ Upstream commit 9ee7837449b3d6f0fcf9132c6b5e5aaa58cc67d4 ] + +Daniel says: + +While trying out [1][2], I noticed that tc monitor doesn't show the +correct handle on delete: + +$ tc monitor +qdisc clsact ffff: dev eno1 parent ffff:fff1 +filter dev eno1 ingress protocol all pref 49152 bpf handle 0x2a [...] +deleted filter dev eno1 ingress protocol all pref 49152 bpf handle 0xf3be0c80 + +some context to explain the above: +The user identity of any tc filter is represented by a 32-bit +identifier encoded in tcm->tcm_handle. Example 0x2a in the bpf filter +above. A user wishing to delete, get or even modify a specific filter +uses this handle to reference it. +Every classifier is free to provide its own semantics for the 32 bit handle. +Example: classifiers like u32 use schemes like 800:1:801 to describe +the semantics of their filters represented as hash table, bucket and +node ids etc. +Classifiers also have internal per-filter representation which is different +from this externally visible identity. Most classifiers set this +internal representation to be a pointer address (which allows fast retrieval +of said filters in their implementations). This internal representation +is referenced with the "fh" variable in the kernel control code. + +When a user successfuly deletes a specific filter, by specifying the correct +tcm->tcm_handle, an event is generated to user space which indicates +which specific filter was deleted. + +Before this patch, the "fh" value was sent to user space as the identity. +As an example what is shown in the sample bpf filter delete event above +is 0xf3be0c80. This is infact a 32-bit truncation of 0xffff8807f3be0c80 +which happens to be a 64-bit memory address of the internal filter +representation (address of the corresponding filter's struct cls_bpf_prog); + +After this patch the appropriate user identifiable handle as encoded +in the originating request tcm->tcm_handle is generated in the event. +One of the cardinal rules of netlink rules is to be able to take an +event (such as a delete in this case) and reflect it back to the +kernel and successfully delete the filter. This patch achieves that. + +Note, this issue has existed since the original TC action +infrastructure code patch back in 2004 as found in: +https://git.kernel.org/cgit/linux/kernel/git/history/history.git/commit/ + +[1] http://patchwork.ozlabs.org/patch/682828/ +[2] http://patchwork.ozlabs.org/patch/682829/ + +Fixes: 4e54c4816bfe ("[NET]: Add tc extensions infrastructure.") +Reported-by: Daniel Borkmann <daniel@iogearbox.net> +Acked-by: Cong Wang <xiyou.wangcong@gmail.com> +Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/sched/cls_api.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/sched/cls_api.c ++++ b/net/sched/cls_api.c +@@ -310,7 +310,8 @@ replay: + case RTM_DELTFILTER: + err = tp->ops->delete(tp, fh); + if (err == 0) +- tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER); ++ tfilter_notify(net, skb, n, tp, ++ t->tcm_handle, RTM_DELTFILTER); + goto errout; + case RTM_GETTFILTER: + err = tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER); diff --git a/releases/3.2.94/netfilter-nf_conntrack-fix-rcu-race-in-nf_conntrack_find_get.patch b/releases/3.2.94/netfilter-nf_conntrack-fix-rcu-race-in-nf_conntrack_find_get.patch new file mode 100644 index 00000000..52e8f005 --- /dev/null +++ b/releases/3.2.94/netfilter-nf_conntrack-fix-rcu-race-in-nf_conntrack_find_get.patch @@ -0,0 +1,144 @@ +From: Andrey Vagin <avagin@openvz.org> +Date: Wed, 29 Jan 2014 19:34:14 +0100 +Subject: netfilter: nf_conntrack: fix RCU race in nf_conntrack_find_get + +commit c6825c0976fa7893692e0e43b09740b419b23c09 upstream. + +Lets look at destroy_conntrack: + +hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode); +... +nf_conntrack_free(ct) + kmem_cache_free(net->ct.nf_conntrack_cachep, ct); + +net->ct.nf_conntrack_cachep is created with SLAB_DESTROY_BY_RCU. + +The hash is protected by rcu, so readers look up conntracks without +locks. +A conntrack is removed from the hash, but in this moment a few readers +still can use the conntrack. Then this conntrack is released and another +thread creates conntrack with the same address and the equal tuple. +After this a reader starts to validate the conntrack: +* It's not dying, because a new conntrack was created +* nf_ct_tuple_equal() returns true. + +But this conntrack is not initialized yet, so it can not be used by two +threads concurrently. In this case BUG_ON may be triggered from +nf_nat_setup_info(). + +Florian Westphal suggested to check the confirm bit too. I think it's +right. + +task 1 task 2 task 3 + nf_conntrack_find_get + ____nf_conntrack_find +destroy_conntrack + hlist_nulls_del_rcu + nf_conntrack_free + kmem_cache_free + __nf_conntrack_alloc + kmem_cache_alloc + memset(&ct->tuplehash[IP_CT_DIR_MAX], + if (nf_ct_is_dying(ct)) + if (!nf_ct_tuple_equal() + +I'm not sure, that I have ever seen this race condition in a real life. +Currently we are investigating a bug, which is reproduced on a few nodes. +In our case one conntrack is initialized from a few tasks concurrently, +we don't have any other explanation for this. + +<2>[46267.083061] kernel BUG at net/ipv4/netfilter/nf_nat_core.c:322! +... +<4>[46267.083951] RIP: 0010:[<ffffffffa01e00a4>] [<ffffffffa01e00a4>] nf_nat_setup_info+0x564/0x590 [nf_nat] +... +<4>[46267.085549] Call Trace: +<4>[46267.085622] [<ffffffffa023421b>] alloc_null_binding+0x5b/0xa0 [iptable_nat] +<4>[46267.085697] [<ffffffffa02342bc>] nf_nat_rule_find+0x5c/0x80 [iptable_nat] +<4>[46267.085770] [<ffffffffa0234521>] nf_nat_fn+0x111/0x260 [iptable_nat] +<4>[46267.085843] [<ffffffffa0234798>] nf_nat_out+0x48/0xd0 [iptable_nat] +<4>[46267.085919] [<ffffffff814841b9>] nf_iterate+0x69/0xb0 +<4>[46267.085991] [<ffffffff81494e70>] ? ip_finish_output+0x0/0x2f0 +<4>[46267.086063] [<ffffffff81484374>] nf_hook_slow+0x74/0x110 +<4>[46267.086133] [<ffffffff81494e70>] ? ip_finish_output+0x0/0x2f0 +<4>[46267.086207] [<ffffffff814b5890>] ? dst_output+0x0/0x20 +<4>[46267.086277] [<ffffffff81495204>] ip_output+0xa4/0xc0 +<4>[46267.086346] [<ffffffff814b65a4>] raw_sendmsg+0x8b4/0x910 +<4>[46267.086419] [<ffffffff814c10fa>] inet_sendmsg+0x4a/0xb0 +<4>[46267.086491] [<ffffffff814459aa>] ? sock_update_classid+0x3a/0x50 +<4>[46267.086562] [<ffffffff81444d67>] sock_sendmsg+0x117/0x140 +<4>[46267.086638] [<ffffffff8151997b>] ? _spin_unlock_bh+0x1b/0x20 +<4>[46267.086712] [<ffffffff8109d370>] ? autoremove_wake_function+0x0/0x40 +<4>[46267.086785] [<ffffffff81495e80>] ? do_ip_setsockopt+0x90/0xd80 +<4>[46267.086858] [<ffffffff8100be0e>] ? call_function_interrupt+0xe/0x20 +<4>[46267.086936] [<ffffffff8118cb10>] ? ub_slab_ptr+0x20/0x90 +<4>[46267.087006] [<ffffffff8118cb10>] ? ub_slab_ptr+0x20/0x90 +<4>[46267.087081] [<ffffffff8118f2e8>] ? kmem_cache_alloc+0xd8/0x1e0 +<4>[46267.087151] [<ffffffff81445599>] sys_sendto+0x139/0x190 +<4>[46267.087229] [<ffffffff81448c0d>] ? sock_setsockopt+0x16d/0x6f0 +<4>[46267.087303] [<ffffffff810efa47>] ? audit_syscall_entry+0x1d7/0x200 +<4>[46267.087378] [<ffffffff810ef795>] ? __audit_syscall_exit+0x265/0x290 +<4>[46267.087454] [<ffffffff81474885>] ? compat_sys_setsockopt+0x75/0x210 +<4>[46267.087531] [<ffffffff81474b5f>] compat_sys_socketcall+0x13f/0x210 +<4>[46267.087607] [<ffffffff8104dea3>] ia32_sysret+0x0/0x5 +<4>[46267.087676] Code: 91 20 e2 01 75 29 48 89 de 4c 89 f7 e8 56 fa ff ff 85 c0 0f 84 68 fc ff ff 0f b6 4d c6 41 8b 45 00 e9 4d fb ff ff e8 7c 19 e9 e0 <0f> 0b eb fe f6 05 17 91 20 e2 80 74 ce 80 3d 5f 2e 00 00 00 74 +<1>[46267.088023] RIP [<ffffffffa01e00a4>] nf_nat_setup_info+0x564/0x590 + +Cc: Eric Dumazet <eric.dumazet@gmail.com> +Cc: Florian Westphal <fw@strlen.de> +Cc: Pablo Neira Ayuso <pablo@netfilter.org> +Cc: Patrick McHardy <kaber@trash.net> +Cc: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> +Cc: "David S. Miller" <davem@davemloft.net> +Cc: Cyrill Gorcunov <gorcunov@openvz.org> +Signed-off-by: Andrey Vagin <avagin@openvz.org> +Acked-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/netfilter/nf_conntrack_core.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -307,6 +307,21 @@ static void death_by_timeout(unsigned lo + nf_ct_put(ct); + } + ++static inline bool ++nf_ct_key_equal(struct nf_conntrack_tuple_hash *h, ++ const struct nf_conntrack_tuple *tuple, ++ u16 zone) ++{ ++ struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); ++ ++ /* A conntrack can be recreated with the equal tuple, ++ * so we need to check that the conntrack is confirmed ++ */ ++ return nf_ct_tuple_equal(tuple, &h->tuple) && ++ nf_ct_zone(ct) == zone && ++ nf_ct_is_confirmed(ct); ++} ++ + /* + * Warning : + * - Caller must take a reference on returned object +@@ -328,8 +343,7 @@ ____nf_conntrack_find(struct net *net, u + local_bh_disable(); + begin: + hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[bucket], hnnode) { +- if (nf_ct_tuple_equal(tuple, &h->tuple) && +- nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)) == zone) { ++ if (nf_ct_key_equal(h, tuple, zone)) { + NF_CT_STAT_INC(net, found); + local_bh_enable(); + return h; +@@ -376,8 +390,7 @@ begin: + !atomic_inc_not_zero(&ct->ct_general.use))) + h = NULL; + else { +- if (unlikely(!nf_ct_tuple_equal(tuple, &h->tuple) || +- nf_ct_zone(ct) != zone)) { ++ if (unlikely(!nf_ct_key_equal(h, tuple, zone))) { + nf_ct_put(ct); + goto begin; + } diff --git a/releases/3.2.94/nl80211-check-for-the-required-netlink-attributes-presence.patch b/releases/3.2.94/nl80211-check-for-the-required-netlink-attributes-presence.patch new file mode 100644 index 00000000..6c530574 --- /dev/null +++ b/releases/3.2.94/nl80211-check-for-the-required-netlink-attributes-presence.patch @@ -0,0 +1,37 @@ +From: Vladis Dronov <vdronov@redhat.com> +Date: Wed, 13 Sep 2017 00:21:21 +0200 +Subject: nl80211: check for the required netlink attributes presence + +commit e785fa0a164aa11001cba931367c7f94ffaff888 upstream. + +nl80211_set_rekey_data() does not check if the required attributes +NL80211_REKEY_DATA_{REPLAY_CTR,KEK,KCK} are present when processing +NL80211_CMD_SET_REKEY_OFFLOAD request. This request can be issued by +users with CAP_NET_ADMIN privilege and may result in NULL dereference +and a system crash. Add a check for the required attributes presence. +This patch is based on the patch by bo Zhang. + +This fixes CVE-2017-12153. + +References: https://bugzilla.redhat.com/show_bug.cgi?id=1491046 +Fixes: e5497d766ad ("cfg80211/nl80211: support GTK rekey offload") +Reported-by: bo Zhang <zhangbo5891001@gmail.com> +Signed-off-by: Vladis Dronov <vdronov@redhat.com> +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/wireless/nl80211.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -5823,6 +5823,9 @@ static int nl80211_set_rekey_data(struct + if (err) + return err; + ++ if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] || ++ !tb[NL80211_REKEY_DATA_KCK]) ++ return -EINVAL; + if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN) + return -ERANGE; + if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN) diff --git a/releases/3.2.94/parisc-use-compat_sys_keyctl.patch b/releases/3.2.94/parisc-use-compat_sys_keyctl.patch new file mode 100644 index 00000000..c53fe766 --- /dev/null +++ b/releases/3.2.94/parisc-use-compat_sys_keyctl.patch @@ -0,0 +1,29 @@ +From: Eric Biggers <ebiggers@google.com> +Date: Mon, 12 Jun 2017 23:18:30 -0700 +Subject: parisc: use compat_sys_keyctl() + +commit b0f94efd5aa8daa8a07d7601714c2573266cd4c9 upstream. + +Architectures with a compat syscall table must put compat_sys_keyctl() +in it, not sys_keyctl(). The parisc architecture was not doing this; +fix it. + +Signed-off-by: Eric Biggers <ebiggers@google.com> +Acked-by: Helge Deller <deller@gmx.de> +Signed-off-by: Helge Deller <deller@gmx.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/parisc/kernel/syscall_table.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/parisc/kernel/syscall_table.S ++++ b/arch/parisc/kernel/syscall_table.S +@@ -364,7 +364,7 @@ + ENTRY_SAME(ni_syscall) /* 263: reserved for vserver */ + ENTRY_SAME(add_key) + ENTRY_SAME(request_key) /* 265 */ +- ENTRY_SAME(keyctl) ++ ENTRY_COMP(keyctl) + ENTRY_SAME(ioprio_set) + ENTRY_SAME(ioprio_get) + ENTRY_SAME(inotify_init) diff --git a/releases/3.2.94/pci-correct-pci_std_resource_end-usage.patch b/releases/3.2.94/pci-correct-pci_std_resource_end-usage.patch new file mode 100644 index 00000000..effd47bd --- /dev/null +++ b/releases/3.2.94/pci-correct-pci_std_resource_end-usage.patch @@ -0,0 +1,28 @@ +From: Bjorn Helgaas <bhelgaas@google.com> +Date: Fri, 19 May 2017 14:40:50 -0500 +Subject: PCI: Correct PCI_STD_RESOURCE_END usage + +commit 2f686f1d9beee135de6d08caea707ec7bfc916d4 upstream. + +PCI_STD_RESOURCE_END is (confusingly) the index of the last valid BAR, not +the *number* of BARs. To iterate through all possible BARs, we need to +include PCI_STD_RESOURCE_END. + +Fixes: 9fe373f9997b ("PCI: Increase IBM ipr SAS Crocodile BARs to at least system page size") +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/pci/quirks.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -358,7 +358,7 @@ static void quirk_extend_bar_to_page(str + { + int i; + +- for (i = 0; i < PCI_STD_RESOURCE_END; i++) { ++ for (i = 0; i <= PCI_STD_RESOURCE_END; i++) { + struct resource *r = &dev->resource[i]; + + if (r->flags & IORESOURCE_MEM && resource_size(r) < PAGE_SIZE) { diff --git a/releases/3.2.94/pci-mark-haswell-power-control-unit-as-having-non-compliant-bars.patch b/releases/3.2.94/pci-mark-haswell-power-control-unit-as-having-non-compliant-bars.patch new file mode 100644 index 00000000..57464a8e --- /dev/null +++ b/releases/3.2.94/pci-mark-haswell-power-control-unit-as-having-non-compliant-bars.patch @@ -0,0 +1,63 @@ +From: Bjorn Helgaas <bhelgaas@google.com> +Date: Thu, 1 Sep 2016 08:52:29 -0500 +Subject: PCI: Mark Haswell Power Control Unit as having non-compliant BARs + +commit 6af7e4f77259ee946103387372cb159f2e99a6d4 upstream. + +The Haswell Power Control Unit has a non-PCI register (CONFIG_TDP_NOMINAL) +where BAR 0 is supposed to be. This is erratum HSE43 in the spec update +referenced below: + + The PCIe* Base Specification indicates that Configuration Space Headers + have a base address register at offset 0x10. Due to this erratum, the + Power Control Unit's CONFIG_TDP_NOMINAL CSR (Bus 1; Device 30; Function + 3; Offset 0x10) is located where a base register is expected. + +Mark the PCU as having non-compliant BARs so we don't try to probe any of +them. There are no other BARs on this device. + +Rename the quirk so it's not Broadwell-specific. + +Link: http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v3-spec-update.html +Link: http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v3-datasheet-vol-2.html (section 5.4, Device 30 Function 3) +Link: https://bugzilla.kernel.org/show_bug.cgi?id=153881 +Reported-by: Paul Menzel <pmenzel@molgen.mpg.de> +Tested-by: Prarit Bhargava <prarit@redhat.com> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Acked-by: Myron Stowe <myron.stowe@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/pci/fixup.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +--- a/arch/x86/pci/fixup.c ++++ b/arch/x86/pci/fixup.c +@@ -540,15 +540,21 @@ static void __devinit twinhead_reserve_k + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_killing_zone); + + /* +- * Broadwell EP Home Agent BARs erroneously return non-zero values when read. ++ * Device [8086:2fc0] ++ * Erratum HSE43 ++ * CONFIG_TDP_NOMINAL CSR Implemented at Incorrect Offset ++ * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v3-spec-update.html + * +- * See http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v4-spec-update.html +- * entry BDF2. ++ * Devices [8086:6f60,6fa0,6fc0] ++ * Erratum BDF2 ++ * PCI BARs in the Home Agent Will Return Non-Zero Values During Enumeration ++ * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v4-spec-update.html + */ +-static void pci_bdwep_bar(struct pci_dev *dev) ++static void pci_invalid_bar(struct pci_dev *dev) + { + dev->non_compliant_bars = 1; + } +-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6f60, pci_bdwep_bar); +-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_bdwep_bar); +-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_bdwep_bar); ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2fc0, pci_invalid_bar); ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6f60, pci_invalid_bar); ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_invalid_bar); ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_invalid_bar); diff --git a/releases/3.2.94/pci-pm-restore-the-status-of-pci-devices-across-hibernation.patch b/releases/3.2.94/pci-pm-restore-the-status-of-pci-devices-across-hibernation.patch new file mode 100644 index 00000000..d0c41731 --- /dev/null +++ b/releases/3.2.94/pci-pm-restore-the-status-of-pci-devices-across-hibernation.patch @@ -0,0 +1,89 @@ +From: Chen Yu <yu.c.chen@intel.com> +Date: Thu, 25 May 2017 16:49:07 +0800 +Subject: PCI/PM: Restore the status of PCI devices across hibernation + +commit e60514bd4485c0c7c5a7cf779b200ce0b95c70d6 upstream. + +Currently we saw a lot of "No irq handler" errors during hibernation, which +caused the system hang finally: + + ata4.00: qc timeout (cmd 0xec) + ata4.00: failed to IDENTIFY (I/O error, err_mask=0x4) + ata4.00: revalidation failed (errno=-5) + ata4: SATA link up 6.0 Gbps (SStatus 133 SControl 300) + do_IRQ: 31.151 No irq handler for vector + +According to above logs, there is an interrupt triggered and it is +dispatched to CPU31 with a vector number 151, but there is no handler for +it, thus this IRQ will not get acked and will cause an IRQ flood which +kills the system. To be more specific, the 31.151 is an interrupt from the +AHCI host controller. + +After some investigation, the reason why this issue is triggered is because +the thaw_noirq() function does not restore the MSI/MSI-X settings across +hibernation. + +The scenario is illustrated below: + + 1. Before hibernation, IRQ 34 is the handler for the AHCI device, which + is bound to CPU31. + + 2. Hibernation starts, the AHCI device is put into low power state. + + 3. All the nonboot CPUs are put offline, so IRQ 34 has to be migrated to + the last alive one - CPU0. + + 4. After the snapshot has been created, all the nonboot CPUs are brought + up again; IRQ 34 remains bound to CPU0. + + 5. AHCI devices are put into D0. + + 6. The snapshot is written to the disk. + +The issue is triggered in step 6. The AHCI interrupt should be delivered +to CPU0, however it is delivered to the original CPU31 instead, which +causes the "No irq handler" issue. + +Ying Huang has provided a clue that, in step 3 it is possible that writing +to the register might not take effect as the PCI devices have been +suspended. + +In step 3, the IRQ 34 affinity should be modified from CPU31 to CPU0, but +in fact it is not. In __pci_write_msi_msg(), if the device is already in +low power state, the low level MSI message entry will not be updated but +cached. During the device restore process after a normal suspend/resume, +pci_restore_msi_state() writes the cached MSI back to the hardware. + +But this is not the case for hibernation. pci_restore_msi_state() is not +currently called in pci_pm_thaw_noirq(), although pci_save_state() has +saved the necessary PCI cached information in pci_pm_freeze_noirq(). + +Restore the PCI status for the device during hibernation. Otherwise the +status might be lost across hibernation (for example, settings for MSI, +MSI-X, ATS, ACS, IOV, etc.), which might cause problems during hibernation. + +Suggested-by: Ying Huang <ying.huang@intel.com> +Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +Signed-off-by: Chen Yu <yu.c.chen@intel.com> +[bhelgaas: changelog] +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +Cc: Len Brown <len.brown@intel.com> +Cc: Dan Williams <dan.j.williams@intel.com> +Cc: Rui Zhang <rui.zhang@intel.com> +Cc: Ying Huang <ying.huang@intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/pci/pci-driver.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -873,6 +873,7 @@ static int pci_pm_thaw_noirq(struct devi + return pci_legacy_resume_early(dev); + + pci_update_current_state(pci_dev, PCI_D0); ++ pci_restore_state(pci_dev); + + if (drv && drv->pm && drv->pm->thaw_noirq) + error = drv->pm->thaw_noirq(dev); diff --git a/releases/3.2.94/pci-work-around-poweroff-suspend-to-ram-issue-on-macbook-pro-11.patch b/releases/3.2.94/pci-work-around-poweroff-suspend-to-ram-issue-on-macbook-pro-11.patch new file mode 100644 index 00000000..4c765b8d --- /dev/null +++ b/releases/3.2.94/pci-work-around-poweroff-suspend-to-ram-issue-on-macbook-pro-11.patch @@ -0,0 +1,80 @@ +From: Bjorn Helgaas <bhelgaas@google.com> +Date: Fri, 19 Aug 2016 16:30:25 +0800 +Subject: PCI: Work around poweroff & suspend-to-RAM issue on Macbook Pro 11 + +commit 13cfc732160f7bc7e596128ce34cda361c556966 upstream. + +Neither soft poweroff (transition to ACPI power state S5) nor +suspend-to-RAM (transition to state S3) works on the Macbook Pro 11,4 and +11,5. + +The problem is related to the [mem 0x7fa00000-0x7fbfffff] space. When we +use that space, e.g., by assigning it to the 00:1c.0 Root Port, the ACPI +Power Management 1 Control Register (PM1_CNT) at [io 0x1804] doesn't work +anymore. + +Linux does a soft poweroff (transition to S5) by writing to PM1_CNT. The +theory about why this doesn't work is: + + - The write to PM1_CNT causes an SMI + - The BIOS SMI handler depends on something in + [mem 0x7fa00000-0x7fbfffff] + - When Linux assigns [mem 0x7fa00000-0x7fbfffff] to the 00:1c.0 Port, it + covers up whatever the SMI handler uses, so the SMI handler no longer + works correctly + +Reserve the [mem 0x7fa00000-0x7fbfffff] space so we don't assign it to +anything. + +This is voodoo programming, since we don't know what the real conflict is, +but we've failed to find the root cause. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=103211 +Tested-by: thejoe@gmail.com +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Cc: Rafael J. Wysocki <rafael@kernel.org> +Cc: Lukas Wunner <lukas@wunner.de> +Cc: Chen Yu <yu.c.chen@intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/pci/fixup.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +--- a/arch/x86/pci/fixup.c ++++ b/arch/x86/pci/fixup.c +@@ -558,3 +558,35 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IN + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6f60, pci_invalid_bar); + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_invalid_bar); + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_invalid_bar); ++ ++/* ++ * Apple MacBook Pro: Avoid [mem 0x7fa00000-0x7fbfffff] ++ * ++ * Using the [mem 0x7fa00000-0x7fbfffff] region, e.g., by assigning it to ++ * the 00:1c.0 Root Port, causes a conflict with [io 0x1804], which is used ++ * for soft poweroff and suspend-to-RAM. ++ * ++ * As far as we know, this is related to the address space, not to the Root ++ * Port itself. Attaching the quirk to the Root Port is a convenience, but ++ * it could probably also be a standalone DMI quirk. ++ * ++ * https://bugzilla.kernel.org/show_bug.cgi?id=103211 ++ */ ++static void quirk_apple_mbp_poweroff(struct pci_dev *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct resource *res; ++ ++ if ((!dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,4") && ++ !dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,5")) || ++ pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x1c, 0)) ++ return; ++ ++ res = request_mem_region(0x7fa00000, 0x200000, ++ "MacBook Pro poweroff workaround"); ++ if (res) ++ dev_info(dev, "claimed %s %pR\n", res->name, res); ++ else ++ dev_info(dev, "can't work around MacBook Pro poweroff issue\n"); ++} ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_apple_mbp_poweroff); diff --git a/releases/3.2.94/perf-core-correct-event-creation-with-perf_format_group.patch b/releases/3.2.94/perf-core-correct-event-creation-with-perf_format_group.patch new file mode 100644 index 00000000..29432adb --- /dev/null +++ b/releases/3.2.94/perf-core-correct-event-creation-with-perf_format_group.patch @@ -0,0 +1,81 @@ +From: Peter Zijlstra <peterz@infradead.org> +Date: Tue, 30 May 2017 11:45:12 +0200 +Subject: perf/core: Correct event creation with PERF_FORMAT_GROUP + +commit ba5213ae6b88fb170c4771fef6553f759c7d8cdd upstream. + +Andi was asking about PERF_FORMAT_GROUP vs inherited events, which led +to the discovery of a bug from commit: + + 3dab77fb1bf8 ("perf: Rework/fix the whole read vs group stuff") + + - PERF_SAMPLE_GROUP = 1U << 4, + + PERF_SAMPLE_READ = 1U << 4, + + - if (attr->inherit && (attr->sample_type & PERF_SAMPLE_GROUP)) + + if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP)) + +is a clear fail :/ + +While this changes user visible behaviour; it was previously possible +to create an inherited event with PERF_SAMPLE_READ; this is deemed +acceptible because its results were always incorrect. + +Reported-by: Andi Kleen <ak@linux.intel.com> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> +Cc: Arnaldo Carvalho de Melo <acme@kernel.org> +Cc: Jiri Olsa <jolsa@kernel.org> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Stephane Eranian <eranian@google.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Vince Weaver <vince@deater.net> +Fixes: 3dab77fb1bf8 ("perf: Rework/fix the whole read vs group stuff") +Link: http://lkml.kernel.org/r/20170530094512.dy2nljns2uq7qa3j@hirez.programming.kicks-ass.net +Signed-off-by: Ingo Molnar <mingo@kernel.org> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/events/core.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -4240,9 +4240,6 @@ static void perf_output_read_one(struct + __output_copy(handle, values, n * sizeof(u64)); + } + +-/* +- * XXX PERF_FORMAT_GROUP vs inherited events seems difficult. +- */ + static void perf_output_read_group(struct perf_output_handle *handle, + struct perf_event *event, + u64 enabled, u64 running) +@@ -4286,6 +4283,13 @@ static void perf_output_read_group(struc + #define PERF_FORMAT_TOTAL_TIMES (PERF_FORMAT_TOTAL_TIME_ENABLED|\ + PERF_FORMAT_TOTAL_TIME_RUNNING) + ++/* ++ * XXX PERF_SAMPLE_READ vs inherited events seems difficult. ++ * ++ * The problem is that its both hard and excessively expensive to iterate the ++ * child list, not to mention that its impossible to IPI the children running ++ * on another CPU, from interrupt/NMI context. ++ */ + static void perf_output_read(struct perf_output_handle *handle, + struct perf_event *event) + { +@@ -6284,9 +6288,10 @@ perf_event_alloc(struct perf_event_attr + local64_set(&hwc->period_left, hwc->sample_period); + + /* +- * we currently do not support PERF_FORMAT_GROUP on inherited events ++ * We currently do not support PERF_SAMPLE_READ on inherited events. ++ * See perf_output_read(). + */ +- if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP)) ++ if (attr->inherit && (attr->sample_type & PERF_SAMPLE_READ)) + goto done; + + pmu = perf_init_event(event); diff --git a/releases/3.2.94/perf-x86-check-if-user-fp-is-valid.patch b/releases/3.2.94/perf-x86-check-if-user-fp-is-valid.patch new file mode 100644 index 00000000..d7cc706b --- /dev/null +++ b/releases/3.2.94/perf-x86-check-if-user-fp-is-valid.patch @@ -0,0 +1,93 @@ +From: Arun Sharma <asharma@fb.com> +Date: Fri, 20 Apr 2012 15:41:35 -0700 +Subject: perf/x86: Check if user fp is valid + +commit bc6ca7b342d5ae15c3ba3081fd40271b8039fb25 upstream. + +Signed-off-by: Arun Sharma <asharma@fb.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> +Link: http://lkml.kernel.org/r/1334961696-19580-4-git-send-email-asharma@fb.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +[bwh: Backported to 3.2: also add user_addr_max() macro] +Cc: Jann Horn <jannh@google.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/arch/x86/include/asm/uaccess.h ++++ b/arch/x86/include/asm/uaccess.h +@@ -32,9 +32,9 @@ + + #define segment_eq(a, b) ((a).seg == (b).seg) + +-#define __addr_ok(addr) \ +- ((unsigned long __force)(addr) < \ +- (current_thread_info()->addr_limit.seg)) ++#define user_addr_max() (current_thread_info()->addr_limit.seg) ++#define __addr_ok(addr) \ ++ ((unsigned long __force)(addr) < user_addr_max()) + + /* + * Test whether a block of memory is a valid user space address. +@@ -46,14 +46,14 @@ + * This needs 33-bit (65-bit for x86_64) arithmetic. We have a carry... + */ + +-#define __range_not_ok(addr, size) \ ++#define __range_not_ok(addr, size, limit) \ + ({ \ + unsigned long flag, roksum; \ + __chk_user_ptr(addr); \ + asm("add %3,%1 ; sbb %0,%0 ; cmp %1,%4 ; sbb $0,%0" \ + : "=&r" (flag), "=r" (roksum) \ + : "1" (addr), "g" ((long)(size)), \ +- "rm" (current_thread_info()->addr_limit.seg)); \ ++ "rm" (limit)); \ + flag; \ + }) + +@@ -76,7 +76,8 @@ + * checks that the pointer is in the user space range - after calling + * this function, memory access functions may still return -EFAULT. + */ +-#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0)) ++#define access_ok(type, addr, size) \ ++ (likely(__range_not_ok(addr, size, user_addr_max()) == 0)) + + /* + * The exception table consists of pairs of addresses: the first is the +--- a/arch/x86/kernel/cpu/perf_event.c ++++ b/arch/x86/kernel/cpu/perf_event.c +@@ -1461,6 +1461,12 @@ perf_callchain_kernel(struct perf_callch + dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry); + } + ++static inline int ++valid_user_frame(const void __user *fp, unsigned long size) ++{ ++ return (__range_not_ok(fp, size, TASK_SIZE) == 0); ++} ++ + #ifdef CONFIG_COMPAT + static inline int + perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) +@@ -1485,6 +1491,9 @@ perf_callchain_user32(struct pt_regs *re + if (fp < compat_ptr(regs->sp)) + break; + ++ if (!valid_user_frame(fp, sizeof(frame))) ++ break; ++ + perf_callchain_store(entry, frame.return_address); + fp = compat_ptr(frame.next_frame); + } +@@ -1531,6 +1540,9 @@ perf_callchain_user(struct perf_callchai + if ((unsigned long)fp < regs->sp) + break; + ++ if (!valid_user_frame(fp, sizeof(frame))) ++ break; ++ + perf_callchain_store(entry, frame.return_address); + fp = frame.next_frame; + } diff --git a/releases/3.2.94/pm-domains-fix-unsafe-iteration-over-modified-list-of-device-links.patch b/releases/3.2.94/pm-domains-fix-unsafe-iteration-over-modified-list-of-device-links.patch new file mode 100644 index 00000000..e01bc8ca --- /dev/null +++ b/releases/3.2.94/pm-domains-fix-unsafe-iteration-over-modified-list-of-device-links.patch @@ -0,0 +1,39 @@ +From: Krzysztof Kozlowski <krzk@kernel.org> +Date: Wed, 28 Jun 2017 16:56:18 +0200 +Subject: PM / Domains: Fix unsafe iteration over modified list of device links + +commit c6e83cac3eda5f7dd32ee1453df2f7abb5c6cd46 upstream. + +pm_genpd_remove_subdomain() iterates over domain's master_links list and +removes matching element thus it has to use safe version of list +iteration. + +Fixes: f721889ff65a ("PM / Domains: Support for generic I/O PM domains (v8)") +Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> +Acked-by: Ulf Hansson <ulf.hansson@linaro.org> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/base/power/domain.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/base/power/domain.c ++++ b/drivers/base/power/domain.c +@@ -1240,7 +1240,7 @@ int pm_genpd_add_subdomain(struct generi + int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, + struct generic_pm_domain *subdomain) + { +- struct gpd_link *link; ++ struct gpd_link *l, *link; + int ret = -EINVAL; + + if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)) +@@ -1249,7 +1249,7 @@ int pm_genpd_remove_subdomain(struct gen + start: + genpd_acquire_lock(genpd); + +- list_for_each_entry(link, &genpd->master_links, master_node) { ++ list_for_each_entry_safe(link, l, &genpd->master_links, master_node) { + if (link->slave != subdomain) + continue; + diff --git a/releases/3.2.94/powerpc-asm-mark-cr0-as-clobbered-in-mftb.patch b/releases/3.2.94/powerpc-asm-mark-cr0-as-clobbered-in-mftb.patch new file mode 100644 index 00000000..fd1a5350 --- /dev/null +++ b/releases/3.2.94/powerpc-asm-mark-cr0-as-clobbered-in-mftb.patch @@ -0,0 +1,34 @@ +From: Oliver O'Halloran <oohall@gmail.com> +Date: Thu, 6 Jul 2017 18:46:43 +1000 +Subject: powerpc/asm: Mark cr0 as clobbered in mftb() + +commit 2400fd822f467cb4c886c879d8ad99feac9cf319 upstream. + +The workaround for the CELL timebase bug does not correctly mark cr0 as +being clobbered. This means GCC doesn't know that the asm block changes cr0 and +might leave the result of an unrelated comparison in cr0 across the block, which +we then trash, leading to basically random behaviour. + +Fixes: 859deea949c3 ("[POWERPC] Cell timebase bug workaround") +Signed-off-by: Oliver O'Halloran <oohall@gmail.com> +[mpe: Tweak change log and flag for stable] +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/include/asm/reg.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/powerpc/include/asm/reg.h ++++ b/arch/powerpc/include/asm/reg.h +@@ -1054,7 +1054,9 @@ + " .llong 0\n" \ + " .llong 0\n" \ + ".previous" \ +- : "=r" (rval) : "i" (CPU_FTR_CELL_TB_BUG)); rval;}) ++ : "=r" (rval) \ ++ : "i" (CPU_FTR_CELL_TB_BUG) : "cr0"); \ ++ rval;}) + #else + #define mftb() ({unsigned long rval; \ + asm volatile("mftb %0" : "=r" (rval)); rval;}) diff --git a/releases/3.2.94/powerpc-fix-emulation-of-mfocrf-in-emulate_step.patch b/releases/3.2.94/powerpc-fix-emulation-of-mfocrf-in-emulate_step.patch new file mode 100644 index 00000000..e05bf764 --- /dev/null +++ b/releases/3.2.94/powerpc-fix-emulation-of-mfocrf-in-emulate_step.patch @@ -0,0 +1,44 @@ +From: Anton Blanchard <anton@samba.org> +Date: Thu, 15 Jun 2017 09:46:39 +1000 +Subject: powerpc: Fix emulation of mfocrf in emulate_step() + +commit 64e756c55aa46fc18fd53e8f3598b73b528d8637 upstream. + +From POWER4 onwards, mfocrf() only places the specified CR field into +the destination GPR, and the rest of it is set to 0. The PowerPC AS +from version 3.0 now requires this behaviour. + +The emulation code currently puts the entire CR into the destination GPR. +Fix it. + +Fixes: 6888199f7fe5 ("[POWERPC] Emulate more instructions in software") +Signed-off-by: Anton Blanchard <anton@samba.org> +Acked-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/lib/sstep.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/arch/powerpc/lib/sstep.c ++++ b/arch/powerpc/lib/sstep.c +@@ -863,6 +863,19 @@ int __kprobes emulate_step(struct pt_reg + goto instr_done; + #endif + case 19: /* mfcr */ ++ if ((instr >> 20) & 1) { ++ imm = 0xf0000000UL; ++ for (sh = 0; sh < 8; ++sh) { ++ if (instr & (0x80000 >> sh)) { ++ regs->gpr[rd] = regs->ccr & imm; ++ break; ++ } ++ imm >>= 4; ++ } ++ ++ goto instr_done; ++ } ++ + regs->gpr[rd] = regs->ccr; + regs->gpr[rd] &= 0xffffffffUL; + goto instr_done; diff --git a/releases/3.2.94/rdma-uverbs-check-port-number-supplied-by-user-verbs-cmds.patch b/releases/3.2.94/rdma-uverbs-check-port-number-supplied-by-user-verbs-cmds.patch new file mode 100644 index 00000000..693e741c --- /dev/null +++ b/releases/3.2.94/rdma-uverbs-check-port-number-supplied-by-user-verbs-cmds.patch @@ -0,0 +1,77 @@ +From: Boris Pismenny <borisp@mellanox.com> +Date: Tue, 27 Jun 2017 15:09:13 +0300 +Subject: RDMA/uverbs: Check port number supplied by user verbs cmds + +commit 5ecce4c9b17bed4dc9cb58bfb10447307569b77b upstream. + +The ib_uverbs_create_ah() ind ib_uverbs_modify_qp() calls receive +the port number from user input as part of its attributes and assumes +it is valid. Down on the stack, that parameter is used to access kernel +data structures. If the value is invalid, the kernel accesses memory +it should not. To prevent this, verify the port number before using it. + +BUG: KASAN: use-after-free in ib_uverbs_create_ah+0x6d5/0x7b0 +Read of size 4 at addr ffff880018d67ab8 by task syz-executor/313 + +BUG: KASAN: slab-out-of-bounds in modify_qp.isra.4+0x19d0/0x1ef0 +Read of size 4 at addr ffff88006c40ec58 by task syz-executor/819 + +Fixes: 67cdb40ca444 ("[IB] uverbs: Implement more commands") +Fixes: 189aba99e70 ("IB/uverbs: Extend modify_qp and support packet pacing") +Cc: <security@kernel.org> +Cc: Yevgeny Kliteynik <kliteyn@mellanox.com> +Cc: Tziporet Koren <tziporet@mellanox.com> +Cc: Alex Polak <alexpo@mellanox.com> +Signed-off-by: Boris Pismenny <borisp@mellanox.com> +Signed-off-by: Leon Romanovsky <leon@kernel.org> +Signed-off-by: Doug Ledford <dledford@redhat.com> +[bwh: Backported to 3.2: + - In modify_qp(), command structure is cmd not cmd->base + - In modify_qp(), add release_qp label + - In ib_uverbs_create_ah(), add definition of ib_dev + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/infiniband/core/uverbs_cmd.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -1790,6 +1790,11 @@ ssize_t ib_uverbs_modify_qp(struct ib_uv + goto out; + } + ++ if (!rdma_is_port_valid(qp->device, cmd.port_num)) { ++ ret = -EINVAL; ++ goto release_qp; ++ } ++ + attr->qp_state = cmd.qp_state; + attr->cur_qp_state = cmd.cur_qp_state; + attr->path_mtu = cmd.path_mtu; +@@ -1843,6 +1848,7 @@ ssize_t ib_uverbs_modify_qp(struct ib_uv + ret = ib_modify_qp(qp, attr, modify_qp_mask(qp->qp_type, cmd.attr_mask)); + } + ++release_qp: + put_qp_read(qp); + + if (ret) +@@ -2262,6 +2268,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uv + const char __user *buf, int in_len, + int out_len) + { ++ struct ib_device *ib_dev = file->device->ib_dev; + struct ib_uverbs_create_ah cmd; + struct ib_uverbs_create_ah_resp resp; + struct ib_uobject *uobj; +@@ -2276,6 +2283,9 @@ ssize_t ib_uverbs_create_ah(struct ib_uv + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + ++ if (!rdma_is_port_valid(ib_dev, cmd.attr.port_num)) ++ return -EINVAL; ++ + uobj = kmalloc(sizeof *uobj, GFP_KERNEL); + if (!uobj) + return -ENOMEM; diff --git a/releases/3.2.94/reiserfs-don-t-clear-sgid-when-inheriting-acls.patch b/releases/3.2.94/reiserfs-don-t-clear-sgid-when-inheriting-acls.patch new file mode 100644 index 00000000..cf4a6b3e --- /dev/null +++ b/releases/3.2.94/reiserfs-don-t-clear-sgid-when-inheriting-acls.patch @@ -0,0 +1,107 @@ +From: Jan Kara <jack@suse.cz> +Date: Thu, 22 Jun 2017 09:32:49 +0200 +Subject: reiserfs: Don't clear SGID when inheriting ACLs + +commit 6883cd7f68245e43e91e5ee583b7550abf14523f upstream. + +When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit +set, DIR1 is expected to have SGID bit set (and owning group equal to +the owning group of 'DIR0'). However when 'DIR0' also has some default +ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on +'DIR1' to get cleared if user is not member of the owning group. + +Fix the problem by moving posix_acl_update_mode() out of +__reiserfs_set_acl() into reiserfs_set_acl(). That way the function will +not be called when inheriting ACLs which is what we want as it prevents +SGID bit clearing and the mode has been properly set by +posix_acl_create() anyway. + +Fixes: 073931017b49d9458aa351605b43a7e34598caef +CC: reiserfs-devel@vger.kernel.org +Signed-off-by: Jan Kara <jack@suse.cz> +[bwh: Backported to 3.2: the __reiserfs_set_acl() function didn't exist, + so added it] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/reiserfs/xattr_acl.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/fs/reiserfs/xattr_acl.c ++++ b/fs/reiserfs/xattr_acl.c +@@ -250,15 +250,9 @@ struct posix_acl *reiserfs_get_acl(struc + return acl; + } + +-/* +- * Inode operation set_posix_acl(). +- * +- * inode->i_mutex: down +- * BKL held [before 2.5.x] +- */ + static int +-reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, +- int type, struct posix_acl *acl) ++__reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, ++ int type, struct posix_acl *acl) + { + char *name; + void *value = NULL; +@@ -271,11 +265,6 @@ reiserfs_set_acl(struct reiserfs_transac + switch (type) { + case ACL_TYPE_ACCESS: + name = POSIX_ACL_XATTR_ACCESS; +- if (acl) { +- error = posix_acl_update_mode(inode, &inode->i_mode, &acl); +- if (error) +- return error; +- } + break; + case ACL_TYPE_DEFAULT: + name = POSIX_ACL_XATTR_DEFAULT; +@@ -316,6 +305,26 @@ reiserfs_set_acl(struct reiserfs_transac + return error; + } + ++/* ++ * Inode operation set_posix_acl(). ++ * ++ * inode->i_mutex: down ++ */ ++static int ++reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, ++ int type, struct posix_acl *acl) ++{ ++ int error; ++ ++ if (type == ACL_TYPE_ACCESS && acl) { ++ error = posix_acl_update_mode(inode, &inode->i_mode, ++ &acl); ++ if (error) ++ return error; ++ } ++ return __reiserfs_set_acl(th, inode, type, acl); ++} ++ + /* dir->i_mutex: locked, + * inode is new and not released into the wild yet */ + int +@@ -350,8 +359,8 @@ reiserfs_inherit_default_acl(struct reis + if (acl) { + /* Copy the default ACL to the default ACL of a new directory */ + if (S_ISDIR(inode->i_mode)) { +- err = reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT, +- acl); ++ err = __reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT, ++ acl); + if (err) + goto cleanup; + } +@@ -364,7 +373,7 @@ reiserfs_inherit_default_acl(struct reis + + /* If we need an ACL.. */ + if (err > 0) +- err = reiserfs_set_acl(th, inode, ACL_TYPE_ACCESS, acl); ++ err = __reiserfs_set_acl(th, inode, ACL_TYPE_ACCESS, acl); + cleanup: + posix_acl_release(acl); + } else { diff --git a/releases/3.2.94/reiserfs-preserve-i_mode-if-__reiserfs_set_acl-fails.patch b/releases/3.2.94/reiserfs-preserve-i_mode-if-__reiserfs_set_acl-fails.patch new file mode 100644 index 00000000..ac435e83 --- /dev/null +++ b/releases/3.2.94/reiserfs-preserve-i_mode-if-__reiserfs_set_acl-fails.patch @@ -0,0 +1,51 @@ +From: =?UTF-8?q?Ernesto=20A=2E=20Fern=C3=A1ndez?= + <ernesto.mnd.fernandez@gmail.com> +Date: Mon, 17 Jul 2017 18:42:41 +0200 +Subject: reiserfs: preserve i_mode if __reiserfs_set_acl() fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit fcea8aed91f53b51f9b943dc01f12d8aa666c720 upstream. + +When changing a file's acl mask, reiserfs_set_acl() will first set the +group bits of i_mode to the value of the mask, and only then set the +actual extended attribute representing the new acl. + +If the second part fails (due to lack of space, for example) and the +file had no acl attribute to begin with, the system will from now on +assume that the mask permission bits are actual group permission bits, +potentially granting access to the wrong users. + +Prevent this by only changing the inode mode after the acl has been set. + +Signed-off-by: Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com> +Signed-off-by: Jan Kara <jack@suse.cz> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/fs/reiserfs/xattr_acl.c ++++ b/fs/reiserfs/xattr_acl.c +@@ -315,14 +315,19 @@ reiserfs_set_acl(struct reiserfs_transac + int type, struct posix_acl *acl) + { + int error; ++ int update_mode = 0; ++ umode_t mode = inode->i_mode; + + if (type == ACL_TYPE_ACCESS && acl) { +- error = posix_acl_update_mode(inode, &inode->i_mode, +- &acl); ++ error = posix_acl_update_mode(inode, &mode, &acl); + if (error) + return error; ++ update_mode = 1; + } +- return __reiserfs_set_acl(th, inode, type, acl); ++ error = __reiserfs_set_acl(th, inode, type, acl); ++ if (!error && update_mode) ++ inode->i_mode = mode; ++ return error; + } + + /* dir->i_mutex: locked, diff --git a/releases/3.2.94/rtc-rtc-nuc900-fix-loop-timeout-test.patch b/releases/3.2.94/rtc-rtc-nuc900-fix-loop-timeout-test.patch new file mode 100644 index 00000000..4bf73f75 --- /dev/null +++ b/releases/3.2.94/rtc-rtc-nuc900-fix-loop-timeout-test.patch @@ -0,0 +1,28 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Fri, 23 Jun 2017 11:29:00 +0300 +Subject: rtc: rtc-nuc900: fix loop timeout test + +commit d0a67c372df410b579197ea818596001fe20070d upstream. + +We should change this post-op to a pre-op because we want the loop to +exit with "timeout" set to zero. + +Fixes: 0a89b55364e0 ("nuc900/rtc: change the waiting for device ready implement") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/rtc/rtc-nuc900.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/rtc/rtc-nuc900.c ++++ b/drivers/rtc/rtc-nuc900.c +@@ -93,7 +93,7 @@ static int *check_rtc_access_enable(stru + __raw_writel(AERPOWERON, nuc900_rtc->rtc_reg + REG_RTC_AER); + + while (!(__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_AER) & AERRWENB) +- && timeout--) ++ && --timeout) + mdelay(1); + + if (!timeout) diff --git a/releases/3.2.94/s390-syscalls-fix-out-of-bounds-arguments-access.patch b/releases/3.2.94/s390-syscalls-fix-out-of-bounds-arguments-access.patch new file mode 100644 index 00000000..f819a5ab --- /dev/null +++ b/releases/3.2.94/s390-syscalls-fix-out-of-bounds-arguments-access.patch @@ -0,0 +1,54 @@ +From: Jiri Olsa <jolsa@kernel.org> +Date: Thu, 29 Jun 2017 11:38:11 +0200 +Subject: s390/syscalls: Fix out of bounds arguments access + +commit c46fc0424ced3fb71208e72bd597d91b9169a781 upstream. + +Zorro reported following crash while having enabled +syscall tracing (CONFIG_FTRACE_SYSCALLS): + + Unable to handle kernel pointer dereference at virtual ... + Oops: 0011 [#1] SMP DEBUG_PAGEALLOC + + SNIP + + Call Trace: + ([<000000000024d79c>] ftrace_syscall_enter+0xec/0x1d8) + [<00000000001099c6>] do_syscall_trace_enter+0x236/0x2f8 + [<0000000000730f1c>] sysc_tracesys+0x1a/0x32 + [<000003fffcf946a2>] 0x3fffcf946a2 + INFO: lockdep is turned off. + Last Breaking-Event-Address: + [<000000000022dd44>] rb_event_data+0x34/0x40 + ---[ end trace 8c795f86b1b3f7b9 ]--- + +The crash happens in syscall_get_arguments function for +syscalls with zero arguments, that will try to access +first argument (args[0]) in event entry, but it's not +allocated. + +Bail out of there are no arguments. + +Reported-by: Zorro Lang <zlang@redhat.com> +Signed-off-by: Jiri Olsa <jolsa@kernel.org> +Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/s390/include/asm/syscall.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/s390/include/asm/syscall.h ++++ b/arch/s390/include/asm/syscall.h +@@ -62,6 +62,12 @@ static inline void syscall_get_arguments + { + unsigned long mask = -1UL; + ++ /* ++ * No arguments for this syscall, there's nothing to do. ++ */ ++ if (!n) ++ return; ++ + BUG_ON(i + n > 6); + #ifdef CONFIG_COMPAT + if (test_tsk_thread_flag(task, TIF_31BIT)) diff --git a/releases/3.2.94/saa7164-fix-double-fetch-pcie-access-condition.patch b/releases/3.2.94/saa7164-fix-double-fetch-pcie-access-condition.patch new file mode 100644 index 00000000..77c09330 --- /dev/null +++ b/releases/3.2.94/saa7164-fix-double-fetch-pcie-access-condition.patch @@ -0,0 +1,74 @@ +From: Steven Toth <stoth@kernellabs.com> +Date: Tue, 6 Jun 2017 09:30:27 -0300 +Subject: [media] saa7164: fix double fetch PCIe access condition + +commit 6fb05e0dd32e566facb96ea61a48c7488daa5ac3 upstream. + +Avoid a double fetch by reusing the values from the prior transfer. + +Originally reported via https://bugzilla.kernel.org/show_bug.cgi?id=195559 + +Thanks to Pengfei Wang <wpengfeinudt@gmail.com> for reporting. + +Signed-off-by: Steven Toth <stoth@kernellabs.com> +Reported-by: Pengfei Wang <wpengfeinudt@gmail.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> +[bwh: Backported to 3.2: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/video/saa7164/saa7164-bus.c | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) + +--- a/drivers/media/video/saa7164/saa7164-bus.c ++++ b/drivers/media/video/saa7164/saa7164-bus.c +@@ -393,11 +393,11 @@ int saa7164_bus_get(struct saa7164_dev * + msg_tmp.size = le16_to_cpu((__force __le16)msg_tmp.size); + msg_tmp.command = le32_to_cpu((__force __le32)msg_tmp.command); + msg_tmp.controlselector = le16_to_cpu((__force __le16)msg_tmp.controlselector); ++ memcpy(msg, &msg_tmp, sizeof(*msg)); + + /* No need to update the read positions, because this was a peek */ + /* If the caller specifically want to peek, return */ + if (peekonly) { +- memcpy(msg, &msg_tmp, sizeof(*msg)); + goto peekout; + } + +@@ -442,21 +442,15 @@ int saa7164_bus_get(struct saa7164_dev * + space_rem = bus->m_dwSizeGetRing - curr_grp; + + if (space_rem < sizeof(*msg)) { +- /* msg wraps around the ring */ +- memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, space_rem); +- memcpy_fromio((u8 *)msg + space_rem, bus->m_pdwGetRing, +- sizeof(*msg) - space_rem); + if (buf) + memcpy_fromio(buf, bus->m_pdwGetRing + sizeof(*msg) - + space_rem, buf_size); + + } else if (space_rem == sizeof(*msg)) { +- memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); + if (buf) + memcpy_fromio(buf, bus->m_pdwGetRing, buf_size); + } else { + /* Additional data wraps around the ring */ +- memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); + if (buf) { + memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + + sizeof(*msg), space_rem - sizeof(*msg)); +@@ -469,15 +463,10 @@ int saa7164_bus_get(struct saa7164_dev * + + } else { + /* No wrapping */ +- memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); + if (buf) + memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg), + buf_size); + } +- /* Convert from little endian to CPU */ +- msg->size = le16_to_cpu((__force __le16)msg->size); +- msg->command = le32_to_cpu((__force __le32)msg->command); +- msg->controlselector = le16_to_cpu((__force __le16)msg->controlselector); + + /* Update the read positions, adjusting the ring */ + saa7164_writel(bus->m_dwGetReadPos, new_grp); diff --git a/releases/3.2.94/saa7164-fix-endian-conversion-in-saa7164_bus_set.patch b/releases/3.2.94/saa7164-fix-endian-conversion-in-saa7164_bus_set.patch new file mode 100644 index 00000000..e4b9b214 --- /dev/null +++ b/releases/3.2.94/saa7164-fix-endian-conversion-in-saa7164_bus_set.patch @@ -0,0 +1,39 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Mon, 28 Nov 2011 09:08:53 -0300 +Subject: [media] saa7164: fix endian conversion in saa7164_bus_set() + +commit 773ddbd228dc16a4829836e1dc16383e44c8575e upstream. + +The msg->command field is 32 bits, and we should fill it with a call +to cpu_to_le32(). The current code is broke on big endian systems. +On little endian systems it truncates the 32 bit value to 16 bits +which probably still works fine. + +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Cc: Steven Toth <stoth@kernellabs.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/video/saa7164/saa7164-bus.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/video/saa7164/saa7164-bus.c ++++ b/drivers/media/video/saa7164/saa7164-bus.c +@@ -149,7 +149,7 @@ int saa7164_bus_set(struct saa7164_dev * + saa7164_bus_verify(dev); + + msg->size = cpu_to_le16(msg->size); +- msg->command = cpu_to_le16(msg->command); ++ msg->command = cpu_to_le32(msg->command); + msg->controlselector = cpu_to_le16(msg->controlselector); + + if (msg->size > dev->bus.m_wMaxReqSize) { +@@ -464,7 +464,7 @@ int saa7164_bus_get(struct saa7164_dev * + + peekout: + msg->size = le16_to_cpu(msg->size); +- msg->command = le16_to_cpu(msg->command); ++ msg->command = le32_to_cpu(msg->command); + msg->controlselector = le16_to_cpu(msg->controlselector); + ret = SAA_OK; + out: diff --git a/releases/3.2.94/saa7164-fix-sparse-warnings.patch b/releases/3.2.94/saa7164-fix-sparse-warnings.patch new file mode 100644 index 00000000..ee6a5fb1 --- /dev/null +++ b/releases/3.2.94/saa7164-fix-sparse-warnings.patch @@ -0,0 +1,475 @@ +From: Hans Verkuil <hverkuil@xs4all.nl> +Date: Fri, 7 Nov 2014 11:39:46 -0300 +Subject: [media] saa7164: fix sparse warnings + +commit 065e1477d277174242e73e7334c717b840d0693f upstream. + +Fix many sparse warnings: + +drivers/media/pci/saa7164/saa7164-core.c:97:18: warning: cast removes address space of expression +drivers/media/pci/saa7164/saa7164-core.c:122:31: warning: cast removes address space of expression +drivers/media/pci/saa7164/saa7164-core.c:122:31: warning: incorrect type in initializer (different address spaces) +drivers/media/pci/saa7164/saa7164-core.c:122:31: expected unsigned char [noderef] [usertype] <asn:2>*bufcpu +drivers/media/pci/saa7164/saa7164-core.c:122:31: got unsigned char [usertype] *<noident> +drivers/media/pci/saa7164/saa7164-core.c:282:44: warning: cast removes address space of expression +drivers/media/pci/saa7164/saa7164-core.c:286:38: warning: cast removes address space of expression +drivers/media/pci/saa7164/saa7164-core.c:286:35: warning: incorrect type in assignment (different address spaces) +drivers/media/pci/saa7164/saa7164-core.c:286:35: expected unsigned char [noderef] [usertype] <asn:2>*p +drivers/media/pci/saa7164/saa7164-core.c:286:35: got unsigned char [usertype] *<noident> +drivers/media/pci/saa7164/saa7164-core.c:352:44: warning: cast removes address space of expression +drivers/media/pci/saa7164/saa7164-core.c:527:53: warning: cast removes address space of expression +drivers/media/pci/saa7164/saa7164-core.c:129:30: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-core.c:133:38: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-core.c:133:72: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-core.c:134:35: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-core.c:287:61: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-core.c:288:65: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-core.c:289:65: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-core.c:290:65: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-core.c:291:65: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-core.c:292:65: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-core.c:293:65: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-core.c:294:65: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-fw.c:548:52: warning: incorrect type in argument 5 (different address spaces) +drivers/media/pci/saa7164/saa7164-fw.c:548:52: expected unsigned char [usertype] *dst +drivers/media/pci/saa7164/saa7164-fw.c:548:52: got unsigned char [noderef] [usertype] <asn:2>* +drivers/media/pci/saa7164/saa7164-fw.c:579:44: warning: incorrect type in argument 5 (different address spaces) +drivers/media/pci/saa7164/saa7164-fw.c:579:44: expected unsigned char [usertype] *dst +drivers/media/pci/saa7164/saa7164-fw.c:579:44: got unsigned char [noderef] [usertype] <asn:2>* +drivers/media/pci/saa7164/saa7164-fw.c:597:44: warning: incorrect type in argument 5 (different address spaces) +drivers/media/pci/saa7164/saa7164-fw.c:597:44: expected unsigned char [usertype] *dst +drivers/media/pci/saa7164/saa7164-fw.c:597:44: got unsigned char [noderef] [usertype] <asn:2>* +drivers/media/pci/saa7164/saa7164-bus.c:36:36: warning: cast removes address space of expression +drivers/media/pci/saa7164/saa7164-bus.c:41:36: warning: cast removes address space of expression +drivers/media/pci/saa7164/saa7164-bus.c:151:19: warning: incorrect type in assignment (different base types) +drivers/media/pci/saa7164/saa7164-bus.c:151:19: expected unsigned short [unsigned] [usertype] size +drivers/media/pci/saa7164/saa7164-bus.c:151:19: got restricted __le16 [usertype] <noident> +drivers/media/pci/saa7164/saa7164-bus.c:152:22: warning: incorrect type in assignment (different base types) +drivers/media/pci/saa7164/saa7164-bus.c:152:22: expected unsigned int [unsigned] [usertype] command +drivers/media/pci/saa7164/saa7164-bus.c:152:22: got restricted __le32 [usertype] <noident> +drivers/media/pci/saa7164/saa7164-bus.c:153:30: warning: incorrect type in assignment (different base types) +drivers/media/pci/saa7164/saa7164-bus.c:153:30: expected unsigned short [unsigned] [usertype] controlselector +drivers/media/pci/saa7164/saa7164-bus.c:153:30: got restricted __le16 [usertype] <noident> +drivers/media/pci/saa7164/saa7164-bus.c:172:20: warning: cast to restricted __le32 +drivers/media/pci/saa7164/saa7164-bus.c:173:20: warning: cast to restricted __le32 +drivers/media/pci/saa7164/saa7164-bus.c:206:28: warning: cast to restricted __le32 +drivers/media/pci/saa7164/saa7164-bus.c:287:9: warning: incorrect type in argument 1 (different base types) +drivers/media/pci/saa7164/saa7164-bus.c:287:9: expected unsigned int [unsigned] val +drivers/media/pci/saa7164/saa7164-bus.c:287:9: got restricted __le32 [usertype] <noident> +drivers/media/pci/saa7164/saa7164-bus.c:339:20: warning: cast to restricted __le32 +drivers/media/pci/saa7164/saa7164-bus.c:340:20: warning: cast to restricted __le32 +drivers/media/pci/saa7164/saa7164-bus.c:463:9: warning: incorrect type in argument 1 (different base types) +drivers/media/pci/saa7164/saa7164-bus.c:463:9: expected unsigned int [unsigned] val +drivers/media/pci/saa7164/saa7164-bus.c:463:9: got restricted __le32 [usertype] <noident> +drivers/media/pci/saa7164/saa7164-bus.c:466:21: warning: cast to restricted __le16 +drivers/media/pci/saa7164/saa7164-bus.c:467:24: warning: cast to restricted __le32 +drivers/media/pci/saa7164/saa7164-bus.c:468:32: warning: cast to restricted __le16 +drivers/media/pci/saa7164/saa7164-buffer.c:122:18: warning: incorrect type in assignment (different address spaces) +drivers/media/pci/saa7164/saa7164-buffer.c:122:18: expected unsigned long long [noderef] [usertype] <asn:2>*cpu +drivers/media/pci/saa7164/saa7164-buffer.c:122:18: got void * +drivers/media/pci/saa7164/saa7164-buffer.c:127:21: warning: incorrect type in assignment (different address spaces) +drivers/media/pci/saa7164/saa7164-buffer.c:127:21: expected unsigned long long [noderef] [usertype] <asn:2>*pt_cpu +drivers/media/pci/saa7164/saa7164-buffer.c:127:21: got void * +drivers/media/pci/saa7164/saa7164-buffer.c:134:20: warning: cast removes address space of expression +drivers/media/pci/saa7164/saa7164-buffer.c:156:63: warning: incorrect type in argument 3 (different address spaces) +drivers/media/pci/saa7164/saa7164-buffer.c:156:63: expected void *vaddr +drivers/media/pci/saa7164/saa7164-buffer.c:156:63: got unsigned long long [noderef] [usertype] <asn:2>*cpu +drivers/media/pci/saa7164/saa7164-buffer.c:179:57: warning: incorrect type in argument 3 (different address spaces) +drivers/media/pci/saa7164/saa7164-buffer.c:179:57: expected void *vaddr +drivers/media/pci/saa7164/saa7164-buffer.c:179:57: got unsigned long long [noderef] [usertype] <asn:2>*cpu +drivers/media/pci/saa7164/saa7164-buffer.c:180:56: warning: incorrect type in argument 3 (different address spaces) +drivers/media/pci/saa7164/saa7164-buffer.c:180:56: expected void *vaddr +drivers/media/pci/saa7164/saa7164-buffer.c:180:56: got unsigned long long [noderef] [usertype] <asn:2>*pt_cpu +drivers/media/pci/saa7164/saa7164-buffer.c:84:17: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-buffer.c:147:31: warning: dereference of noderef expression +drivers/media/pci/saa7164/saa7164-buffer.c:148:17: warning: dereference of noderef expression + +Most are caused by pointers marked as __iomem when they aren't or not marked as +__iomem when they should. + +Also note that readl/writel already do endian conversion, so there is no need to +do it again. + +saa7164_bus_set/get were a bit tricky: you have to make sure the msg endian +conversion is done at the right time, and that the code isn't using fields that +are still little endian instead of cpu-endianness. + +The approach chosen is to convert just before writing to the ring buffer +and to convert it back right after reading from the ring buffer. + +Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> +Cc: Steven Toth <stoth@kernellabs.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com> +[bwh: Backported to 3.2: adjust filenames, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/video/saa7164/saa7164-buffer.c | 4 +- + drivers/media/video/saa7164/saa7164-bus.c | 101 +++++++++++++++++------------ + drivers/media/video/saa7164/saa7164-core.c | 13 ++-- + drivers/media/video/saa7164/saa7164-fw.c | 6 +- + drivers/media/video/saa7164/saa7164-types.h | 4 +- + drivers/media/video/saa7164/saa7164.h | 4 +- + 6 files changed, 74 insertions(+), 58 deletions(-) + +--- a/drivers/media/video/saa7164/saa7164-buffer.c ++++ b/drivers/media/video/saa7164/saa7164-buffer.c +@@ -130,9 +130,9 @@ struct saa7164_buffer *saa7164_buffer_al + goto fail2; + + /* init the buffers to a known pattern, easier during debugging */ +- memset_io(buf->cpu, 0xff, buf->pci_size); ++ memset(buf->cpu, 0xff, buf->pci_size); + buf->crc = crc32(0, buf->cpu, buf->actual_size); +- memset_io(buf->pt_cpu, 0xff, buf->pt_size); ++ memset(buf->pt_cpu, 0xff, buf->pt_size); + + dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p (%d pageptrs)\n", + __func__, buf, params->numpagetables); +--- a/drivers/media/video/saa7164/saa7164-bus.c ++++ b/drivers/media/video/saa7164/saa7164-bus.c +@@ -33,12 +33,12 @@ int saa7164_bus_setup(struct saa7164_dev + b->Type = TYPE_BUS_PCIe; + b->m_wMaxReqSize = SAA_DEVICE_MAXREQUESTSIZE; + +- b->m_pdwSetRing = (u8 *)(dev->bmmio + ++ b->m_pdwSetRing = (u8 __iomem *)(dev->bmmio + + ((u32)dev->busdesc.CommandRing)); + + b->m_dwSizeSetRing = SAA_DEVICE_BUFFERBLOCKSIZE; + +- b->m_pdwGetRing = (u8 *)(dev->bmmio + ++ b->m_pdwGetRing = (u8 __iomem *)(dev->bmmio + + ((u32)dev->busdesc.ResponseRing)); + + b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE; +@@ -138,6 +138,7 @@ int saa7164_bus_set(struct saa7164_dev * + u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp; + u32 new_swp, space_rem; + int ret = SAA_ERR_BAD_PARAMETER; ++ u16 size; + + if (!msg) { + printk(KERN_ERR "%s() !msg\n", __func__); +@@ -148,10 +149,6 @@ int saa7164_bus_set(struct saa7164_dev * + + saa7164_bus_verify(dev); + +- msg->size = cpu_to_le16(msg->size); +- msg->command = cpu_to_le32(msg->command); +- msg->controlselector = cpu_to_le16(msg->controlselector); +- + if (msg->size > dev->bus.m_wMaxReqSize) { + printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n", + __func__); +@@ -169,8 +166,8 @@ int saa7164_bus_set(struct saa7164_dev * + bytes_to_write = sizeof(*msg) + msg->size; + free_write_space = 0; + timeout = SAA_BUS_TIMEOUT; +- curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos)); +- curr_swp = le32_to_cpu(saa7164_readl(bus->m_dwSetWritePos)); ++ curr_srp = saa7164_readl(bus->m_dwSetReadPos); ++ curr_swp = saa7164_readl(bus->m_dwSetWritePos); + + /* Deal with ring wrapping issues */ + if (curr_srp > curr_swp) +@@ -203,7 +200,7 @@ int saa7164_bus_set(struct saa7164_dev * + mdelay(1); + + /* Check the space usage again */ +- curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos)); ++ curr_srp = saa7164_readl(bus->m_dwSetReadPos); + + /* Deal with ring wrapping issues */ + if (curr_srp > curr_swp) +@@ -223,6 +220,16 @@ int saa7164_bus_set(struct saa7164_dev * + dprintk(DBGLVL_BUS, "%s() bus->m_dwSizeSetRing = %x\n", __func__, + bus->m_dwSizeSetRing); + ++ /* ++ * Make a copy of msg->size before it is converted to le16 since it is ++ * used in the code below. ++ */ ++ size = msg->size; ++ /* Convert to le16/le32 */ ++ msg->size = (__force u16)cpu_to_le16(msg->size); ++ msg->command = (__force u32)cpu_to_le32(msg->command); ++ msg->controlselector = (__force u16)cpu_to_le16(msg->controlselector); ++ + /* Mental Note: line 462 tmmhComResBusPCIe.cpp */ + + /* Check if we're going to wrap again */ +@@ -243,28 +250,28 @@ int saa7164_bus_set(struct saa7164_dev * + dprintk(DBGLVL_BUS, "%s() tr4\n", __func__); + + /* Split the msg into pieces as the ring wraps */ +- memcpy(bus->m_pdwSetRing + curr_swp, msg, space_rem); +- memcpy(bus->m_pdwSetRing, (u8 *)msg + space_rem, ++ memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, space_rem); ++ memcpy_toio(bus->m_pdwSetRing, (u8 *)msg + space_rem, + sizeof(*msg) - space_rem); + +- memcpy(bus->m_pdwSetRing + sizeof(*msg) - space_rem, +- buf, msg->size); ++ memcpy_toio(bus->m_pdwSetRing + sizeof(*msg) - space_rem, ++ buf, size); + + } else if (space_rem == sizeof(*msg)) { + dprintk(DBGLVL_BUS, "%s() tr5\n", __func__); + + /* Additional data at the beginning of the ring */ +- memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); +- memcpy(bus->m_pdwSetRing, buf, msg->size); ++ memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); ++ memcpy_toio(bus->m_pdwSetRing, buf, size); + + } else { + /* Additional data wraps around the ring */ +- memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); +- if (msg->size > 0) { +- memcpy(bus->m_pdwSetRing + curr_swp + ++ memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); ++ if (size > 0) { ++ memcpy_toio(bus->m_pdwSetRing + curr_swp + + sizeof(*msg), buf, space_rem - + sizeof(*msg)); +- memcpy(bus->m_pdwSetRing, (u8 *)buf + ++ memcpy_toio(bus->m_pdwSetRing, (u8 *)buf + + space_rem - sizeof(*msg), + bytes_to_write - space_rem); + } +@@ -276,15 +283,20 @@ int saa7164_bus_set(struct saa7164_dev * + dprintk(DBGLVL_BUS, "%s() tr6\n", __func__); + + /* The ring buffer doesn't wrap, two simple copies */ +- memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); +- memcpy(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf, +- msg->size); ++ memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); ++ memcpy_toio(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf, ++ size); + } + + dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp); + + /* Update the bus write position */ +- saa7164_writel(bus->m_dwSetWritePos, cpu_to_le32(new_swp)); ++ saa7164_writel(bus->m_dwSetWritePos, new_swp); ++ ++ /* Convert back to cpu after writing the msg to the ringbuffer. */ ++ msg->size = le16_to_cpu((__force __le16)msg->size); ++ msg->command = le32_to_cpu((__force __le32)msg->command); ++ msg->controlselector = le16_to_cpu((__force __le16)msg->controlselector); + ret = SAA_OK; + + out: +@@ -336,8 +348,8 @@ int saa7164_bus_get(struct saa7164_dev * + /* Peek the bus to see if a msg exists, if it's not what we're expecting + * then return cleanly else read the message from the bus. + */ +- curr_gwp = le32_to_cpu(saa7164_readl(bus->m_dwGetWritePos)); +- curr_grp = le32_to_cpu(saa7164_readl(bus->m_dwGetReadPos)); ++ curr_gwp = saa7164_readl(bus->m_dwGetWritePos); ++ curr_grp = saa7164_readl(bus->m_dwGetReadPos); + + if (curr_gwp == curr_grp) { + ret = SAA_ERR_EMPTY; +@@ -369,14 +381,18 @@ int saa7164_bus_get(struct saa7164_dev * + new_grp -= bus->m_dwSizeGetRing; + space_rem = bus->m_dwSizeGetRing - curr_grp; + +- memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem); +- memcpy((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing, ++ memcpy_fromio(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem); ++ memcpy_fromio((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing, + bytes_to_read - space_rem); + + } else { + /* No wrapping */ +- memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read); ++ memcpy_fromio(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read); + } ++ /* Convert from little endian to CPU */ ++ msg_tmp.size = le16_to_cpu((__force __le16)msg_tmp.size); ++ msg_tmp.command = le32_to_cpu((__force __le32)msg_tmp.command); ++ msg_tmp.controlselector = le16_to_cpu((__force __le16)msg_tmp.controlselector); + + /* No need to update the read positions, because this was a peek */ + /* If the caller specifically want to peek, return */ +@@ -427,24 +443,24 @@ int saa7164_bus_get(struct saa7164_dev * + + if (space_rem < sizeof(*msg)) { + /* msg wraps around the ring */ +- memcpy(msg, bus->m_pdwGetRing + curr_grp, space_rem); +- memcpy((u8 *)msg + space_rem, bus->m_pdwGetRing, ++ memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, space_rem); ++ memcpy_fromio((u8 *)msg + space_rem, bus->m_pdwGetRing, + sizeof(*msg) - space_rem); + if (buf) +- memcpy(buf, bus->m_pdwGetRing + sizeof(*msg) - ++ memcpy_fromio(buf, bus->m_pdwGetRing + sizeof(*msg) - + space_rem, buf_size); + + } else if (space_rem == sizeof(*msg)) { +- memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); ++ memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); + if (buf) +- memcpy(buf, bus->m_pdwGetRing, buf_size); ++ memcpy_fromio(buf, bus->m_pdwGetRing, buf_size); + } else { + /* Additional data wraps around the ring */ +- memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); ++ memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); + if (buf) { +- memcpy(buf, bus->m_pdwGetRing + curr_grp + ++ memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + + sizeof(*msg), space_rem - sizeof(*msg)); +- memcpy(buf + space_rem - sizeof(*msg), ++ memcpy_fromio(buf + space_rem - sizeof(*msg), + bus->m_pdwGetRing, bytes_to_read - + space_rem); + } +@@ -453,19 +469,20 @@ int saa7164_bus_get(struct saa7164_dev * + + } else { + /* No wrapping */ +- memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); ++ memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); + if (buf) +- memcpy(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg), ++ memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg), + buf_size); + } ++ /* Convert from little endian to CPU */ ++ msg->size = le16_to_cpu((__force __le16)msg->size); ++ msg->command = le32_to_cpu((__force __le32)msg->command); ++ msg->controlselector = le16_to_cpu((__force __le16)msg->controlselector); + + /* Update the read positions, adjusting the ring */ +- saa7164_writel(bus->m_dwGetReadPos, cpu_to_le32(new_grp)); ++ saa7164_writel(bus->m_dwGetReadPos, new_grp); + + peekout: +- msg->size = le16_to_cpu(msg->size); +- msg->command = le32_to_cpu(msg->command); +- msg->controlselector = le16_to_cpu(msg->controlselector); + ret = SAA_OK; + out: + mutex_unlock(&bus->lock); +--- a/drivers/media/video/saa7164/saa7164-core.c ++++ b/drivers/media/video/saa7164/saa7164-core.c +@@ -140,7 +140,7 @@ static void saa7164_ts_verifier(struct s + u32 i; + u8 cc, a; + u16 pid; +- u8 __iomem *bufcpu = (u8 *)buf->cpu; ++ u8 *bufcpu = (u8 *)buf->cpu; + + port->sync_errors = 0; + port->v_cc_errors = 0; +@@ -281,7 +281,7 @@ static void saa7164_work_enchandler_help + struct saa7164_user_buffer *ubuf = NULL; + struct list_head *c, *n; + int i = 0; +- u8 __iomem *p; ++ u8 *p; + + mutex_lock(&port->dmaqueue_lock); + list_for_each_safe(c, n, &port->dmaqueue.list) { +@@ -338,8 +338,7 @@ static void saa7164_work_enchandler_help + + if (buf->actual_size <= ubuf->actual_size) { + +- memcpy_fromio(ubuf->data, buf->cpu, +- ubuf->actual_size); ++ memcpy(ubuf->data, buf->cpu, ubuf->actual_size); + + if (crc_checking) { + /* Throw a new checksum on the read buffer */ +@@ -366,7 +365,7 @@ static void saa7164_work_enchandler_help + * with known bad data. We check for this data at a later point + * in time. */ + saa7164_buffer_zero_offsets(port, bufnr); +- memset_io(buf->cpu, 0xff, buf->pci_size); ++ memset(buf->cpu, 0xff, buf->pci_size); + if (crc_checking) { + /* Throw yet aanother new checksum on the dma buffer */ + buf->crc = crc32(0, buf->cpu, buf->actual_size); +@@ -1134,7 +1133,7 @@ static int saa7164_proc_show(struct seq_ + if (c == 0) + seq_printf(m, " %04x:", i); + +- seq_printf(m, " %02x", *(b->m_pdwSetRing + i)); ++ seq_printf(m, " %02x", readb(b->m_pdwSetRing + i)); + + if (++c == 16) { + seq_printf(m, "\n"); +@@ -1149,7 +1148,7 @@ static int saa7164_proc_show(struct seq_ + if (c == 0) + seq_printf(m, " %04x:", i); + +- seq_printf(m, " %02x", *(b->m_pdwGetRing + i)); ++ seq_printf(m, " %02x", readb(b->m_pdwGetRing + i)); + + if (++c == 16) { + seq_printf(m, "\n"); +--- a/drivers/media/video/saa7164/saa7164-fw.c ++++ b/drivers/media/video/saa7164/saa7164-fw.c +@@ -72,7 +72,7 @@ int saa7164_dl_wait_clr(struct saa7164_d + /* TODO: move dlflags into dev-> and change to write/readl/b */ + /* TODO: Excessive levels of debug */ + int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize, +- u32 dlflags, u8 *dst, u32 dstsize) ++ u32 dlflags, u8 __iomem *dst, u32 dstsize) + { + u32 reg, timeout, offset; + u8 *srcbuf = NULL; +@@ -136,7 +136,7 @@ int saa7164_downloadimage(struct saa7164 + srcsize -= dstsize, offset += dstsize) { + + dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize); +- memcpy(dst, srcbuf + offset, dstsize); ++ memcpy_toio(dst, srcbuf + offset, dstsize); + + /* Flag the data as ready */ + saa7164_writel(drflag, 1); +@@ -154,7 +154,7 @@ int saa7164_downloadimage(struct saa7164 + + dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize); + /* Write last block to the device */ +- memcpy(dst, srcbuf+offset, srcsize); ++ memcpy_toio(dst, srcbuf+offset, srcsize); + + /* Flag the data as ready */ + saa7164_writel(drflag, 1); +--- a/drivers/media/video/saa7164/saa7164-types.h ++++ b/drivers/media/video/saa7164/saa7164-types.h +@@ -78,9 +78,9 @@ enum tmBusType { + struct tmComResBusInfo { + enum tmBusType Type; + u16 m_wMaxReqSize; +- u8 *m_pdwSetRing; ++ u8 __iomem *m_pdwSetRing; + u32 m_dwSizeSetRing; +- u8 *m_pdwGetRing; ++ u8 __iomem *m_pdwGetRing; + u32 m_dwSizeGetRing; + u32 m_dwSetWritePos; + u32 m_dwSetReadPos; +--- a/drivers/media/video/saa7164/saa7164.h ++++ b/drivers/media/video/saa7164/saa7164.h +@@ -315,13 +315,13 @@ struct saa7164_buffer { + + /* A block of page align PCI memory */ + u32 pci_size; /* PCI allocation size in bytes */ +- u64 __iomem *cpu; /* Virtual address */ ++ u64 *cpu; /* Virtual address */ + dma_addr_t dma; /* Physical address */ + u32 crc; /* Checksum for the entire buffer data */ + + /* A page table that splits the block into a number of entries */ + u32 pt_size; /* PCI allocation size in bytes */ +- u64 __iomem *pt_cpu; /* Virtual address */ ++ u64 *pt_cpu; /* Virtual address */ + dma_addr_t pt_dma; /* Physical address */ + + /* Encoder fops */ diff --git a/releases/3.2.94/sched-add-macros-to-define-bitops-for-task-atomic-flags.patch b/releases/3.2.94/sched-add-macros-to-define-bitops-for-task-atomic-flags.patch new file mode 100644 index 00000000..84e8da0f --- /dev/null +++ b/releases/3.2.94/sched-add-macros-to-define-bitops-for-task-atomic-flags.patch @@ -0,0 +1,62 @@ +From: Zefan Li <lizefan@huawei.com> +Date: Thu, 25 Sep 2014 09:40:40 +0800 +Subject: sched: add macros to define bitops for task atomic flags + +commit e0e5070b20e01f0321f97db4e4e174f3f6b49e50 upstream. + +This will simplify code when we add new flags. + +v3: +- Kees pointed out that no_new_privs should never be cleared, so we +shouldn't define task_clear_no_new_privs(). we define 3 macros instead +of a single one. + +v2: +- updated scripts/tags.sh, suggested by Peter + +Cc: Ingo Molnar <mingo@kernel.org> +Cc: Miao Xie <miaox@cn.fujitsu.com> +Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Acked-by: Kees Cook <keescook@chromium.org> +Signed-off-by: Zefan Li <lizefan@huawei.com> +Signed-off-by: Tejun Heo <tj@kernel.org> +[lizf: Backported to 3.4: + - adjust context + - remove no_new_priv code + - add atomic_flags to struct task_struct] +[bwh: Backported to 3.2: + - Drop changes in scripts/tags.sh + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1313,6 +1313,8 @@ struct task_struct { + unsigned sched_reset_on_fork:1; + unsigned sched_contributes_to_load:1; + ++ unsigned long atomic_flags; /* Flags needing atomic access. */ ++ + pid_t pid; + pid_t tgid; + +@@ -1844,6 +1846,18 @@ extern void thread_group_times(struct ta + #define tsk_used_math(p) ((p)->flags & PF_USED_MATH) + #define used_math() tsk_used_math(current) + ++/* Per-process atomic flags. */ ++ ++#define TASK_PFA_TEST(name, func) \ ++ static inline bool task_##func(struct task_struct *p) \ ++ { return test_bit(PFA_##name, &p->atomic_flags); } ++#define TASK_PFA_SET(name, func) \ ++ static inline void task_set_##func(struct task_struct *p) \ ++ { set_bit(PFA_##name, &p->atomic_flags); } ++#define TASK_PFA_CLEAR(name, func) \ ++ static inline void task_clear_##func(struct task_struct *p) \ ++ { clear_bit(PFA_##name, &p->atomic_flags); } ++ + /* + * task->jobctl flags + */ diff --git a/releases/3.2.94/sched-fair-cpumask-export-for_each_cpu_wrap.patch b/releases/3.2.94/sched-fair-cpumask-export-for_each_cpu_wrap.patch new file mode 100644 index 00000000..ea119891 --- /dev/null +++ b/releases/3.2.94/sched-fair-cpumask-export-for_each_cpu_wrap.patch @@ -0,0 +1,91 @@ +From: Peter Zijlstra <peterz@infradead.org> +Date: Fri, 14 Apr 2017 14:20:05 +0200 +Subject: sched/fair, cpumask: Export for_each_cpu_wrap() + +commit c743f0a5c50f2fcbc628526279cfa24f3dabe182 upstream. + +More users for for_each_cpu_wrap() have appeared. Promote the construct +to generic cpumask interface. + +The implementation is slightly modified to reduce arguments. + +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Cc: Lauro Ramos Venancio <lvenanci@redhat.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Mike Galbraith <efault@gmx.de> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Rik van Riel <riel@redhat.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: lwang@redhat.com +Link: http://lkml.kernel.org/r/20170414122005.o35me2h5nowqkxbv@hirez.programming.kicks-ass.net +Signed-off-by: Ingo Molnar <mingo@kernel.org> +[bwh: Backported to 3.2: there's no old version of the function to delete] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/include/linux/cpumask.h ++++ b/include/linux/cpumask.h +@@ -216,6 +216,23 @@ int cpumask_any_but(const struct cpumask + (cpu) = cpumask_next_zero((cpu), (mask)), \ + (cpu) < nr_cpu_ids;) + ++extern int cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool wrap); ++ ++/** ++ * for_each_cpu_wrap - iterate over every cpu in a mask, starting at a specified location ++ * @cpu: the (optionally unsigned) integer iterator ++ * @mask: the cpumask poiter ++ * @start: the start location ++ * ++ * The implementation does not assume any bit in @mask is set (including @start). ++ * ++ * After the loop, cpu is >= nr_cpu_ids. ++ */ ++#define for_each_cpu_wrap(cpu, mask, start) \ ++ for ((cpu) = cpumask_next_wrap((start)-1, (mask), (start), false); \ ++ (cpu) < nr_cpumask_bits; \ ++ (cpu) = cpumask_next_wrap((cpu), (mask), (start), true)) ++ + /** + * for_each_cpu_and - iterate over every cpu in both masks + * @cpu: the (optionally unsigned) integer iterator +--- a/lib/cpumask.c ++++ b/lib/cpumask.c +@@ -75,6 +75,38 @@ int cpumask_any_but(const struct cpumask + return i; + } + ++/** ++ * cpumask_next_wrap - helper to implement for_each_cpu_wrap ++ * @n: the cpu prior to the place to search ++ * @mask: the cpumask pointer ++ * @start: the start point of the iteration ++ * @wrap: assume @n crossing @start terminates the iteration ++ * ++ * Returns >= nr_cpu_ids on completion ++ * ++ * Note: the @wrap argument is required for the start condition when ++ * we cannot assume @start is set in @mask. ++ */ ++int cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool wrap) ++{ ++ int next; ++ ++again: ++ next = cpumask_next(n, mask); ++ ++ if (wrap && n < start && next >= start) { ++ return nr_cpumask_bits; ++ ++ } else if (next >= nr_cpumask_bits) { ++ wrap = true; ++ n = -1; ++ goto again; ++ } ++ ++ return next; ++} ++EXPORT_SYMBOL(cpumask_next_wrap); ++ + /* These are not inline because of header tangles. */ + #ifdef CONFIG_CPUMASK_OFFSTACK + /** diff --git a/releases/3.2.94/sched-topology-fix-building-of-overlapping-sched-groups.patch b/releases/3.2.94/sched-topology-fix-building-of-overlapping-sched-groups.patch new file mode 100644 index 00000000..65b72a29 --- /dev/null +++ b/releases/3.2.94/sched-topology-fix-building-of-overlapping-sched-groups.patch @@ -0,0 +1,62 @@ +From: Peter Zijlstra <peterz@infradead.org> +Date: Fri, 14 Apr 2017 17:24:02 +0200 +Subject: sched/topology: Fix building of overlapping sched-groups + +commit 0372dd2736e02672ac6e189c31f7d8c02ad543cd upstream. + +When building the overlapping groups, we very obviously should start +with the previous domain of _this_ @cpu, not CPU-0. + +This can be readily demonstrated with a topology like: + + node 0 1 2 3 + 0: 10 20 30 20 + 1: 20 10 20 30 + 2: 30 20 10 20 + 3: 20 30 20 10 + +Where (for example) CPU1 ends up generating the following nonsensical groups: + + [] CPU1 attaching sched-domain: + [] domain 0: span 0-2 level NUMA + [] groups: 1 2 0 + [] domain 1: span 0-3 level NUMA + [] groups: 1-3 (cpu_capacity = 3072) 0-1,3 (cpu_capacity = 3072) + +Where the fact that domain 1 doesn't include a group with span 0-2 is +the obvious fail. + +With patch this looks like: + + [] CPU1 attaching sched-domain: + [] domain 0: span 0-2 level NUMA + [] groups: 1 0 2 + [] domain 1: span 0-3 level NUMA + [] groups: 0-2 (cpu_capacity = 3072) 0,2-3 (cpu_capacity = 3072) + +Debugged-by: Lauro Ramos Venancio <lvenanci@redhat.com> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Mike Galbraith <efault@gmx.de> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: linux-kernel@vger.kernel.org +Fixes: e3589f6c81e4 ("sched: Allow for overlapping sched_domain spans") +Signed-off-by: Ingo Molnar <mingo@kernel.org> +[bwh: Backported to 3.2: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/sched.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/sched.c ++++ b/kernel/sched.c +@@ -7479,7 +7479,7 @@ build_overlap_sched_groups(struct sched_ + + cpumask_clear(covered); + +- for_each_cpu(i, span) { ++ for_each_cpu_wrap(i, span, cpu) { + struct cpumask *sg_span; + + if (cpumask_test_cpu(i, covered)) diff --git a/releases/3.2.94/scsi-bnx2i-missing-error-code-in-bnx2i_ep_connect.patch b/releases/3.2.94/scsi-bnx2i-missing-error-code-in-bnx2i_ep_connect.patch new file mode 100644 index 00000000..f4bd1bb2 --- /dev/null +++ b/releases/3.2.94/scsi-bnx2i-missing-error-code-in-bnx2i_ep_connect.patch @@ -0,0 +1,31 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Fri, 23 Jun 2017 10:02:00 +0300 +Subject: scsi: bnx2i: missing error code in bnx2i_ep_connect() + +commit 1d32a62c74b3bcb69822b0f4745af5410cfec3a7 upstream. + +If bnx2i_map_ep_dbell_regs() then we accidentally return NULL instead of +an error pointer. It results in a NULL dereference in +iscsi_if_ep_connect(). + +Fixes: cf4e6363859d ("[SCSI] bnx2i: Add bnx2i iSCSI driver.") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/bnx2i/bnx2i_iscsi.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c ++++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c +@@ -1894,7 +1894,8 @@ static struct iscsi_endpoint *bnx2i_ep_c + + bnx2i_ep_active_list_add(hba, bnx2i_ep); + +- if (bnx2i_map_ep_dbell_regs(bnx2i_ep)) ++ rc = bnx2i_map_ep_dbell_regs(bnx2i_ep); ++ if (rc) + goto del_active_ep; + + mutex_unlock(&hba->net_dev_lock); diff --git a/releases/3.2.94/scsi-scsi_transport_iscsi-fix-the-issue-that-iscsi_if_rx-doesn-t.patch b/releases/3.2.94/scsi-scsi_transport_iscsi-fix-the-issue-that-iscsi_if_rx-doesn-t.patch new file mode 100644 index 00000000..e1b290ee --- /dev/null +++ b/releases/3.2.94/scsi-scsi_transport_iscsi-fix-the-issue-that-iscsi_if_rx-doesn-t.patch @@ -0,0 +1,58 @@ +From: Xin Long <lucien.xin@gmail.com> +Date: Sun, 27 Aug 2017 20:25:26 +0800 +Subject: scsi: scsi_transport_iscsi: fix the issue that iscsi_if_rx doesn't + parse nlmsg properly + +commit c88f0e6b06f4092995688211a631bb436125d77b upstream. + +ChunYu found a kernel crash by syzkaller: + +[ 651.617875] kasan: CONFIG_KASAN_INLINE enabled +[ 651.618217] kasan: GPF could be caused by NULL-ptr deref or user memory access +[ 651.618731] general protection fault: 0000 [#1] SMP KASAN +[ 651.621543] CPU: 1 PID: 9539 Comm: scsi Not tainted 4.11.0.cov #32 +[ 651.621938] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 +[ 651.622309] task: ffff880117780000 task.stack: ffff8800a3188000 +[ 651.622762] RIP: 0010:skb_release_data+0x26c/0x590 +[...] +[ 651.627260] Call Trace: +[ 651.629156] skb_release_all+0x4f/0x60 +[ 651.629450] consume_skb+0x1a5/0x600 +[ 651.630705] netlink_unicast+0x505/0x720 +[ 651.632345] netlink_sendmsg+0xab2/0xe70 +[ 651.633704] sock_sendmsg+0xcf/0x110 +[ 651.633942] ___sys_sendmsg+0x833/0x980 +[ 651.637117] __sys_sendmsg+0xf3/0x240 +[ 651.638820] SyS_sendmsg+0x32/0x50 +[ 651.639048] entry_SYSCALL_64_fastpath+0x1f/0xc2 + +It's caused by skb_shared_info at the end of sk_buff was overwritten by +ISCSI_KEVENT_IF_ERROR when parsing nlmsg info from skb in iscsi_if_rx. + +During the loop if skb->len == nlh->nlmsg_len and both are sizeof(*nlh), +ev = nlmsg_data(nlh) will acutally get skb_shinfo(SKB) instead and set a +new value to skb_shinfo(SKB)->nr_frags by ev->type. + +This patch is to fix it by checking nlh->nlmsg_len properly there to +avoid over accessing sk_buff. + +Reported-by: ChunYu Wang <chunwang@redhat.com> +Signed-off-by: Xin Long <lucien.xin@gmail.com> +Acked-by: Chris Leech <cleech@redhat.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/scsi_transport_iscsi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/scsi_transport_iscsi.c ++++ b/drivers/scsi/scsi_transport_iscsi.c +@@ -2079,7 +2079,7 @@ iscsi_if_rx(struct sk_buff *skb) + uint32_t group; + + nlh = nlmsg_hdr(skb); +- if (nlh->nlmsg_len < sizeof(*nlh) || ++ if (nlh->nlmsg_len < sizeof(*nlh) + sizeof(*ev) || + skb->len < nlh->nlmsg_len) { + break; + } diff --git a/releases/3.2.94/scsi-ses-do-not-add-a-device-to-an-enclosure-if.patch b/releases/3.2.94/scsi-ses-do-not-add-a-device-to-an-enclosure-if.patch new file mode 100644 index 00000000..01d69a75 --- /dev/null +++ b/releases/3.2.94/scsi-ses-do-not-add-a-device-to-an-enclosure-if.patch @@ -0,0 +1,51 @@ +From: Maurizio Lombardi <mlombard@redhat.com> +Date: Tue, 27 Jun 2017 11:53:27 +0200 +Subject: scsi: ses: do not add a device to an enclosure if + enclosure_add_links() fails. + +commit 62e62ffd95539b9220894a7900a619e0f3ef4756 upstream. + +The enclosure_add_device() function should fail if it can't create the +relevant sysfs links. + +Signed-off-by: Maurizio Lombardi <mlombard@redhat.com> +Tested-by: Douglas Miller <dougmill@linux.vnet.ibm.com> +Acked-by: James Bottomley <jejb@linux.vnet.ibm.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/misc/enclosure.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/misc/enclosure.c ++++ b/drivers/misc/enclosure.c +@@ -320,6 +320,7 @@ int enclosure_add_device(struct enclosur + struct device *dev) + { + struct enclosure_component *cdev; ++ int err; + + if (!edev || component >= edev->components) + return -EINVAL; +@@ -329,12 +330,17 @@ int enclosure_add_device(struct enclosur + if (cdev->dev == dev) + return -EEXIST; + +- if (cdev->dev) ++ if (cdev->dev) { + enclosure_remove_links(cdev); +- +- put_device(cdev->dev); ++ put_device(cdev->dev); ++ } + cdev->dev = get_device(dev); +- return enclosure_add_links(cdev); ++ err = enclosure_add_links(cdev); ++ if (err) { ++ put_device(cdev->dev); ++ cdev->dev = NULL; ++ } ++ return err; + } + EXPORT_SYMBOL_GPL(enclosure_add_device); + diff --git a/releases/3.2.94/scsi-sun_esp-fix-device-reference-leaks.patch b/releases/3.2.94/scsi-sun_esp-fix-device-reference-leaks.patch new file mode 100644 index 00000000..42b3586f --- /dev/null +++ b/releases/3.2.94/scsi-sun_esp-fix-device-reference-leaks.patch @@ -0,0 +1,49 @@ +From: Johan Hovold <johan@kernel.org> +Date: Wed, 21 Jun 2017 11:35:09 +0200 +Subject: scsi: sun_esp: fix device reference leaks + +commit f62f9ffdb5ef683ef8cffb43932fa72cc3713e94 upstream. + +Make sure to drop the reference to the dma device taken by +of_find_device_by_node() on probe errors and on driver unbind. + +Fixes: 334ae614772b ("sparc: Kill SBUS DVMA layer.") +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/sun_esp.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/sun_esp.c ++++ b/drivers/scsi/sun_esp.c +@@ -568,6 +568,7 @@ static int __devinit esp_sbus_probe(stru + struct device_node *dp = op->dev.of_node; + struct platform_device *dma_of = NULL; + int hme = 0; ++ int ret; + + if (dp->parent && + (!strcmp(dp->parent->name, "espdma") || +@@ -582,7 +583,11 @@ static int __devinit esp_sbus_probe(stru + if (!dma_of) + return -ENODEV; + +- return esp_sbus_probe_one(op, dma_of, hme); ++ ret = esp_sbus_probe_one(op, dma_of, hme); ++ if (ret) ++ put_device(&dma_of->dev); ++ ++ return ret; + } + + static int __devexit esp_sbus_remove(struct platform_device *op) +@@ -615,6 +620,8 @@ static int __devexit esp_sbus_remove(str + + dev_set_drvdata(&op->dev, NULL); + ++ put_device(&dma_of->dev); ++ + return 0; + } + diff --git a/releases/3.2.94/series b/releases/3.2.94/series new file mode 100644 index 00000000..65aaadd9 --- /dev/null +++ b/releases/3.2.94/series @@ -0,0 +1,74 @@ +sched-fair-cpumask-export-for_each_cpu_wrap.patch +sched-topology-fix-building-of-overlapping-sched-groups.patch +mwifiex-fixup-error-cases-in-mwifiex_add_virtual_intf.patch +wlcore-fix-64k-page-support.patch +mceusb-fix-memory-leaks-in-error-path.patch +perf-core-correct-event-creation-with-perf_format_group.patch +usb-usbip-set-buffer-pointers-to-null-after-free.patch +usb-fix-typo-in-the-definition-of-endpointrequest.patch +pci-correct-pci_std_resource_end-usage.patch +md-don-t-use-flush_signals-in-userspace-processes.patch +udf-fix-races-with-i_size-changes-during-readpage.patch +udf-fix-deadlock-between-writeback-and-udf_setsize.patch +xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch +af_iucv-move-sockaddr-length-checks-to-before-accessing-sa_family-in.patch +scsi-bnx2i-missing-error-code-in-bnx2i_ep_connect.patch +scsi-sun_esp-fix-device-reference-leaks.patch +mips-fix-mips_atomic_set-retry-condition.patch +usb-serial-cp210x-add-id-for-cel-em3588-usb-zigbee-stick.patch +pci-mark-haswell-power-control-unit-as-having-non-compliant-bars.patch +pci-work-around-poweroff-suspend-to-ram-issue-on-macbook-pro-11.patch +pm-domains-fix-unsafe-iteration-over-modified-list-of-device-links.patch +mips-send-sigill-for-bposge32-in-__compute_return_epc_for_insn.patch +add-usb-quirk-for-hvr-950q-to-avoid-intermittent-device-resets.patch +btrfs-don-t-clear-sgid-when-inheriting-acls.patch +pci-pm-restore-the-status-of-pci-devices-across-hibernation.patch +scsi-ses-do-not-add-a-device-to-an-enclosure-if.patch +parisc-use-compat_sys_keyctl.patch +ipv6-always-add-flag-an-address-that-failed-dad-with-dadfailed.patch +ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch +drm-i915-disable-msi-for-all-pre-gen5.patch +ib-core-create-common-start-end-port-functions.patch +ib-core-add-inline-function-to-validate-port.patch +rdma-uverbs-check-port-number-supplied-by-user-verbs-cmds.patch +s390-syscalls-fix-out-of-bounds-arguments-access.patch +rtc-rtc-nuc900-fix-loop-timeout-test.patch +tpm-fix-a-kernel-memory-leak-in-tpm-sysfs.c.patch +cfg80211-check-if-pmkid-attribute-is-of-expected-size.patch +cfg80211-validate-frequencies-nested-in.patch +mm-mmap.c-do-not-blow-on-prot_none-map_fixed-holes-in-the-stack.patch +fs-dcache.c-fix-spin-lockup-issue-on-nlru-lock.patch +powerpc-asm-mark-cr0-as-clobbered-in-mftb.patch +powerpc-fix-emulation-of-mfocrf-in-emulate_step.patch +input-i8042-fix-crash-at-boot-time.patch +ubifs-correctly-evict-xattr-inodes.patch +ubifs-don-t-leak-kernel-memory-to-the-mtd.patch +mm-fix-overflow-check-in-expand_upwards.patch +vt-fix-unchecked-__put_user-in-tioclinux-ioctls.patch +ext2-don-t-clear-sgid-when-inheriting-acls.patch +ext2-preserve-i_mode-if-ext2_set_acl-fails.patch +ext3-don-t-clear-sgid-when-inheriting-acls.patch +ext3-preserve-i_mode-if-ext3_set_acl-fails.patch +reiserfs-don-t-clear-sgid-when-inheriting-acls.patch +reiserfs-preserve-i_mode-if-__reiserfs_set_acl-fails.patch +ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch +ext4-don-t-clear-sgid-when-inheriting-acls.patch +btrfs-preserve-i_mode-if-__btrfs_set_acl-fails.patch +saa7164-fix-endian-conversion-in-saa7164_bus_set.patch +saa7164-fix-sparse-warnings.patch +saa7164-fix-double-fetch-pcie-access-condition.patch +nl80211-check-for-the-required-netlink-attributes-presence.patch +kvm-nvmx-don-t-allow-l2-to-access-the-hardware-cr8.patch +video-fbdev-aty-do-not-leak-uninitialized-padding-in-clk-to.patch +xfs-xfs_is_realtime_inode-should-be-false-if-no-rt-device-present.patch +scsi-scsi_transport_iscsi-fix-the-issue-that-iscsi_if_rx-doesn-t.patch +bluetooth-properly-check-l2cap-config-option-output-buffer-length.patch +l2tp-avoid-use-after-free-caused-by-l2tp_ip_backlog_recv.patch +netfilter-nf_conntrack-fix-rcu-race-in-nf_conntrack_find_get.patch +mips-refactor-clear_page-and-copy_page-functions.patch +perf-x86-check-if-user-fp-is-valid.patch +m32r-add-definition-of-ioremap_wc-to-io.h.patch +m32r-add-io-_rep-helpers.patch +net-sched-filters-fix-notification-of-filter-delete-with-proper-handle.patch +sched-add-macros-to-define-bitops-for-task-atomic-flags.patch +cpuset-pf_spread_page-and-pf_spread_slab-should-be-atomic-flags.patch diff --git a/releases/3.2.94/tpm-fix-a-kernel-memory-leak-in-tpm-sysfs.c.patch b/releases/3.2.94/tpm-fix-a-kernel-memory-leak-in-tpm-sysfs.c.patch new file mode 100644 index 00000000..259297b0 --- /dev/null +++ b/releases/3.2.94/tpm-fix-a-kernel-memory-leak-in-tpm-sysfs.c.patch @@ -0,0 +1,38 @@ +From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> +Date: Tue, 20 Jun 2017 11:38:02 +0200 +Subject: tpm: fix a kernel memory leak in tpm-sysfs.c + +commit 13b47cfcfc60495cde216eef4c01040d76174cbe upstream. + +While cleaning up sysfs callback that prints EK we discovered a kernel +memory leak. This commit fixes the issue by zeroing the buffer used for +TPM command/response. + +The leak happen when we use either tpm_vtpm_proxy, tpm_ibmvtpm or +xen-tpmfront. + +Fixes: 0883743825e3 ("TPM: sysfs functions consolidation") +Reported-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> +Tested-by: Stefan Berger <stefanb@linux.vnet.ibm.com> +Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> +Signed-off-by: James Morris <james.l.morris@oracle.com> +[bwh: Backported to 3.2: adjust filename, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/char/tpm/tpm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/char/tpm/tpm.c ++++ b/drivers/char/tpm/tpm.c +@@ -879,9 +879,10 @@ ssize_t tpm_show_pubek(struct device *de + ssize_t err; + int i, rc; + char *str = buf; +- + struct tpm_chip *chip = dev_get_drvdata(dev); + ++ memset(&tpm_cmd, 0, sizeof(tpm_cmd)); ++ + tpm_cmd.header.in = tpm_readpubek_header; + err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, + "attempting to read the PUBEK"); diff --git a/releases/3.2.94/ubifs-correctly-evict-xattr-inodes.patch b/releases/3.2.94/ubifs-correctly-evict-xattr-inodes.patch new file mode 100644 index 00000000..62d6d7b6 --- /dev/null +++ b/releases/3.2.94/ubifs-correctly-evict-xattr-inodes.patch @@ -0,0 +1,84 @@ +From: Richard Weinberger <richard@nod.at> +Date: Wed, 17 May 2017 00:20:27 +0200 +Subject: ubifs: Correctly evict xattr inodes + +commit 272eda8298dc82eb411ece82bbb2c62911087b24 upstream. + +UBIFS handles extended attributes just like files, as consequence of +that, they also have inodes. +Therefore UBIFS does all the inode machinery also for xattrs. Since new +inodes have i_nlink of 1, a file or xattr inode will be evicted +if i_nlink goes down to 0 after an unlink. UBIFS assumes this model also +for xattrs, which is not correct. +One can create a file "foo" with xattr "user.test". By reading +"user.test" an inode will be created, and by deleting "user.test" it +will get evicted later. The assumption breaks if the file "foo", which +hosts the xattrs, will be removed. VFS nor UBIFS does not remove each +xattr via ubifs_xattr_remove(), it just removes the host inode from +the TNC and all underlying xattr nodes too and the inode will remain +in the cache and wastes memory. + +To solve this problem, remove xattr inodes from the VFS inode cache in +ubifs_xattr_remove() to make sure that they get evicted. + +Fixes: 1e51764a3c2ac05a ("UBIFS: add new flash file system") +Signed-off-by: Richard Weinberger <richard@nod.at> +[bwh: Backported to 3.2: + - xattr support is optional, so add an #ifdef around the call + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/fs/ubifs/tnc.c ++++ b/fs/ubifs/tnc.c +@@ -2730,6 +2730,10 @@ int ubifs_tnc_remove_ino(struct ubifs_in + dbg_tnc("xent '%s', ino %lu", xent->name, + (unsigned long)xattr_inum); + ++#ifdef CONFIG_UBIFS_FS_XATTR ++ ubifs_evict_xattr_inode(c, xattr_inum); ++#endif ++ + nm.name = xent->name; + nm.len = le16_to_cpu(xent->nlen); + err = ubifs_tnc_remove_nm(c, &key1, &nm); +--- a/fs/ubifs/ubifs.h ++++ b/fs/ubifs/ubifs.h +@@ -1748,6 +1748,7 @@ ssize_t ubifs_getxattr(struct dentry *de + size_t size); + ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); + int ubifs_removexattr(struct dentry *dentry, const char *name); ++void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum); + + /* super.c */ + struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); +--- a/fs/ubifs/xattr.c ++++ b/fs/ubifs/xattr.c +@@ -483,6 +483,28 @@ ssize_t ubifs_listxattr(struct dentry *d + return written; + } + ++/** ++ * ubifs_evict_xattr_inode - Evict an xattr inode. ++ * @c: UBIFS file-system description object ++ * @xattr_inum: xattr inode number ++ * ++ * When an inode that hosts xattrs is being removed we have to make sure ++ * that cached inodes of the xattrs also get removed from the inode cache ++ * otherwise we'd waste memory. This function looks up an inode from the ++ * inode cache and clears the link counter such that iput() will evict ++ * the inode. ++ */ ++void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum) ++{ ++ struct inode *inode; ++ ++ inode = ilookup(c->vfs_sb, xattr_inum); ++ if (inode) { ++ clear_nlink(inode); ++ iput(inode); ++ } ++} ++ + static int remove_xattr(struct ubifs_info *c, struct inode *host, + struct inode *inode, const struct qstr *nm) + { diff --git a/releases/3.2.94/ubifs-don-t-leak-kernel-memory-to-the-mtd.patch b/releases/3.2.94/ubifs-don-t-leak-kernel-memory-to-the-mtd.patch new file mode 100644 index 00000000..c4480796 --- /dev/null +++ b/releases/3.2.94/ubifs-don-t-leak-kernel-memory-to-the-mtd.patch @@ -0,0 +1,64 @@ +From: Richard Weinberger <richard@nod.at> +Date: Fri, 16 Jun 2017 16:21:44 +0200 +Subject: ubifs: Don't leak kernel memory to the MTD + +commit 4acadda74ff8b949c448c0282765ae747e088c87 upstream. + +When UBIFS prepares data structures which will be written to the MTD it +ensues that their lengths are multiple of 8. Since it uses kmalloc() the +padded bytes are left uninitialized and we leak a few bytes of kernel +memory to the MTD. +To make sure that all bytes are initialized, let's switch to kzalloc(). +Kzalloc() is fine in this case because the buffers are not huge and in +the IO path the performance bottleneck is anyway the MTD. + +Fixes: 1e51764a3c2a ("UBIFS: add new flash file system") +Signed-off-by: Richard Weinberger <richard@nod.at> +Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com> +Signed-off-by: Richard Weinberger <richard@nod.at> +[bwh: Backported to 3.2: + - Drop change in ubifs_jnl_xrename() + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ubifs/journal.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/fs/ubifs/journal.c ++++ b/fs/ubifs/journal.c +@@ -573,7 +573,7 @@ int ubifs_jnl_update(struct ubifs_info * + aligned_dlen = ALIGN(dlen, 8); + aligned_ilen = ALIGN(ilen, 8); + len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; +- dent = kmalloc(len, GFP_NOFS); ++ dent = kzalloc(len, GFP_NOFS); + if (!dent) + return -ENOMEM; + +@@ -959,7 +959,7 @@ int ubifs_jnl_rename(struct ubifs_info * + len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8); + if (old_dir != new_dir) + len += plen; +- dent = kmalloc(len, GFP_NOFS); ++ dent = kzalloc(len, GFP_NOFS); + if (!dent) + return -ENOMEM; + +@@ -1307,7 +1307,7 @@ int ubifs_jnl_delete_xattr(struct ubifs_ + hlen = host_ui->data_len + UBIFS_INO_NODE_SZ; + len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8); + +- xent = kmalloc(len, GFP_NOFS); ++ xent = kzalloc(len, GFP_NOFS); + if (!xent) + return -ENOMEM; + +@@ -1414,7 +1414,7 @@ int ubifs_jnl_change_xattr(struct ubifs_ + aligned_len1 = ALIGN(len1, 8); + aligned_len = aligned_len1 + ALIGN(len2, 8); + +- ino = kmalloc(aligned_len, GFP_NOFS); ++ ino = kzalloc(aligned_len, GFP_NOFS); + if (!ino) + return -ENOMEM; + diff --git a/releases/3.2.94/udf-fix-deadlock-between-writeback-and-udf_setsize.patch b/releases/3.2.94/udf-fix-deadlock-between-writeback-and-udf_setsize.patch new file mode 100644 index 00000000..89a9de8a --- /dev/null +++ b/releases/3.2.94/udf-fix-deadlock-between-writeback-and-udf_setsize.patch @@ -0,0 +1,47 @@ +From: Jan Kara <jack@suse.cz> +Date: Tue, 13 Jun 2017 16:20:25 +0200 +Subject: udf: Fix deadlock between writeback and udf_setsize() + +commit f2e95355891153f66d4156bf3a142c6489cd78c6 upstream. + +udf_setsize() called truncate_setsize() with i_data_sem held. Thus +truncate_pagecache() called from truncate_setsize() could lock a page +under i_data_sem which can deadlock as page lock ranks below +i_data_sem - e. g. writeback can hold page lock and try to acquire +i_data_sem to map a block. + +Fix the problem by moving truncate_setsize() calls from under +i_data_sem. It is safe for us to change i_size without holding +i_data_sem as all the places that depend on i_size being stable already +hold inode_lock. + +Fixes: 7e49b6f2480cb9a9e7322a91592e56a5c85361f5 +Signed-off-by: Jan Kara <jack@suse.cz> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/udf/inode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/udf/inode.c ++++ b/fs/udf/inode.c +@@ -1145,8 +1145,8 @@ int udf_setsize(struct inode *inode, lof + up_write(&iinfo->i_data_sem); + return err; + } +- truncate_setsize(inode, newsize); + up_write(&iinfo->i_data_sem); ++ truncate_setsize(inode, newsize); + } else { + if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { + down_write(&iinfo->i_data_sem); +@@ -1162,8 +1162,8 @@ int udf_setsize(struct inode *inode, lof + udf_get_block); + if (err) + return err; +- down_write(&iinfo->i_data_sem); + truncate_setsize(inode, newsize); ++ down_write(&iinfo->i_data_sem); + udf_truncate_extents(inode); + up_write(&iinfo->i_data_sem); + } diff --git a/releases/3.2.94/udf-fix-races-with-i_size-changes-during-readpage.patch b/releases/3.2.94/udf-fix-races-with-i_size-changes-during-readpage.patch new file mode 100644 index 00000000..af9d21cb --- /dev/null +++ b/releases/3.2.94/udf-fix-races-with-i_size-changes-during-readpage.patch @@ -0,0 +1,41 @@ +From: Jan Kara <jack@suse.cz> +Date: Tue, 13 Jun 2017 15:54:58 +0200 +Subject: udf: Fix races with i_size changes during readpage + +commit 9795e0e8ac0d6a3ee092f1b555b284b57feef99e upstream. + +__udf_adinicb_readpage() uses i_size several times. When truncate +changes i_size while the function is running, it can observe several +different values and thus e.g. expose uninitialized parts of page to +userspace. Also use i_size_read() in the function since it does not hold +inode_lock. Since i_size is guaranteed to be small, this cannot really +cause any issues even on 32-bit archs but let's be careful. + +Fixes: 9c2fc0de1a6e638fe58c354a463f544f42a90a09 +Signed-off-by: Jan Kara <jack@suse.cz> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/udf/file.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/fs/udf/file.c ++++ b/fs/udf/file.c +@@ -44,10 +44,15 @@ static void __udf_adinicb_readpage(struc + struct inode *inode = page->mapping->host; + char *kaddr; + struct udf_inode_info *iinfo = UDF_I(inode); ++ loff_t isize = i_size_read(inode); + ++ /* ++ * We have to be careful here as truncate can change i_size under us. ++ * So just sample it once and use the same value everywhere. ++ */ + kaddr = kmap(page); +- memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size); +- memset(kaddr + inode->i_size, 0, PAGE_CACHE_SIZE - inode->i_size); ++ memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, isize); ++ memset(kaddr + isize, 0, PAGE_CACHE_SIZE - isize); + flush_dcache_page(page); + SetPageUptodate(page); + kunmap(page); diff --git a/releases/3.2.94/usb-fix-typo-in-the-definition-of-endpointrequest.patch b/releases/3.2.94/usb-fix-typo-in-the-definition-of-endpointrequest.patch new file mode 100644 index 00000000..dd0cb214 --- /dev/null +++ b/releases/3.2.94/usb-fix-typo-in-the-definition-of-endpointrequest.patch @@ -0,0 +1,31 @@ +From: Benjamin Herrenschmidt <benh@kernel.crashing.org> +Date: Tue, 13 Jun 2017 16:01:13 +1000 +Subject: usb: Fix typo in the definition of Endpoint[out]Request + +commit 7cf916bd639bd26db7214f2205bccdb4b9306256 upstream. + +The current definition is wrong. This breaks my upcoming +Aspeed virtual hub driver. + +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/linux/usb/hcd.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -489,9 +489,9 @@ extern void usb_ep0_reinit(struct usb_de + ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) + + #define EndpointRequest \ +- ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) ++ ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) + #define EndpointOutRequest \ +- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) ++ ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) + + /* class requests from the USB 2.0 hub spec, table 11-15 */ + /* GetBusState and SetHubDescriptor are optional, omitted */ diff --git a/releases/3.2.94/usb-serial-cp210x-add-id-for-cel-em3588-usb-zigbee-stick.patch b/releases/3.2.94/usb-serial-cp210x-add-id-for-cel-em3588-usb-zigbee-stick.patch new file mode 100644 index 00000000..0e6479e8 --- /dev/null +++ b/releases/3.2.94/usb-serial-cp210x-add-id-for-cel-em3588-usb-zigbee-stick.patch @@ -0,0 +1,27 @@ +From: Jeremie Rapin <rapinj@gmail.com> +Date: Wed, 28 Jun 2017 18:23:25 +0200 +Subject: USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick + +commit fd90f73a9925f248d696bde1cfc836d9fda5570d upstream. + +Added the USB serial device ID for the CEL ZigBee EM3588 +radio stick. + +Signed-off-by: Jeremie Rapin <rapinj@gmail.com> +Acked-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/cp210x.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -140,6 +140,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ + { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ + { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ ++ { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */ + { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ diff --git a/releases/3.2.94/usb-usbip-set-buffer-pointers-to-null-after-free.patch b/releases/3.2.94/usb-usbip-set-buffer-pointers-to-null-after-free.patch new file mode 100644 index 00000000..8461fd40 --- /dev/null +++ b/releases/3.2.94/usb-usbip-set-buffer-pointers-to-null-after-free.patch @@ -0,0 +1,51 @@ +From: Michael Grzeschik <m.grzeschik@pengutronix.de> +Date: Mon, 22 May 2017 13:02:44 +0200 +Subject: usb: usbip: set buffer pointers to NULL after free + +commit b3b51417d0af63fb9a06662dc292200aed9ea53f upstream. + +The usbip stack dynamically allocates the transfer_buffer and +setup_packet of each urb that got generated by the tcp to usb stub code. +As these pointers are always used only once we will set them to NULL +after use. This is done likewise to the free_urb code in vudc_dev.c. +This patch fixes double kfree situations where the usbip remote side +added the URB_FREE_BUFFER. + +Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> +Acked-by: Shuah Khan <shuahkh@osg.samsung.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.2: adjust filenames] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/staging/usbip/stub_main.c | 4 ++++ + drivers/staging/usbip/stub_tx.c | 4 ++++ + 2 files changed, 8 insertions(+) + +--- a/drivers/staging/usbip/stub_main.c ++++ b/drivers/staging/usbip/stub_main.c +@@ -237,7 +237,11 @@ void stub_device_cleanup_urbs(struct stu + kmem_cache_free(stub_priv_cache, priv); + + kfree(urb->transfer_buffer); ++ urb->transfer_buffer = NULL; ++ + kfree(urb->setup_packet); ++ urb->setup_packet = NULL; ++ + usb_free_urb(urb); + } + } +--- a/drivers/staging/usbip/stub_tx.c ++++ b/drivers/staging/usbip/stub_tx.c +@@ -28,7 +28,11 @@ static void stub_free_priv_and_urb(struc + struct urb *urb = priv->urb; + + kfree(urb->setup_packet); ++ urb->setup_packet = NULL; ++ + kfree(urb->transfer_buffer); ++ urb->transfer_buffer = NULL; ++ + list_del(&priv->list); + kmem_cache_free(stub_priv_cache, priv); + usb_free_urb(urb); diff --git a/releases/3.2.94/video-fbdev-aty-do-not-leak-uninitialized-padding-in-clk-to.patch b/releases/3.2.94/video-fbdev-aty-do-not-leak-uninitialized-padding-in-clk-to.patch new file mode 100644 index 00000000..2be327ad --- /dev/null +++ b/releases/3.2.94/video-fbdev-aty-do-not-leak-uninitialized-padding-in-clk-to.patch @@ -0,0 +1,32 @@ +From: Vladis Dronov <vdronov@redhat.com> +Date: Mon, 4 Sep 2017 16:00:50 +0200 +Subject: video: fbdev: aty: do not leak uninitialized padding in clk to + userspace + +commit 8e75f7a7a00461ef6d91797a60b606367f6e344d upstream. + +'clk' is copied to a userland with padding byte(s) after 'vclk_post_div' +field unitialized, leaking data from the stack. Fix this ensuring all of +'clk' is initialized to zero. + +References: https://github.com/torvalds/linux/pull/441 +Reported-by: sohu0106 <sohu0106@126.com> +Signed-off-by: Vladis Dronov <vdronov@redhat.com> +Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> +[bwh: Backported to 3.2: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/video/aty/atyfb_base.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/video/aty/atyfb_base.c ++++ b/drivers/video/aty/atyfb_base.c +@@ -1852,7 +1852,7 @@ static int atyfb_ioctl(struct fb_info *i + #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT) + case ATYIO_CLKR: + if (M64_HAS(INTEGRATED)) { +- struct atyclk clk; ++ struct atyclk clk = { 0 }; + union aty_pll *pll = &par->pll; + u32 dsp_config = pll->ct.dsp_config; + u32 dsp_on_off = pll->ct.dsp_on_off; diff --git a/releases/3.2.94/vt-fix-unchecked-__put_user-in-tioclinux-ioctls.patch b/releases/3.2.94/vt-fix-unchecked-__put_user-in-tioclinux-ioctls.patch new file mode 100644 index 00000000..5448b048 --- /dev/null +++ b/releases/3.2.94/vt-fix-unchecked-__put_user-in-tioclinux-ioctls.patch @@ -0,0 +1,48 @@ +From: Adam Borowski <kilobyte@angband.pl> +Date: Sat, 3 Jun 2017 09:35:06 +0200 +Subject: vt: fix unchecked __put_user() in tioclinux ioctls + +commit 6987dc8a70976561d22450b5858fc9767788cc1c upstream. + +Only read access is checked before this call. + +Actually, at the moment this is not an issue, as every in-tree arch does +the same manual checks for VERIFY_READ vs VERIFY_WRITE, relying on the MMU +to tell them apart, but this wasn't the case in the past and may happen +again on some odd arch in the future. + +If anyone cares about 3.7 and earlier, this is a security hole (untested) +on real 80386 CPUs. + +Signed-off-by: Adam Borowski <kilobyte@angband.pl> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/tty/vt/vt.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -2650,18 +2650,18 @@ int tioclinux(struct tty_struct *tty, un + * related to the kernel should not use this. + */ + data = shift_state; +- ret = __put_user(data, p); ++ ret = put_user(data, p); + break; + case TIOCL_GETMOUSEREPORTING: + data = mouse_reporting(); +- ret = __put_user(data, p); ++ ret = put_user(data, p); + break; + case TIOCL_SETVESABLANK: + ret = set_vesa_blanking(p); + break; + case TIOCL_GETKMSGREDIRECT: + data = vt_get_kmsg_redirect(); +- ret = __put_user(data, p); ++ ret = put_user(data, p); + break; + case TIOCL_SETKMSGREDIRECT: + if (!capable(CAP_SYS_ADMIN)) { diff --git a/releases/3.2.94/wlcore-fix-64k-page-support.patch b/releases/3.2.94/wlcore-fix-64k-page-support.patch new file mode 100644 index 00000000..49f92856 --- /dev/null +++ b/releases/3.2.94/wlcore-fix-64k-page-support.patch @@ -0,0 +1,37 @@ +From: Arnd Bergmann <arnd@arndb.de> +Date: Thu, 11 May 2017 13:52:09 +0200 +Subject: wlcore: fix 64K page support + +commit 4a4274bf2dbbd1c7a45be0c89a1687c9d2eef4a0 upstream. + +In the stable linux-3.16 branch, I ran into a warning in the +wlcore driver: + +drivers/net/wireless/ti/wlcore/spi.c: In function 'wl12xx_spi_raw_write': +drivers/net/wireless/ti/wlcore/spi.c:315:1: error: the frame size of 12848 bytes is larger than 2048 bytes [-Werror=frame-larger-than=] + +Newer kernels no longer show the warning, but the bug is still there, +as the allocation is based on the CPU page size rather than the +actual capabilities of the hardware. + +This replaces the PAGE_SIZE macro with the SZ_4K macro, i.e. 4096 bytes +per buffer. + +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> +[bwh: Backported to 3.2: + - Open-code SZ_4K as it is only defined on some architectures here(!) + - Adjust filename, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/net/wireless/wl12xx/wl12xx.h ++++ b/drivers/net/wireless/wl12xx/wl12xx.h +@@ -166,7 +166,7 @@ extern u32 wl12xx_debug_level; + + #define ACX_TX_DESCRIPTORS 16 + +-#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) ++#define WL1271_AGGR_BUFFER_SIZE (4 * 0x00001000) + + enum wl1271_state { + WL1271_STATE_OFF, diff --git a/releases/3.2.94/xfs-xfs_is_realtime_inode-should-be-false-if-no-rt-device-present.patch b/releases/3.2.94/xfs-xfs_is_realtime_inode-should-be-false-if-no-rt-device-present.patch new file mode 100644 index 00000000..e5a64829 --- /dev/null +++ b/releases/3.2.94/xfs-xfs_is_realtime_inode-should-be-false-if-no-rt-device-present.patch @@ -0,0 +1,68 @@ +From: Richard Wareing <rwareing@fb.com> +Date: Wed, 13 Sep 2017 09:09:35 +1000 +Subject: xfs: XFS_IS_REALTIME_INODE() should be false if no rt device present + +commit b31ff3cdf540110da4572e3e29bd172087af65cc upstream. + +If using a kernel with CONFIG_XFS_RT=y and we set the RHINHERIT flag on +a directory in a filesystem that does not have a realtime device and +create a new file in that directory, it gets marked as a real time file. +When data is written and a fsync is issued, the filesystem attempts to +flush a non-existent rt device during the fsync process. + +This results in a crash dereferencing a null buftarg pointer in +xfs_blkdev_issue_flush(): + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 + IP: xfs_blkdev_issue_flush+0xd/0x20 + ..... + Call Trace: + xfs_file_fsync+0x188/0x1c0 + vfs_fsync_range+0x3b/0xa0 + do_fsync+0x3d/0x70 + SyS_fsync+0x10/0x20 + do_syscall_64+0x4d/0xb0 + entry_SYSCALL64_slow_path+0x25/0x25 + +Setting RT inode flags does not require special privileges so any +unprivileged user can cause this oops to occur. To reproduce, confirm +kernel is compiled with CONFIG_XFS_RT=y and run: + + # mkfs.xfs -f /dev/pmem0 + # mount /dev/pmem0 /mnt/test + # mkdir /mnt/test/foo + # xfs_io -c 'chattr +t' /mnt/test/foo + # xfs_io -f -c 'pwrite 0 5m' -c fsync /mnt/test/foo/bar + +Or just run xfstests with MKFS_OPTIONS="-d rtinherit=1" and wait. + +Kernels built with CONFIG_XFS_RT=n are not exposed to this bug. + +Fixes: f538d4da8d52 ("[XFS] write barrier support") +Signed-off-by: Richard Wareing <rwareing@fb.com> +Signed-off-by: Dave Chinner <david@fromorbit.com> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.2: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/xfs/xfs_dinode.h | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/fs/xfs/xfs_dinode.h ++++ b/fs/xfs/xfs_dinode.h +@@ -201,7 +201,14 @@ static inline void xfs_dinode_put_rdev(s + #define XFS_DIFLAG_FILESTREAM (1 << XFS_DIFLAG_FILESTREAM_BIT) + + #ifdef CONFIG_XFS_RT +-#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) ++ ++/* ++ * make sure we ignore the inode flag if the filesystem doesn't have a ++ * configured realtime device. ++ */ ++#define XFS_IS_REALTIME_INODE(ip) \ ++ (((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) && \ ++ (ip)->i_mount->m_rtdev_targp) + #else + #define XFS_IS_REALTIME_INODE(ip) (0) + #endif diff --git a/releases/3.2.94/xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch b/releases/3.2.94/xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch new file mode 100644 index 00000000..8be97e8a --- /dev/null +++ b/releases/3.2.94/xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch @@ -0,0 +1,77 @@ +From: Jiahau Chang <jiahau@gmail.com> +Date: Mon, 19 Jun 2017 13:08:30 +0300 +Subject: xhci: Limit USB2 port wake support for AMD Promontory hosts + +commit dec08194ffeccfa1cf085906b53d301930eae18f upstream. + +For AMD Promontory xHCI host, although you can disable USB 2.0 ports in +BIOS settings, those ports will be enabled anyway after you remove a +device on that port and re-plug it in again. It's a known limitation of +the chip. As a workaround we can clear the PORT_WAKE_BITS. + +This will disable wake on connect, disconnect and overcurrent on +AMD Promontory USB2 ports + +[checkpatch cleanup and commit message reword -Mathias] +Cc: Tsai Nicholas <nicholas.tsai@amd.com> +Signed-off-by: Jiahau Chang <Lars_Chang@asmedia.com.tw> +Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/host/xhci-hub.c | 3 +++ + drivers/usb/host/xhci-pci.c | 12 ++++++++++++ + drivers/usb/host/xhci.h | 1 + + 3 files changed, 16 insertions(+) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -1023,6 +1023,9 @@ int xhci_bus_suspend(struct usb_hcd *hcd + t2 |= PORT_WKOC_E | PORT_WKCONN_E; + t2 &= ~PORT_WKDISC_E; + } ++ if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) && ++ (hcd->speed < HCD_USB3)) ++ t2 &= ~PORT_WAKE_BITS; + } else + t2 &= ~PORT_WAKE_BITS; + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -45,6 +45,11 @@ + #define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8 + #define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0 + ++#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 ++#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba ++#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb ++#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc ++ + static const char hcd_name[] = "xhci_hcd"; + + /* called after powerup, by probe or system-pm "wakeup" */ +@@ -110,6 +115,13 @@ static void xhci_pci_quirks(struct devic + if (pdev->vendor == PCI_VENDOR_ID_AMD) + xhci->quirks |= XHCI_TRUST_TX_LENGTH; + ++ if ((pdev->vendor == PCI_VENDOR_ID_AMD) && ++ ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) || ++ (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) || ++ (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) || ++ (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1))) ++ xhci->quirks |= XHCI_U2_DISABLE_WAKE; ++ + if (pdev->vendor == PCI_VENDOR_ID_INTEL) + xhci->quirks |= XHCI_INTEL_HOST; + if (pdev->vendor == PCI_VENDOR_ID_INTEL) +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1502,6 +1502,7 @@ struct xhci_hcd { + #define XHCI_SPURIOUS_WAKEUP (1 << 18) + #define XHCI_PME_STUCK_QUIRK (1 << 20) + #define XHCI_MISSING_CAS (1 << 24) ++#define XHCI_U2_DISABLE_WAKE (1 << 27) + unsigned int num_active_eps; + unsigned int limit_active_eps; + /* There are two roothubs to keep track of bus suspend info for */ |