From: Andi Kleen <andi@firstfloor.org>
To: nhorman@tuxdriver.com, ak@linux.intel.com,
Trond.Myklebust@netapp.com, security@kernel.org,
jlayton@redhat.com, torvalds@linux-foundation.org,
gregkh@suse.de, linux-kernel@vger.kernel.org, stable@kernel.org,
tim.bird@am.sony.com, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: [PATCH] [36/98] nfs4: Ensure that ACL pages sent over NFS were not allocated from the slab (v3)
Date: Tue, 26 Jul 2011 17:35:28 -0700 (PDT) [thread overview]
Message-ID: <20110727003528.982492403FF@tassilo.jf.intel.com> (raw)
In-Reply-To: <20110726534.972201586@firstfloor.org>
2.6.35-longterm review patch. If anyone has any objections, please let me know.
------------------
From: Neil Horman <nhorman@tuxdriver.com>
commit e9e3d724e2145f5039b423c290ce2b2c3d8f94bc upstream.
The "bad_page()" page allocator sanity check was reported recently (call
chain as follows):
bad_page+0x69/0x91
free_hot_cold_page+0x81/0x144
skb_release_data+0x5f/0x98
__kfree_skb+0x11/0x1a
tcp_ack+0x6a3/0x1868
tcp_rcv_established+0x7a6/0x8b9
tcp_v4_do_rcv+0x2a/0x2fa
tcp_v4_rcv+0x9a2/0x9f6
do_timer+0x2df/0x52c
ip_local_deliver+0x19d/0x263
ip_rcv+0x539/0x57c
netif_receive_skb+0x470/0x49f
:virtio_net:virtnet_poll+0x46b/0x5c5
net_rx_action+0xac/0x1b3
__do_softirq+0x89/0x133
call_softirq+0x1c/0x28
do_softirq+0x2c/0x7d
do_IRQ+0xec/0xf5
default_idle+0x0/0x50
ret_from_intr+0x0/0xa
default_idle+0x29/0x50
cpu_idle+0x95/0xb8
start_kernel+0x220/0x225
_sinittext+0x22f/0x236
It occurs because an skb with a fraglist was freed from the tcp
retransmit queue when it was acked, but a page on that fraglist had
PG_Slab set (indicating it was allocated from the Slab allocator (which
means the free path above can't safely free it via put_page.
We tracked this back to an nfsv4 setacl operation, in which the nfs code
attempted to fill convert the passed in buffer to an array of pages in
__nfs4_proc_set_acl, which gets used by the skb->frags list in
xs_sendpages. __nfs4_proc_set_acl just converts each page in the buffer
to a page struct via virt_to_page, but the vfs allocates the buffer via
kmalloc, meaning the PG_slab bit is set. We can't create a buffer with
kmalloc and free it later in the tcp ack path with put_page, so we need
to either:
1) ensure that when we create the list of pages, no page struct has
PG_Slab set
or
2) not use a page list to send this data
Given that these buffers can be multiple pages and arbitrarily sized, I
think (1) is the right way to go. I've written the below patch to
allocate a page from the buddy allocator directly and copy the data over
to it. This ensures that we have a put_page free-able page for every
entry that winds up on an skb frag list, so it can be safely freed when
the frame is acked. We do a put page on each entry after the
rpc_call_sync call so as to drop our own reference count to the page,
leaving only the ref count taken by tcp_sendpages. This way the data
will be properly freed when the ack comes in
Successfully tested by myself to solve the above oops.
Note, as this is the result of a setacl operation that exceeded a page
of data, I think this amounts to a local DOS triggerable by an
uprivlidged user, so I'm CCing security on this as well.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
CC: Trond Myklebust <Trond.Myklebust@netapp.com>
CC: security@kernel.org
CC: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
fs/nfs/nfs4proc.c | 43 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 41 insertions(+), 2 deletions(-)
Index: linux-2.6.35.y/fs/nfs/nfs4proc.c
===================================================================
--- linux-2.6.35.y.orig/fs/nfs/nfs4proc.c
+++ linux-2.6.35.y/fs/nfs/nfs4proc.c
@@ -3275,6 +3275,35 @@ static void buf_to_pages(const void *buf
}
}
+static int buf_to_pages_noslab(const void *buf, size_t buflen,
+ struct page **pages, unsigned int *pgbase)
+{
+ struct page *newpage, **spages;
+ int rc = 0;
+ size_t len;
+ spages = pages;
+
+ do {
+ len = min(PAGE_CACHE_SIZE, buflen);
+ newpage = alloc_page(GFP_KERNEL);
+
+ if (newpage == NULL)
+ goto unwind;
+ memcpy(page_address(newpage), buf, len);
+ buf += len;
+ buflen -= len;
+ *pages++ = newpage;
+ rc++;
+ } while (buflen != 0);
+
+ return rc;
+
+unwind:
+ for(; rc > 0; rc--)
+ __free_page(spages[rc-1]);
+ return -ENOMEM;
+}
+
struct nfs4_cached_acl {
int cached;
size_t len;
@@ -3441,13 +3470,23 @@ static int __nfs4_proc_set_acl(struct in
.rpc_argp = &arg,
.rpc_resp = &res,
};
- int ret;
+ int ret, i;
if (!nfs4_server_supports_acls(server))
return -EOPNOTSUPP;
+ i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
+ if (i < 0)
+ return i;
nfs_inode_return_delegation(inode);
- buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
ret = nfs4_call_sync(server, &msg, &arg, &res, 1);
+
+ /*
+ * Free each page after tx, so the only ref left is
+ * held by the network stack
+ */
+ for (; i > 0; i--)
+ put_page(pages[i-1]);
+
nfs_access_zap_cache(inode);
nfs_zap_acl_cache(inode);
return ret;
next prev parent reply other threads:[~2011-07-27 0:36 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-27 0:34 [PATCH] [0/98] 2.6.35.14 longterm review Andi Kleen
2011-07-27 0:34 ` [PATCH] [1/98] kbuild: Disable -Wunused-but-set-variable for gcc 4.6.0 Andi Kleen
2011-07-27 0:34 ` [PATCH] [2/98] kbuild: Fix passing -Wno-* options to gcc 4.4+ Andi Kleen
2011-07-27 0:34 ` [PATCH] [3/98] Add Andi Kleen as 2.6.35 longterm maintainer Andi Kleen
2011-07-27 0:34 ` [PATCH] [4/98] Remove the old V4L1 v4lgrab.c file Andi Kleen
2011-07-27 0:34 ` [PATCH] [5/98] agp: fix arbitrary kernel memory writes Andi Kleen
2011-07-27 0:34 ` [PATCH] [6/98] agp: fix OOM and buffer overflow Andi Kleen
2011-07-27 0:34 ` [PATCH] [7/98] i8k: Tell gcc that *regs gets clobbered Andi Kleen
2011-07-27 0:35 ` [PATCH] [8/98] Fix gcc 4.5.1 miscompiling drivers/char/i8k.c (again) Andi Kleen
2011-07-27 0:35 ` [PATCH] [9/98] USB: serial/usb_wwan, fix tty NULL dereference Andi Kleen
2011-07-27 0:35 ` [PATCH] [10/98] ipv6: add special mode accept_ra=2 to accept RA while configured as router Andi Kleen
2011-07-27 17:41 ` Stephen Clark
2011-07-27 20:11 ` Andi Kleen
2011-07-27 0:35 ` [PATCH] [11/98] mpt2sas: prevent heap overflows and unchecked reads Andi Kleen
2011-07-27 0:35 ` [PATCH] [12/98] slub: fix panic with DISCONTIGMEM Andi Kleen
2011-07-27 21:47 ` David Rientjes
2011-07-27 21:55 ` Andi Kleen
2011-07-27 0:35 ` [PATCH] [13/98] set memory ranges in N_NORMAL_MEMORY when onlined Andi Kleen
2011-07-27 0:35 ` [PATCH] [14/98] FLEXCOP-PCI: fix __xlate_proc_name-warning for flexcop-pci Andi Kleen
2011-07-27 0:35 ` [PATCH] [15/98] m68k/mm: Set all online nodes in N_NORMAL_MEMORY Andi Kleen
2011-07-27 0:35 ` [PATCH] [16/98] nfs: don't lose MS_SYNCHRONOUS on remount of noac mount Andi Kleen
2011-07-27 0:35 ` [PATCH] [17/98] NFSv4.1: Ensure state manager thread dies on last umount Andi Kleen
2011-07-27 0:35 ` [PATCH] [18/98] Input: xen-kbdfront - fix mouse getting stuck after save/restore Andi Kleen
2011-07-27 0:35 ` [PATCH] [19/98] pmcraid: reject negative request size Andi Kleen
2011-07-27 0:35 ` [PATCH] [20/98] put stricter guards on queue dead checks Andi Kleen
2011-07-27 0:35 ` [PATCH] [21/98] mmc: sdhci-pci: Fix error case in sdhci_pci_probe_slot() Andi Kleen
2011-07-27 0:35 ` [PATCH] [22/98] mmc: sdhci: Check mrq->cmd in sdhci_tasklet_finish Andi Kleen
2011-07-27 0:35 ` [PATCH] [23/98] mmc: sdhci: Check mrq != NULL " Andi Kleen
2011-07-27 0:35 ` [PATCH] [24/98] USB: fix regression in usbip by setting has_tt flag Andi Kleen
2011-07-27 0:35 ` [PATCH] [25/98] x86, AMD: Fix APIC timer erratum 400 affecting K8 Rev.A-E processors Andi Kleen
2011-07-27 12:38 ` Boris Ostrovsky
2011-07-27 15:42 ` Andi Kleen
2011-07-27 16:06 ` Boris Ostrovsky
2011-07-27 20:13 ` Andi Kleen
2011-07-27 0:35 ` [PATCH] [26/98] af_unix: Only allow recv on connected seqpacket sockets Andi Kleen
2011-07-27 15:58 ` [stable] " Tim Gardner
2011-07-27 16:02 ` Andi Kleen
2011-07-27 19:23 ` Eric W. Biederman
2011-08-01 20:08 ` Andi Kleen
2011-08-01 20:43 ` Tim Gardner
2011-07-27 0:35 ` [PATCH] [27/98] ARM: 6891/1: prevent heap corruption in OABI semtimedop Andi Kleen
2011-07-27 0:35 ` [PATCH] [28/98] Open with O_CREAT flag set fails to open existing files on non writable directories Andi Kleen
2011-07-27 0:35 ` [PATCH] [29/98] can: Add missing socket check in can/bcm release Andi Kleen
2011-07-27 0:35 ` [PATCH] [30/98] fs/partitions/ldm.c: fix oops caused by corrupted partition table Andi Kleen
2011-07-27 0:35 ` [PATCH] [31/98] Input: elantech - discard the first 2 positions on some firmwares Andi Kleen
2011-07-27 0:35 ` [PATCH] [32/98] Staging: rtl8192su: Clean up in case of an error in module initialisation Andi Kleen
2011-07-27 0:35 ` [PATCH] [33/98] Staging: rtl8192su: Fix procfs code for interfaces not named wlan0 Andi Kleen
2011-07-27 0:35 ` [PATCH] [34/98] USB: teach "devices" file about Wireless and SuperSpeed USB Andi Kleen
2011-07-27 0:35 ` [PATCH] [35/98] SUNRPC: fix NFS client over TCP hangs due to packet loss (Bug 16494) Andi Kleen
2011-07-27 0:35 ` Andi Kleen [this message]
2011-07-27 0:35 ` [PATCH] [37/98] nfs: fix compilation warning Andi Kleen
2011-07-27 0:35 ` [PATCH] [38/98] Fix corrupted OSF partition table parsing Andi Kleen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110727003528.982492403FF@tassilo.jf.intel.com \
--to=andi@firstfloor.org \
--cc=Trond.Myklebust@netapp.com \
--cc=ak@linux.intel.com \
--cc=gregkh@suse.de \
--cc=jlayton@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=nhorman@tuxdriver.com \
--cc=security@kernel.org \
--cc=stable@kernel.org \
--cc=stable@vger.kernel.org \
--cc=tim.bird@am.sony.com \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).