[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <53470E26.2030306@cybernetics.com>
Date: Thu, 10 Apr 2014 17:33:26 -0400
From: Tony Battersby <tonyb@...ernetics.com>
To: David Herrmann <dh.herrmann@...il.com>
CC: linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org,
linux-mm@...ck.org, dri-devel@...ts.freedesktop.org
Subject: Re: [PATCH 2/6] shm: add sealing API
(reposted from my comments at http://lwn.net/Articles/593918/)
I may have thought of a way to subvert SEAL_WRITE using O_DIRECT and
asynchronous I/O. I am not sure if this is a real problem or not, but
better to ask, right?
The exploit would go like this:
1) mmap() the shared memory
2) open some *other* file with O_DIRECT
3) prepare a read-type iocb for the *other* file pointing to the
mmap()ed memory
4) io_submit(), but don't wait for it to complete
5) munmap() the shared memory
6) SEAL_WRITE the shared memory
7) the "sealed" memory is overwritten by DMA from the disk drive at some
point in the future when the I/O completes
So this exploit effectively changes the contents of the supposedly
write-protected memory after SEAL_WRITE is granted.
For O_DIRECT the kernel pins the submitted pages in memory for DMA by
incrementing the page reference counts when the I/O is submitted,
allowing the pages to be modified by DMA even if they are no longer
mapped in the address space of the process. This is different from a
regular read(), which uses the CPU to copy the data and will fail if the
pages are not mapped.
I am sure there are also other direct I/O mechanisms in the kernel that
can be used to setup a DMA transfer to change the contents of unmapped
memory; the SCSI generic driver comes to mind.
I suppose SEAL_WRITE could iterate over all the pages in the file and
check to make sure no page refcount is greater than the "expected"
value, and return an error instead of granting the seal if a page is
found with an unexpected extra reference that might have been added by
e.g. get_user_pages() for direct I/O. But looking over shmem_set_seals()
in patch 2/6, it doesn't seem to do that.
Tony Battersby
Cybernetics
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists