* Re: [PATCH] misc/vmw_vmci: bail out earlier on too big queue allocation
[not found] <trinity-96cb58f7-02ae-4ae2-b05d-169e1aa82c64-1606066857501@3c-app-gmx-bs01>
@ 2020-12-09 18:40 ` Greg KH
2020-12-09 18:41 ` Greg KH
0 siblings, 1 reply; 3+ messages in thread
From: Greg KH @ 2020-12-09 18:40 UTC (permalink / raw)
To: nslusarek; +Cc: jhansen, arnd, linux-kernel
On Sun, Nov 22, 2020 at 06:40:57PM +0100, nslusarek@gmx.net wrote:
> From: Norbert Slusarek <nslusarek@gmx.net>
> Date: Sun, 22 Nov 2020 19:16:41 +0100
> Subject: [PATCH] misc/vmw_vmci: bail out earlier on too big queue allocation
>
> For the allocation of a queue pair in qp_host_alloc_queue() an arbitrary value can be
> passed for produce_size, which can lead to miscalculation of memory we'd like to allocate
> in one take. A warning is triggered at __alloc_pages_nodemask() in mm/page_alloc.c:4737
> which aborts the false allocation, but it results in a VMware machine freezing
> for an infinite time.
>
> Signed-off-by: Norbert Slusarek <nslusarek@gmx.net>
>
<snip>
Can you resend this in a non-html format, so that we can apply it, and
so it will show up on the public mailing lists?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] misc/vmw_vmci: bail out earlier on too big queue allocation
2020-12-09 18:40 ` [PATCH] misc/vmw_vmci: bail out earlier on too big queue allocation Greg KH
@ 2020-12-09 18:41 ` Greg KH
0 siblings, 0 replies; 3+ messages in thread
From: Greg KH @ 2020-12-09 18:41 UTC (permalink / raw)
To: nslusarek; +Cc: jhansen, arnd, linux-kernel
On Wed, Dec 09, 2020 at 07:40:33PM +0100, Greg KH wrote:
> On Sun, Nov 22, 2020 at 06:40:57PM +0100, nslusarek@gmx.net wrote:
> > From: Norbert Slusarek <nslusarek@gmx.net>
> > Date: Sun, 22 Nov 2020 19:16:41 +0100
> > Subject: [PATCH] misc/vmw_vmci: bail out earlier on too big queue allocation
> >
> > For the allocation of a queue pair in qp_host_alloc_queue() an arbitrary value can be
> > passed for produce_size, which can lead to miscalculation of memory we'd like to allocate
> > in one take. A warning is triggered at __alloc_pages_nodemask() in mm/page_alloc.c:4737
> > which aborts the false allocation, but it results in a VMware machine freezing
> > for an infinite time.
> >
> > Signed-off-by: Norbert Slusarek <nslusarek@gmx.net>
> >
>
> <snip>
>
> Can you resend this in a non-html format, so that we can apply it, and
> so it will show up on the public mailing lists?
Oh nevermind, you already did, sorry about that...
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] misc/vmw_vmci: bail out earlier on too big queue allocation
@ 2020-11-22 17:44 nslusarek
0 siblings, 0 replies; 3+ messages in thread
From: nslusarek @ 2020-11-22 17:44 UTC (permalink / raw)
Cc: linux-kernel
From: Norbert Slusarek <nslusarek@gmx.net>
Date: Sun, 22 Nov 2020 19:16:41 +0100
Subject: [PATCH] misc/vmw_vmci: bail out earlier on too big queue allocation
For the allocation of a queue pair in qp_host_alloc_queue() an arbitrary value can be
passed for produce_size, which can lead to miscalculation of memory we'd like to allocate
in one take. A warning is triggered at __alloc_pages_nodemask() in mm/page_alloc.c:4737
which aborts the false allocation, but it results in a VMware machine freezing
for an infinite time.
Signed-off-by: Norbert Slusarek <nslusarek@gmx.net>
---
To provide an accurate explanation of the problem, I'll describe my observations and
include a PoC you can run yourself.
The value for produce_size (0x7ffe7001) wasn't chosen randomly, it's the least value
which can trigger the warning. With this value involved, calculations are made in
qp_host_alloc_queue() before calling kzalloc() with queue_size + queue_page_size.
The calculation of queue_size involves taking the size of *queue->kernel_if, which on 5.10-rc4 has the size of 72 bytes and on 5.4.79 it's 168 bytes.
While on 5.10-rc4 the size argument for kzalloc() won't surpass
the maximum value of 4096*1024 for an individual allocation
(for produce_size = 0x7ffe7001 -> kzalloc(4194216)), it will be greater on the stable 5.4.79 kernel
(for produce_size = 0x7ffe7001 -> kzalloc(4194312)).
This will ultimately lead to a warning on the stable 5.4 kernel, but not on the upstream kernel,
so ideally my patch would be backported to stable kernels.
Eventhough the warning in __alloc_pages_nodemask() already aborts the oversized allocation of memory, VMware will hang for an infinite time, hence I wanted to provide this simple patch. We shouldn't rely on the page allocator to abort it anyways, it's better to keep it clean and check for
a too large allocation before calling kzalloc().
When I ran the PoC in QEMU and on a host machine, I didn't experience any freezes at all, but
the warning gets triggered.
PoC (run on 5.4 stable kernel and VMCI driver loaded for /dev/vmci):
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <endian.h>
#include <stdint.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/types.h>
#define VMADDR_CID_LOCAL 1
#define IOCTL_VMCI_VERSION2 1959
#define IOCTL_VMCI_INIT_CONTEXT 1952
#define IOCTL_VMCI_QUEUEPAIR_ALLOC 1960
#define VMCI_VERSION_PREHOSTQP 0x80000
#define VMCI_NO_PRIVILEGE_FLAGS 0
struct vmci_handle {
unsigned int context;
unsigned int resource;
};
struct vmci_qp_alloc_info {
struct vmci_handle handle;
unsigned int peer;
unsigned int flags;
unsigned long produce_size;
unsigned long consume_size;
unsigned long ppn_va;
unsigned long num_ppns;
int result;
unsigned int version;
};
struct vmci_init_blk {
int cid;
int flags;
};
int main(void)
{
int fd, flag;
fd = syscall(__NR_openat, -100, "/dev/vmci", O_RDWR, 0);
flag = VMCI_VERSION_PREHOSTQP;
syscall(__NR_ioctl, fd, IOCTL_VMCI_VERSION2, &flag);
struct vmci_init_blk cxt = {
.cid = VMADDR_CID_LOCAL,
.flags = VMCI_NO_PRIVILEGE_FLAGS
};
syscall(__NR_ioctl, fd, IOCTL_VMCI_INIT_CONTEXT, &cxt);
struct vmci_qp_alloc_info qp = {
.handle.context = VMADDR_CID_LOCAL,
.handle.resource = 0,
.peer = 0,
.flags = 0,
.produce_size = 0x7ffe7001,
.consume_size = 0,
.ppn_va = 0,
.num_ppns = 0,
.result = -1,
.version = 0
};
syscall(__NR_ioctl, fd, IOCTL_VMCI_QUEUEPAIR_ALLOC, &qp);
return 0;
}
---
drivers/misc/vmw_vmci/vmci_queue_pair.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c
index c49065887e8f..997ff32475b2 100644
--- a/drivers/misc/vmw_vmci/vmci_queue_pair.c
+++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c
@@ -526,6 +526,7 @@ static struct vmci_queue *qp_host_alloc_queue(u64 size)
struct vmci_queue *queue;
size_t queue_page_size;
u64 num_pages;
+ unsigned int order;
const size_t queue_size = sizeof(*queue) + sizeof(*(queue->kernel_if));
if (size > SIZE_MAX - PAGE_SIZE)
@@ -537,6 +538,10 @@ static struct vmci_queue *qp_host_alloc_queue(u64 size)
queue_page_size = num_pages * sizeof(*queue->kernel_if->u.h.page);
+ order = get_order(queue_size + queue_page_size);
+ if (order >= MAX_ORDER)
+ return NULL;
+
queue = kzalloc(queue_size + queue_page_size, GFP_KERNEL);
if (queue) {
queue->q_header = NULL;
--
2.29.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-12-09 18:41 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <trinity-96cb58f7-02ae-4ae2-b05d-169e1aa82c64-1606066857501@3c-app-gmx-bs01>
2020-12-09 18:40 ` [PATCH] misc/vmw_vmci: bail out earlier on too big queue allocation Greg KH
2020-12-09 18:41 ` Greg KH
2020-11-22 17:44 nslusarek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).