* [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite
@ 2016-03-30 14:25 Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] ipr: Fix regression when loading firmware Jiri Slaby
` (11 more replies)
0 siblings, 12 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable; +Cc: Insu Yun, Martin K . Petersen, Ben Hutchings, Jiri Slaby
From: Insu Yun <wuninsu@gmail.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit d63c7dd5bcb9441af0526d370c43a65ca2c980d9 upstream.
Return value of snprintf is not bound by size value, 2nd argument.
(https://www.kernel.org/doc/htmldocs/kernel-api/API-snprintf.html).
Return value is number of printed chars, can be larger than 2nd
argument. Therefore, it can write null byte out of bounds ofbuffer.
Since snprintf puts null, it does not need to put additional null byte.
Signed-off-by: Insu Yun <wuninsu@gmail.com>
Reviewed-by: Shane Seymour <shane.seymour@hpe.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Cc: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
drivers/scsi/ipr.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 0f6412db121c..4fa12a4467d2 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3946,13 +3946,12 @@ static ssize_t ipr_store_update_fw(struct device *dev,
struct ipr_sglist *sglist;
char fname[100];
char *src;
- int len, result, dnld_size;
+ int result, dnld_size;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- len = snprintf(fname, 99, "%s", buf);
- fname[len-1] = '\0';
+ snprintf(fname, sizeof(fname), "%s", buf);
if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) {
dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname);
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] ipr: Fix regression when loading firmware
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] ipv4: Don't do expensive useless work during inetdev destroy Jiri Slaby
` (10 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable
Cc: Gabriel Krisman Bertazi, Insu Yun, Martin K . Petersen,
Ben Hutchings, Jiri Slaby
From: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit 21b81716c6bff24cda52dc75588455f879ddbfe9 upstream.
Commit d63c7dd5bcb9 ("ipr: Fix out-of-bounds null overwrite") removed
the end of line handling when storing the update_fw sysfs attribute.
This changed the userpace API because it started refusing writes
terminated by a line feed, which broke the update tools we already have.
This patch re-adds that handling, so both a write terminated by a line
feed or not can make it through with the update.
Fixes: d63c7dd5bcb9 ("ipr: Fix out-of-bounds null overwrite")
Signed-off-by: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
Cc: Insu Yun <wuninsu@gmail.com>
Acked-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Cc: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
drivers/scsi/ipr.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 4fa12a4467d2..d4473d2f8739 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3946,6 +3946,7 @@ static ssize_t ipr_store_update_fw(struct device *dev,
struct ipr_sglist *sglist;
char fname[100];
char *src;
+ char *endline;
int result, dnld_size;
if (!capable(CAP_SYS_ADMIN))
@@ -3953,6 +3954,10 @@ static ssize_t ipr_store_update_fw(struct device *dev,
snprintf(fname, sizeof(fname), "%s", buf);
+ endline = strchr(fname, '\n');
+ if (endline)
+ *endline = '\0';
+
if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) {
dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname);
return -EIO;
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] ipv4: Don't do expensive useless work during inetdev destroy.
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] ipr: Fix regression when loading firmware Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] umount: Do not allow unmounting rootfs Jiri Slaby
` (9 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable; +Cc: David S. Miller, Jiri Slaby
From: "David S. Miller" <davem@davemloft.net>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit fbd40ea0180a2d328c5adc61414dc8bab9335ce2 upstream.
When an inetdev is destroyed, every address assigned to the interface
is removed. And in this scenerio we do two pointless things which can
be very expensive if the number of assigned interfaces is large:
1) Address promotion. We are deleting all addresses, so there is no
point in doing this.
2) A full nf conntrack table purge for every address. We only need to
do this once, as is already caught by the existing
masq_dev_notifier so masq_inet_event() can skip this.
[mk] 3.12.*: The change in masq_inet_event() needs to be duplicated in
both IPv4 and IPv6 version of the function, these two were merged in
3.18.
Reported-by: Solar Designer <solar@openwall.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Tested-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
net/ipv4/devinet.c | 4 ++++
net/ipv4/fib_frontend.c | 4 ++++
net/ipv4/netfilter/ipt_MASQUERADE.c | 12 ++++++++++--
net/ipv6/netfilter/ip6t_MASQUERADE.c | 12 ++++++++++--
4 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 68447109000f..6678bebb82c8 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -328,6 +328,9 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
ASSERT_RTNL();
+ if (in_dev->dead)
+ goto no_promotions;
+
/* 1. Deleting primary ifaddr forces deletion all secondaries
* unless alias promotion is set
**/
@@ -374,6 +377,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
fib_del_ifaddr(ifa, ifa1);
}
+no_promotions:
/* 2. Unlink it */
*ifap = ifa1->ifa_next;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index f7f8cff67344..25a0946f7074 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -812,6 +812,9 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
subnet = 1;
}
+ if (in_dev->dead)
+ goto no_promotions;
+
/* Deletion is more complicated than add.
* We should take care of not to delete too much :-)
*
@@ -887,6 +890,7 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
}
}
+no_promotions:
if (!(ok & BRD_OK))
fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
if (subnet && ifa->ifa_prefixlen < 31) {
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 00352ce0f0de..3bc1c98aa2f0 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -128,10 +128,18 @@ static int masq_inet_event(struct notifier_block *this,
unsigned long event,
void *ptr)
{
- struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
+ struct in_device *idev = ((struct in_ifaddr *)ptr)->ifa_dev;
struct netdev_notifier_info info;
- netdev_notifier_info_init(&info, dev);
+ /* The masq_dev_notifier will catch the case of the device going
+ * down. So if the inetdev is dead and being destroyed we have
+ * no work to do. Otherwise this is an individual address removal
+ * and we have to perform the flush.
+ */
+ if (idev->dead)
+ return NOTIFY_DONE;
+
+ netdev_notifier_info_init(&info, idev->dev);
return masq_device_event(this, event, &info);
}
diff --git a/net/ipv6/netfilter/ip6t_MASQUERADE.c b/net/ipv6/netfilter/ip6t_MASQUERADE.c
index 3e4e92d5e157..bee09e9050c3 100644
--- a/net/ipv6/netfilter/ip6t_MASQUERADE.c
+++ b/net/ipv6/netfilter/ip6t_MASQUERADE.c
@@ -88,10 +88,18 @@ static struct notifier_block masq_dev_notifier = {
static int masq_inet_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
- struct inet6_ifaddr *ifa = ptr;
+ struct inet6_dev *idev = ((struct inet6_ifaddr *)ptr)->idev;
struct netdev_notifier_info info;
- netdev_notifier_info_init(&info, ifa->idev->dev);
+ /* The masq_dev_notifier will catch the case of the device going
+ * down. So if the inetdev is dead and being destroyed we have
+ * no work to do. Otherwise this is an individual address removal
+ * and we have to perform the flush.
+ */
+ if (idev->dead)
+ return NOTIFY_DONE;
+
+ netdev_notifier_info_init(&info, idev->dev);
return masq_device_event(this, event, &info);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] umount: Do not allow unmounting rootfs.
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] ipr: Fix regression when loading firmware Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] ipv4: Don't do expensive useless work during inetdev destroy Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] kernel: Provide READ_ONCE and ASSIGN_ONCE Jiri Slaby
` (8 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable; +Cc: Eric W. Biederman, Jiri Slaby
From: "Eric W. Biederman" <ebiederm@xmission.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit da362b09e42ee0bcaf0356afee6078b4f324baff upstream.
Andrew Vagin <avagin@parallels.com> writes:
> #define _GNU_SOURCE
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <sched.h>
> #include <unistd.h>
> #include <sys/mount.h>
>
> int main(int argc, char **argv)
> {
> int fd;
>
> fd = open("/proc/self/ns/mnt", O_RDONLY);
> if (fd < 0)
> return 1;
> while (1) {
> if (umount2("/", MNT_DETACH) ||
> setns(fd, CLONE_NEWNS))
> break;
> }
>
> return 0;
> }
>
> root@ubuntu:/home/avagin# gcc -Wall nsenter.c -o nsenter
> root@ubuntu:/home/avagin# strace ./nsenter
> execve("./nsenter", ["./nsenter"], [/* 22 vars */]) = 0
> ...
> open("/proc/self/ns/mnt", O_RDONLY) = 3
> umount("/", MNT_DETACH) = 0
> setns(3, 131072) = 0
> umount("/", MNT_DETACH
>
causes:
> [ 260.548301] ------------[ cut here ]------------
> [ 260.550941] kernel BUG at /build/buildd/linux-3.13.0/fs/pnode.c:372!
> [ 260.552068] invalid opcode: 0000 [#1] SMP
> [ 260.552068] Modules linked in: xt_CHECKSUM iptable_mangle xt_tcpudp xt_addrtype xt_conntrack ipt_MASQUERADE iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack bridge stp llc dm_thin_pool dm_persistent_data dm_bufio dm_bio_prison iptable_filter ip_tables x_tables crct10dif_pclmul crc32_pclmul ghash_clmulni_intel binfmt_misc nfsd auth_rpcgss nfs_acl aesni_intel nfs lockd aes_x86_64 sunrpc fscache lrw gf128mul glue_helper ablk_helper cryptd serio_raw ppdev parport_pc lp parport btrfs xor raid6_pq libcrc32c psmouse floppy
> [ 260.552068] CPU: 0 PID: 1723 Comm: nsenter Not tainted 3.13.0-30-generic #55-Ubuntu
> [ 260.552068] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
> [ 260.552068] task: ffff8800376097f0 ti: ffff880074824000 task.ti: ffff880074824000
> [ 260.552068] RIP: 0010:[<ffffffff811e9483>] [<ffffffff811e9483>] propagate_umount+0x123/0x130
> [ 260.552068] RSP: 0018:ffff880074825e98 EFLAGS: 00010246
> [ 260.552068] RAX: ffff88007c741140 RBX: 0000000000000002 RCX: ffff88007c741190
> [ 260.552068] RDX: ffff88007c741190 RSI: ffff880074825ec0 RDI: ffff880074825ec0
> [ 260.552068] RBP: ffff880074825eb0 R08: 00000000000172e0 R09: ffff88007fc172e0
> [ 260.552068] R10: ffffffff811cc642 R11: ffffea0001d59000 R12: ffff88007c741140
> [ 260.552068] R13: ffff88007c741140 R14: ffff88007c741140 R15: 0000000000000000
> [ 260.552068] FS: 00007fd5c7e41740(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000
> [ 260.552068] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 260.552068] CR2: 00007fd5c7968050 CR3: 0000000070124000 CR4: 00000000000406f0
> [ 260.552068] Stack:
> [ 260.552068] 0000000000000002 0000000000000002 ffff88007c631000 ffff880074825ed8
> [ 260.552068] ffffffff811dcfac ffff88007c741140 0000000000000002 ffff88007c741160
> [ 260.552068] ffff880074825f38 ffffffff811dd12b ffffffff811cc642 0000000075640000
> [ 260.552068] Call Trace:
> [ 260.552068] [<ffffffff811dcfac>] umount_tree+0x20c/0x260
> [ 260.552068] [<ffffffff811dd12b>] do_umount+0x12b/0x300
> [ 260.552068] [<ffffffff811cc642>] ? final_putname+0x22/0x50
> [ 260.552068] [<ffffffff811cc849>] ? putname+0x29/0x40
> [ 260.552068] [<ffffffff811dd88c>] SyS_umount+0xdc/0x100
> [ 260.552068] [<ffffffff8172aeff>] tracesys+0xe1/0xe6
> [ 260.552068] Code: 89 50 08 48 8b 50 08 48 89 02 49 89 45 08 e9 72 ff ff ff 0f 1f 44 00 00 4c 89 e6 4c 89 e7 e8 f5 f6 ff ff 48 89 c3 e9 39 ff ff ff <0f> 0b 66 2e 0f 1f 84 00 00 00 00 00 90 66 66 66 66 90 55 b8 01
> [ 260.552068] RIP [<ffffffff811e9483>] propagate_umount+0x123/0x130
> [ 260.552068] RSP <ffff880074825e98>
> [ 260.611451] ---[ end trace 11c33d85f1d4c652 ]--
Which in practice is totally uninteresting. Only the global root user can
do it, and it is just a stupid thing to do.
However that is no excuse to allow a silly way to oops the kernel.
We can avoid this silly problem by setting MNT_LOCKED on the rootfs
mount point and thus avoid needing any special cases in the unmount
code.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
fs/namespace.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/namespace.c b/fs/namespace.c
index bdc6223a7500..d727b0ce11df 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2809,6 +2809,7 @@ static void __init init_mount_tree(void)
root.mnt = mnt;
root.dentry = mnt->mnt_root;
+ mnt->mnt_flags |= MNT_LOCKED;
set_fs_pwd(current->fs, &root);
set_fs_root(current->fs, &root);
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] kernel: Provide READ_ONCE and ASSIGN_ONCE
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
` (2 preceding siblings ...)
2016-03-30 14:25 ` [patch added to 3.12-stable] umount: Do not allow unmounting rootfs Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
2016-03-30 16:33 ` Christian Borntraeger
2016-03-30 14:25 ` [patch added to 3.12-stable] xen: Add RING_COPY_REQUEST() Jiri Slaby
` (7 subsequent siblings)
11 siblings, 1 reply; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable; +Cc: Christian Borntraeger, Jiri Slaby
From: Christian Borntraeger <borntraeger@de.ibm.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit 230fa253df6352af12ad0a16128760b5cb3f92df upstream.
ACCESS_ONCE does not work reliably on non-scalar types. For
example gcc 4.6 and 4.7 might remove the volatile tag for such
accesses during the SRA (scalar replacement of aggregates) step
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145)
Let's provide READ_ONCE/ASSIGN_ONCE that will do all accesses via
scalar types as suggested by Linus Torvalds. Accesses larger than
the machines word size cannot be guaranteed to be atomic. These
macros will use memcpy and emit a build warning.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
include/linux/compiler.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 19a199414bd0..237063adbe1b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -179,6 +179,80 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
# define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
#endif
+#include <uapi/linux/types.h>
+
+static __always_inline void data_access_exceeds_word_size(void)
+#ifdef __compiletime_warning
+__compiletime_warning("data access exceeds word size and won't be atomic")
+#endif
+;
+
+static __always_inline void data_access_exceeds_word_size(void)
+{
+}
+
+static __always_inline void __read_once_size(volatile void *p, void *res, int size)
+{
+ switch (size) {
+ case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
+ case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
+ case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
+#ifdef CONFIG_64BIT
+ case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
+#endif
+ default:
+ barrier();
+ __builtin_memcpy((void *)res, (const void *)p, size);
+ data_access_exceeds_word_size();
+ barrier();
+ }
+}
+
+static __always_inline void __assign_once_size(volatile void *p, void *res, int size)
+{
+ switch (size) {
+ case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
+ case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
+ case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
+#ifdef CONFIG_64BIT
+ case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
+#endif
+ default:
+ barrier();
+ __builtin_memcpy((void *)p, (const void *)res, size);
+ data_access_exceeds_word_size();
+ barrier();
+ }
+}
+
+/*
+ * Prevent the compiler from merging or refetching reads or writes. The
+ * compiler is also forbidden from reordering successive instances of
+ * READ_ONCE, ASSIGN_ONCE and ACCESS_ONCE (see below), but only when the
+ * compiler is aware of some particular ordering. One way to make the
+ * compiler aware of ordering is to put the two invocations of READ_ONCE,
+ * ASSIGN_ONCE or ACCESS_ONCE() in different C statements.
+ *
+ * In contrast to ACCESS_ONCE these two macros will also work on aggregate
+ * data types like structs or unions. If the size of the accessed data
+ * type exceeds the word size of the machine (e.g., 32 bits or 64 bits)
+ * READ_ONCE() and ASSIGN_ONCE() will fall back to memcpy and print a
+ * compile-time warning.
+ *
+ * Their two major use cases are: (1) Mediating communication between
+ * process-level code and irq/NMI handlers, all running on the same CPU,
+ * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
+ * mutilate accesses that either do not require ordering or that interact
+ * with an explicit memory barrier or atomic instruction that provides the
+ * required ordering.
+ */
+
+#define READ_ONCE(x) \
+ ({ typeof(x) __val; __read_once_size(&x, &__val, sizeof(__val)); __val; })
+
+#define ASSIGN_ONCE(val, x) \
+ ({ typeof(x) __val; __val = val; __assign_once_size(&x, &__val, sizeof(__val)); __val; })
+
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] xen: Add RING_COPY_REQUEST()
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
` (3 preceding siblings ...)
2016-03-30 14:25 ` [patch added to 3.12-stable] kernel: Provide READ_ONCE and ASSIGN_ONCE Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-netback: don't use last request to determine minimum Tx credit Jiri Slaby
` (6 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable; +Cc: David Vrabel, Konrad Rzeszutek Wilk, Jiri Slaby
From: David Vrabel <david.vrabel@citrix.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit 454d5d882c7e412b840e3c99010fe81a9862f6fb upstream.
Using RING_GET_REQUEST() on a shared ring is easy to use incorrectly
(i.e., by not considering that the other end may alter the data in the
shared ring while it is being inspected). Safe usage of a request
generally requires taking a local copy.
Provide a RING_COPY_REQUEST() macro to use instead of
RING_GET_REQUEST() and an open-coded memcpy(). This takes care of
ensuring that the copy is done correctly regardless of any possible
compiler optimizations.
Use a volatile source to prevent the compiler from reordering or
omitting the copy.
This is part of XSA155.
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
include/xen/interface/io/ring.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h
index 7d28aff605c7..7dc685b4057d 100644
--- a/include/xen/interface/io/ring.h
+++ b/include/xen/interface/io/ring.h
@@ -181,6 +181,20 @@ struct __name##_back_ring { \
#define RING_GET_REQUEST(_r, _idx) \
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
+/*
+ * Get a local copy of a request.
+ *
+ * Use this in preference to RING_GET_REQUEST() so all processing is
+ * done on a local copy that cannot be modified by the other end.
+ *
+ * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this
+ * to be ineffective where _req is a struct which consists of only bitfields.
+ */
+#define RING_COPY_REQUEST(_r, _idx, _req) do { \
+ /* Use volatile to force the copy into _req. */ \
+ *(_req) = *(volatile typeof(_req))RING_GET_REQUEST(_r, _idx); \
+} while (0)
+
#define RING_GET_RESPONSE(_r, _idx) \
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] xen-netback: don't use last request to determine minimum Tx credit
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
` (4 preceding siblings ...)
2016-03-30 14:25 ` [patch added to 3.12-stable] xen: Add RING_COPY_REQUEST() Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-netback: use RING_COPY_REQUEST() throughout Jiri Slaby
` (5 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable; +Cc: David Vrabel, Konrad Rzeszutek Wilk, Jiri Slaby
From: David Vrabel <david.vrabel@citrix.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit 0f589967a73f1f30ab4ac4dd9ce0bb399b4d6357 upstream.
The last from guest transmitted request gives no indication about the
minimum amount of credit that the guest might need to send a packet
since the last packet might have been a small one.
Instead allow for the worst case 128 KiB packet.
This is part of XSA155.
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
drivers/net/xen-netback/netback.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index a1186533cee8..d4a1db9fb224 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -695,9 +695,7 @@ static void tx_add_credit(struct xenvif *vif)
* Allow a burst big enough to transmit a jumbo packet of up to 128kB.
* Otherwise the interface can seize up due to insufficient credit.
*/
- max_burst = RING_GET_REQUEST(&vif->tx, vif->tx.req_cons)->size;
- max_burst = min(max_burst, 131072UL);
- max_burst = max(max_burst, vif->credit_bytes);
+ max_burst = max(131072UL, vif->credit_bytes);
/* Take care that adding a new chunk of credit doesn't wrap to zero. */
max_credit = vif->remaining_credit + vif->credit_bytes;
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] xen-netback: use RING_COPY_REQUEST() throughout
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
` (5 preceding siblings ...)
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-netback: don't use last request to determine minimum Tx credit Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-blkback: only read request operation from shared ring once Jiri Slaby
` (4 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable; +Cc: David Vrabel, Konrad Rzeszutek Wilk, Jiri Slaby
From: David Vrabel <david.vrabel@citrix.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit 68a33bfd8403e4e22847165d149823a2e0e67c9c upstream.
Instead of open-coding memcpy()s and directly accessing Tx and Rx
requests, use the new RING_COPY_REQUEST() that ensures the local copy
is correct.
This is more than is strictly necessary for guest Rx requests since
only the id and gref fields are used and it is harmless if the
frontend modifies these.
This is part of XSA155.
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
drivers/net/xen-netback/netback.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index d4a1db9fb224..a773794bb7f2 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -313,17 +313,17 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif *vif,
struct netrx_pending_operations *npo)
{
struct xenvif_rx_meta *meta;
- struct xen_netif_rx_request *req;
+ struct xen_netif_rx_request req;
- req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++);
+ RING_COPY_REQUEST(&vif->rx, vif->rx.req_cons++, &req);
meta = npo->meta + npo->meta_prod++;
meta->gso_size = 0;
meta->size = 0;
- meta->id = req->id;
+ meta->id = req.id;
npo->copy_off = 0;
- npo->copy_gref = req->gref;
+ npo->copy_gref = req.gref;
return meta;
}
@@ -424,7 +424,7 @@ static int xenvif_gop_skb(struct sk_buff *skb,
struct xenvif *vif = netdev_priv(skb->dev);
int nr_frags = skb_shinfo(skb)->nr_frags;
int i;
- struct xen_netif_rx_request *req;
+ struct xen_netif_rx_request req;
struct xenvif_rx_meta *meta;
unsigned char *data;
int head = 1;
@@ -434,14 +434,14 @@ static int xenvif_gop_skb(struct sk_buff *skb,
/* Set up a GSO prefix descriptor, if necessary */
if (skb_shinfo(skb)->gso_size && vif->gso_prefix) {
- req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++);
+ RING_COPY_REQUEST(&vif->rx, vif->rx.req_cons++, &req);
meta = npo->meta + npo->meta_prod++;
meta->gso_size = skb_shinfo(skb)->gso_size;
meta->size = 0;
- meta->id = req->id;
+ meta->id = req.id;
}
- req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++);
+ RING_COPY_REQUEST(&vif->rx, vif->rx.req_cons++, &req);
meta = npo->meta + npo->meta_prod++;
if (!vif->gso_prefix)
@@ -450,9 +450,9 @@ static int xenvif_gop_skb(struct sk_buff *skb,
meta->gso_size = 0;
meta->size = 0;
- meta->id = req->id;
+ meta->id = req.id;
npo->copy_off = 0;
- npo->copy_gref = req->gref;
+ npo->copy_gref = req.gref;
data = skb->data;
while (data < skb_tail_pointer(skb)) {
@@ -721,7 +721,7 @@ static void xenvif_tx_err(struct xenvif *vif,
make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR);
if (cons == end)
break;
- txp = RING_GET_REQUEST(&vif->tx, cons++);
+ RING_COPY_REQUEST(&vif->tx, cons++, txp);
} while (1);
vif->tx.req_cons = cons;
}
@@ -786,8 +786,7 @@ static int xenvif_count_requests(struct xenvif *vif,
if (drop_err)
txp = &dropped_tx;
- memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + slots),
- sizeof(*txp));
+ RING_COPY_REQUEST(&vif->tx, cons + slots, txp);
/* If the guest submitted a frame >= 64 KiB then
* first->size overflowed and following slots will
@@ -1073,8 +1072,7 @@ static int xenvif_get_extras(struct xenvif *vif,
return -EBADR;
}
- memcpy(&extra, RING_GET_REQUEST(&vif->tx, cons),
- sizeof(extra));
+ RING_COPY_REQUEST(&vif->tx, cons, &extra);
if (unlikely(!extra.type ||
extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
vif->tx.req_cons = ++cons;
@@ -1250,7 +1248,7 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif)
idx = vif->tx.req_cons;
rmb(); /* Ensure that we see the request before we copy it. */
- memcpy(&txreq, RING_GET_REQUEST(&vif->tx, idx), sizeof(txreq));
+ RING_COPY_REQUEST(&vif->tx, idx, &txreq);
/* Credit-based scheduling. */
if (txreq.size > vif->remaining_credit &&
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] xen-blkback: only read request operation from shared ring once
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
` (6 preceding siblings ...)
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-netback: use RING_COPY_REQUEST() throughout Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-blkback: read from indirect descriptors only once Jiri Slaby
` (3 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable
Cc: Roger Pau Monné, David Vrabel, Konrad Rzeszutek Wilk,
Jan Beulich, Jiri Slaby
From: Roger Pau Monné <roger.pau@citrix.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit 1f13d75ccb806260079e0679d55d9253e370ec8a upstream.
A compiler may load a switch statement value multiple times, which could
be bad when the value is in memory shared with the frontend.
When converting a non-native request to a native one, ensure that
src->operation is only loaded once by using READ_ONCE().
This is part of XSA155.
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: "Jan Beulich" <JBeulich@suse.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
drivers/block/xen-blkback/common.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
index 8d8807563d99..ab225ff1af8e 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -388,8 +388,8 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst,
struct blkif_x86_32_request *src)
{
int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
- dst->operation = src->operation;
- switch (src->operation) {
+ dst->operation = READ_ONCE(src->operation);
+ switch (dst->operation) {
case BLKIF_OP_READ:
case BLKIF_OP_WRITE:
case BLKIF_OP_WRITE_BARRIER:
@@ -436,8 +436,8 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst,
struct blkif_x86_64_request *src)
{
int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
- dst->operation = src->operation;
- switch (src->operation) {
+ dst->operation = READ_ONCE(src->operation);
+ switch (dst->operation) {
case BLKIF_OP_READ:
case BLKIF_OP_WRITE:
case BLKIF_OP_WRITE_BARRIER:
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] xen-blkback: read from indirect descriptors only once
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
` (7 preceding siblings ...)
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-blkback: only read request operation from shared ring once Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen/pciback: Save xen_pci_op commands before processing it Jiri Slaby
` (2 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable
Cc: Roger Pau Monné, David Vrabel, Konrad Rzeszutek Wilk,
Jan Beulich, Jiri Slaby
From: Roger Pau Monné <roger.pau@citrix.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit 18779149101c0dd43ded43669ae2a92d21b6f9cb upstream.
Since indirect descriptors are in memory shared with the frontend, the
frontend could alter the first_sect and last_sect values after they have
been validated but before they are recorded in the request. This may
result in I/O requests that overflow the foreign page, possibly
overwriting local pages when the I/O request is executed.
When parsing indirect descriptors, only read first_sect and last_sect
once.
This is part of XSA155.
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Jan Beulich <JBeulich@suse.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
drivers/block/xen-blkback/blkback.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index 6beaaf83680e..77128dea547f 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -853,6 +853,8 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
goto unmap;
for (n = 0, i = 0; n < nseg; n++) {
+ uint8_t first_sect, last_sect;
+
if ((n % SEGS_PER_INDIRECT_FRAME) == 0) {
/* Map indirect segments */
if (segments)
@@ -860,15 +862,18 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
segments = kmap_atomic(pages[n/SEGS_PER_INDIRECT_FRAME]->page);
}
i = n % SEGS_PER_INDIRECT_FRAME;
+
pending_req->segments[n]->gref = segments[i].gref;
- seg[n].nsec = segments[i].last_sect -
- segments[i].first_sect + 1;
- seg[n].offset = (segments[i].first_sect << 9);
- if ((segments[i].last_sect >= (PAGE_SIZE >> 9)) ||
- (segments[i].last_sect < segments[i].first_sect)) {
+
+ first_sect = READ_ONCE(segments[i].first_sect);
+ last_sect = READ_ONCE(segments[i].last_sect);
+ if (last_sect >= (PAGE_SIZE >> 9) || last_sect < first_sect) {
rc = -EINVAL;
goto unmap;
}
+
+ seg[n].nsec = last_sect - first_sect + 1;
+ seg[n].offset = first_sect << 9;
preq->nr_sects += seg[n].nsec;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] xen/pciback: Save xen_pci_op commands before processing it
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
` (8 preceding siblings ...)
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-blkback: read from indirect descriptors only once Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen/pciback: Save the number of MSI-X entries to be copied later Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xfs: allow inode allocations in post-growfs disk space Jiri Slaby
11 siblings, 0 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable; +Cc: Konrad Rzeszutek Wilk, Jan Beulich, David Vrabel, Jiri Slaby
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit 8135cf8b092723dbfcc611fe6fdcb3a36c9951c5 upstream.
Double fetch vulnerabilities that happen when a variable is
fetched twice from shared memory but a security check is only
performed the first time.
The xen_pcibk_do_op function performs a switch statements on the op->cmd
value which is stored in shared memory. Interestingly this can result
in a double fetch vulnerability depending on the performed compiler
optimization.
This patch fixes it by saving the xen_pci_op command before
processing it. We also use 'barrier' to make sure that the
compiler does not perform any optimization.
This is part of XSA155.
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Jan Beulich <JBeulich@suse.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: "Jan Beulich" <JBeulich@suse.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
drivers/xen/xen-pciback/pciback.h | 1 +
drivers/xen/xen-pciback/pciback_ops.c | 15 ++++++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h
index f72af87640e0..560b3ecbcba8 100644
--- a/drivers/xen/xen-pciback/pciback.h
+++ b/drivers/xen/xen-pciback/pciback.h
@@ -37,6 +37,7 @@ struct xen_pcibk_device {
struct xen_pci_sharedinfo *sh_info;
unsigned long flags;
struct work_struct op_work;
+ struct xen_pci_op op;
};
struct xen_pcibk_dev_data {
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index 1199d147dcde..a2da466d2333 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -331,9 +331,11 @@ void xen_pcibk_do_op(struct work_struct *data)
container_of(data, struct xen_pcibk_device, op_work);
struct pci_dev *dev;
struct xen_pcibk_dev_data *dev_data = NULL;
- struct xen_pci_op *op = &pdev->sh_info->op;
+ struct xen_pci_op *op = &pdev->op;
int test_intx = 0;
+ *op = pdev->sh_info->op;
+ barrier();
dev = xen_pcibk_get_pci_dev(pdev, op->domain, op->bus, op->devfn);
if (dev == NULL)
@@ -375,6 +377,17 @@ void xen_pcibk_do_op(struct work_struct *data)
if ((dev_data->enable_intx != test_intx))
xen_pcibk_control_isr(dev, 0 /* no reset */);
}
+ pdev->sh_info->op.err = op->err;
+ pdev->sh_info->op.value = op->value;
+#ifdef CONFIG_PCI_MSI
+ if (op->cmd == XEN_PCI_OP_enable_msix && op->err == 0) {
+ unsigned int i;
+
+ for (i = 0; i < op->value; i++)
+ pdev->sh_info->op.msix_entries[i].vector =
+ op->msix_entries[i].vector;
+ }
+#endif
/* Tell the driver domain that we're done. */
wmb();
clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] xen/pciback: Save the number of MSI-X entries to be copied later.
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
` (9 preceding siblings ...)
2016-03-30 14:25 ` [patch added to 3.12-stable] xen/pciback: Save xen_pci_op commands before processing it Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xfs: allow inode allocations in post-growfs disk space Jiri Slaby
11 siblings, 0 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable; +Cc: Konrad Rzeszutek Wilk, David Vrabel, Jan Beulich, Jiri Slaby
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit d159457b84395927b5a52adb72f748dd089ad5e5 upstream.
Commit 8135cf8b092723dbfcc611fe6fdcb3a36c9951c5 (xen/pciback: Save
xen_pci_op commands before processing it) broke enabling MSI-X because
it would never copy the resulting vectors into the response. The
number of vectors requested was being overwritten by the return value
(typically zero for success).
Save the number of vectors before processing the op, so the correct
number of vectors are copied afterwards.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Cc: "Jan Beulich" <JBeulich@suse.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
drivers/xen/xen-pciback/pciback_ops.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index a2da466d2333..69f0d4d1d8b7 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -333,6 +333,9 @@ void xen_pcibk_do_op(struct work_struct *data)
struct xen_pcibk_dev_data *dev_data = NULL;
struct xen_pci_op *op = &pdev->op;
int test_intx = 0;
+#ifdef CONFIG_PCI_MSI
+ unsigned int nr = 0;
+#endif
*op = pdev->sh_info->op;
barrier();
@@ -361,6 +364,7 @@ void xen_pcibk_do_op(struct work_struct *data)
op->err = xen_pcibk_disable_msi(pdev, dev, op);
break;
case XEN_PCI_OP_enable_msix:
+ nr = op->value;
op->err = xen_pcibk_enable_msix(pdev, dev, op);
break;
case XEN_PCI_OP_disable_msix:
@@ -383,7 +387,7 @@ void xen_pcibk_do_op(struct work_struct *data)
if (op->cmd == XEN_PCI_OP_enable_msix && op->err == 0) {
unsigned int i;
- for (i = 0; i < op->value; i++)
+ for (i = 0; i < nr; i++)
pdev->sh_info->op.msix_entries[i].vector =
op->msix_entries[i].vector;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch added to 3.12-stable] xfs: allow inode allocations in post-growfs disk space
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
` (10 preceding siblings ...)
2016-03-30 14:25 ` [patch added to 3.12-stable] xen/pciback: Save the number of MSI-X entries to be copied later Jiri Slaby
@ 2016-03-30 14:25 ` Jiri Slaby
11 siblings, 0 replies; 14+ messages in thread
From: Jiri Slaby @ 2016-03-30 14:25 UTC (permalink / raw)
To: stable; +Cc: Eric Sandeen, Dave Chinner, Jiri Slaby
From: Eric Sandeen <sandeen@redhat.com>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit 9de67c3ba9ea961ba420573d56479d09d33a7587 upstream.
Today, if we perform an xfs_growfs which adds allocation groups,
mp->m_maxagi is not properly updated when the growfs is complete.
Therefore inodes will continue to be allocated only in the
AGs which existed prior to the growfs, and the new space
won't be utilized.
This is because of this path in xfs_growfs_data_private():
xfs_growfs_data_private
xfs_initialize_perag(mp, nagcount, &nagimax);
if (mp->m_flags & XFS_MOUNT_32BITINODES)
index = xfs_set_inode32(mp);
else
index = xfs_set_inode64(mp);
if (maxagi)
*maxagi = index;
where xfs_set_inode* iterates over the (old) agcount in
mp->m_sb.sb_agblocks, which has not yet been updated
in the growfs path. So "index" will be returned based on
the old agcount, not the new one, and new AGs are not available
for inode allocation.
Fix this by explicitly passing the proper AG count (which
xfs_initialize_perag() already has) down another level,
so that xfs_set_inode* can make the proper decision about
acceptable AGs for inode allocation in the potentially
newly-added AGs.
This has been broken since 3.7, when these two
xfs_set_inode* functions were added in commit 2d2194f.
Prior to that, we looped over "agcount" not sb_agblocks
in these calculations.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
fs/xfs/xfs_mount.c | 4 ++--
fs/xfs/xfs_super.c | 20 +++++++++++++-------
fs/xfs/xfs_super.h | 4 ++--
3 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index dc602b564255..6df2d305d4b3 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -254,9 +254,9 @@ xfs_initialize_perag(
mp->m_flags &= ~XFS_MOUNT_32BITINODES;
if (mp->m_flags & XFS_MOUNT_32BITINODES)
- index = xfs_set_inode32(mp);
+ index = xfs_set_inode32(mp, agcount);
else
- index = xfs_set_inode64(mp);
+ index = xfs_set_inode64(mp, agcount);
if (maxagi)
*maxagi = index;
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 15188cc99449..c85735880301 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -602,8 +602,13 @@ xfs_max_file_offset(
return (((__uint64_t)pagefactor) << bitshift) - 1;
}
+/*
+ * xfs_set_inode32() and xfs_set_inode64() are passed an agcount
+ * because in the growfs case, mp->m_sb.sb_agcount is not updated
+ * yet to the potentially higher ag count.
+ */
xfs_agnumber_t
-xfs_set_inode32(struct xfs_mount *mp)
+xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount)
{
xfs_agnumber_t index = 0;
xfs_agnumber_t maxagi = 0;
@@ -625,10 +630,10 @@ xfs_set_inode32(struct xfs_mount *mp)
do_div(icount, sbp->sb_agblocks);
max_metadata = icount;
} else {
- max_metadata = sbp->sb_agcount;
+ max_metadata = agcount;
}
- for (index = 0; index < sbp->sb_agcount; index++) {
+ for (index = 0; index < agcount; index++) {
ino = XFS_AGINO_TO_INO(mp, index, agino);
if (ino > XFS_MAXINUMBER_32) {
@@ -653,11 +658,11 @@ xfs_set_inode32(struct xfs_mount *mp)
}
xfs_agnumber_t
-xfs_set_inode64(struct xfs_mount *mp)
+xfs_set_inode64(struct xfs_mount *mp, xfs_agnumber_t agcount)
{
xfs_agnumber_t index = 0;
- for (index = 0; index < mp->m_sb.sb_agcount; index++) {
+ for (index = 0; index < agcount; index++) {
struct xfs_perag *pag;
pag = xfs_perag_get(mp, index);
@@ -1203,6 +1208,7 @@ xfs_fs_remount(
char *options)
{
struct xfs_mount *mp = XFS_M(sb);
+ xfs_sb_t *sbp = &mp->m_sb;
substring_t args[MAX_OPT_ARGS];
char *p;
int error;
@@ -1222,10 +1228,10 @@ xfs_fs_remount(
mp->m_flags &= ~XFS_MOUNT_BARRIER;
break;
case Opt_inode64:
- mp->m_maxagi = xfs_set_inode64(mp);
+ mp->m_maxagi = xfs_set_inode64(mp, sbp->sb_agcount);
break;
case Opt_inode32:
- mp->m_maxagi = xfs_set_inode32(mp);
+ mp->m_maxagi = xfs_set_inode32(mp, sbp->sb_agcount);
break;
default:
/*
diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h
index bbe3d15a7904..b4cfe21d8fb0 100644
--- a/fs/xfs/xfs_super.h
+++ b/fs/xfs/xfs_super.h
@@ -76,8 +76,8 @@ extern __uint64_t xfs_max_file_offset(unsigned int);
extern void xfs_flush_inodes(struct xfs_mount *mp);
extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
-extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *);
-extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *);
+extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *, xfs_agnumber_t agcount);
+extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *, xfs_agnumber_t agcount);
extern const struct export_operations xfs_export_operations;
extern const struct xattr_handler *xfs_xattr_handlers[];
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [patch added to 3.12-stable] kernel: Provide READ_ONCE and ASSIGN_ONCE
2016-03-30 14:25 ` [patch added to 3.12-stable] kernel: Provide READ_ONCE and ASSIGN_ONCE Jiri Slaby
@ 2016-03-30 16:33 ` Christian Borntraeger
0 siblings, 0 replies; 14+ messages in thread
From: Christian Borntraeger @ 2016-03-30 16:33 UTC (permalink / raw)
To: Jiri Slaby, stable
On 03/30/2016 04:25 PM, Jiri Slaby wrote:
> From: Christian Borntraeger <borntraeger@de.ibm.com>
>
> This patch has been added to the 3.12 stable tree. If you have any
> objections, please let us know.
>
> ===============
>
> commit 230fa253df6352af12ad0a16128760b5cb3f92df upstream.
>
> ACCESS_ONCE does not work reliably on non-scalar types. For
> example gcc 4.6 and 4.7 might remove the volatile tag for such
> accesses during the SRA (scalar replacement of aggregates) step
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145)
>
> Let's provide READ_ONCE/ASSIGN_ONCE that will do all accesses via
> scalar types as suggested by Linus Torvalds. Accesses larger than
> the machines word size cannot be guaranteed to be atomic. These
> macros will use memcpy and emit a build warning.
>
> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
There have been several followup patches (e.g.
43239cbe79fc ("kernel: Change ASSIGN_ONCE(val, x) to WRITE_ONCE(x, val)")
7bd3e239d6c6d ("locking: Remove atomicy checks from {READ,WRITE}_ONCE")
and others.
I think this patch should not go alone.
> ---
> include/linux/compiler.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 74 insertions(+)
>
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index 19a199414bd0..237063adbe1b 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -179,6 +179,80 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
> # define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
> #endif
>
> +#include <uapi/linux/types.h>
> +
> +static __always_inline void data_access_exceeds_word_size(void)
> +#ifdef __compiletime_warning
> +__compiletime_warning("data access exceeds word size and won't be atomic")
> +#endif
> +;
> +
> +static __always_inline void data_access_exceeds_word_size(void)
> +{
> +}
> +
> +static __always_inline void __read_once_size(volatile void *p, void *res, int size)
> +{
> + switch (size) {
> + case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
> + case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
> + case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
> +#ifdef CONFIG_64BIT
> + case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
> +#endif
> + default:
> + barrier();
> + __builtin_memcpy((void *)res, (const void *)p, size);
> + data_access_exceeds_word_size();
> + barrier();
> + }
> +}
> +
> +static __always_inline void __assign_once_size(volatile void *p, void *res, int size)
> +{
> + switch (size) {
> + case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
> + case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
> + case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
> +#ifdef CONFIG_64BIT
> + case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
> +#endif
> + default:
> + barrier();
> + __builtin_memcpy((void *)p, (const void *)res, size);
> + data_access_exceeds_word_size();
> + barrier();
> + }
> +}
> +
> +/*
> + * Prevent the compiler from merging or refetching reads or writes. The
> + * compiler is also forbidden from reordering successive instances of
> + * READ_ONCE, ASSIGN_ONCE and ACCESS_ONCE (see below), but only when the
> + * compiler is aware of some particular ordering. One way to make the
> + * compiler aware of ordering is to put the two invocations of READ_ONCE,
> + * ASSIGN_ONCE or ACCESS_ONCE() in different C statements.
> + *
> + * In contrast to ACCESS_ONCE these two macros will also work on aggregate
> + * data types like structs or unions. If the size of the accessed data
> + * type exceeds the word size of the machine (e.g., 32 bits or 64 bits)
> + * READ_ONCE() and ASSIGN_ONCE() will fall back to memcpy and print a
> + * compile-time warning.
> + *
> + * Their two major use cases are: (1) Mediating communication between
> + * process-level code and irq/NMI handlers, all running on the same CPU,
> + * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
> + * mutilate accesses that either do not require ordering or that interact
> + * with an explicit memory barrier or atomic instruction that provides the
> + * required ordering.
> + */
> +
> +#define READ_ONCE(x) \
> + ({ typeof(x) __val; __read_once_size(&x, &__val, sizeof(__val)); __val; })
> +
> +#define ASSIGN_ONCE(val, x) \
> + ({ typeof(x) __val; __val = val; __assign_once_size(&x, &__val, sizeof(__val)); __val; })
> +
> #endif /* __KERNEL__ */
>
> #endif /* __ASSEMBLY__ */
>
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2016-03-30 16:34 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] ipr: Fix regression when loading firmware Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] ipv4: Don't do expensive useless work during inetdev destroy Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] umount: Do not allow unmounting rootfs Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] kernel: Provide READ_ONCE and ASSIGN_ONCE Jiri Slaby
2016-03-30 16:33 ` Christian Borntraeger
2016-03-30 14:25 ` [patch added to 3.12-stable] xen: Add RING_COPY_REQUEST() Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-netback: don't use last request to determine minimum Tx credit Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-netback: use RING_COPY_REQUEST() throughout Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-blkback: only read request operation from shared ring once Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-blkback: read from indirect descriptors only once Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen/pciback: Save xen_pci_op commands before processing it Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen/pciback: Save the number of MSI-X entries to be copied later Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xfs: allow inode allocations in post-growfs disk space Jiri Slaby
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.