mirror of
https://git.openafs.org/openafs.git
synced 2025-01-31 05:27:44 +00:00
Mark Vitale
17ca935bbd
afs: pioctl kernel memory overrun
CVE-2015-8312: Any pioctl with an input buffer size (ViceIoctl->in_size) exactly equal to AFS_LRALLOCSIZE (4096 bytes) will cause a one-byte overwrite of its kernel memory working buffer. This may crash the operating system or cause other undefined behavior. The attacking pioctl must be a valid AFS pioctl code. However, it need not specify valid arguments (in the ViceIoctl), since only rudimentary checking is done in afs_HandlePioctl. Most argument validation occurs later in the individual pioctl handlers. Nor does the issuer need to be authenticated or authorized in any way, since authorization checks also occur much later, in the individual pioctl handlers. An unauthorized user may therefore trigger the overrun by either crafting his own malicious pioctl, or by issuing a privileged command, e.g. 'fs newalias', with appropriately sized but otherwise arbitrary arguments. In the latter case, the attacker will see the expected error message: "fs: You do not have the required rights to do this operation" but in either case the damage has been done. Pioctls are not logged or audited in any way (except those that cause loggable or auditable events as side effects). root cause: afs_HandlePioctli() calls afs_pd_alloc() to allocate two two afs_pdata structs, one for input and one for output. The memory for these buffers is based on the requested size, plus at least one extra byte for the null terminator to be set later: requested size allocated ================= ================================= > AFS_LRALLOCSIZ osi_Alloc(size+1) <= AFS_LRALLOCSIZ afs_AllocLargeSize(AFS_LRALLOCSIZ) afs_HandlePioctl then adds a null terminator to each buffer, one byte past the requested size. This is safe in all cases except one: if the requested in_size was _exactly_ AFS_LRALLOCSIZ (4096 bytes), this null is one byte beyond the allocated storage, zeroing a byte of kernel memory. Commit 6260cbecd0795c4795341bdcf98671de6b9a43fb introduced the null terminators and they were correct at that time. But the commit message warns: "note that this works because PIGGYSIZE is always less than AFS_LRALLOCSIZ" Commit f8ed1111d76bbf36a466036ff74b44e1425be8bd introduced the bug by increasing the maximum size of the buffers but failing to account correctly for the null terminator in the case of input buffer size == AFS_LRALLOCSIZ. Commit 592a99d6e693bc640e2bdfc2e7e5243fcedc8f93 (master version of one of the fixes in the recent 1.6.13 security release) is the fix that drew my attention to this new bug. Ironically, 592a99 (combined with this commit), will make it possible to eliminate the "offending" null termination line altogether since it will now be performed automatically by afs_pd_alloc(). [kaduk@mit.edu: adjust commit message for CVE number assignment, reduce unneeded churn in the diff.] Change-Id: I1a536b3a53ec4b6721fbd39a915207da4358720c
AFS is a distributed file system that enables users to share and access all of the files stored in a network of computers as easily as they access the files stored on their local machines. The file system is called distributed for this exact reason: files can reside on many different machines, but are available to users on every machine. OpenAFS 1.0 was originally released by IBM under the terms of the IBM Public License 1.0 (IPL10). For details on IPL10 see the LICENSE file in this directory. The current OpenAFS distribution is licensed under a combination of the IPL10 and many other licenses as granted by the relevant copyright holders. The LICENSE file in this directory contains more details, thought not a comprehensive statement. See INSTALL for information about building and installing OpenAFS on various platforms. See CODING for developer information and guidelines. See NEWS for recent changes to OpenAFS.
Description
Languages
C
72.2%
C++
20.1%
Makefile
1.4%
Perl
1.2%
Rich Text Format
1%
Other
3.7%