--- /dev/null
+From 2ef863720da4d9f368aaca0461c672a3008195ca Mon Sep 17 00:00:00 2001
+From: Mark Vitale <mvitale@sinenomine.net>
+Date: Fri, 7 Aug 2015 11:56:16 -0400
+Subject: [PATCH] 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: I0299274c6d879f95c9b40cc85859294c26c410d7
+---
+ src/afs/afs_pioctl.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c
+index e91316a..0c96172 100644
+--- a/src/afs/afs_pioctl.c
++++ b/src/afs/afs_pioctl.c
+@@ -53,8 +53,9 @@ struct afs_pdata {
+ static_inline int
+ afs_pd_alloc(struct afs_pdata *apd, size_t size)
+ {
+-
+- if (size > AFS_LRALLOCSIZ)
++ /* Ensure that we give caller at least one trailing guard byte
++ * for the NUL terminator. */
++ if (size >= AFS_LRALLOCSIZ)
+ apd->ptr = osi_Alloc(size + 1);
+ else
+ apd->ptr = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
+@@ -62,11 +63,13 @@ afs_pd_alloc(struct afs_pdata *apd, size_t size)
+ if (apd->ptr == NULL)
+ return ENOMEM;
+
+- if (size > AFS_LRALLOCSIZ)
++ /* Clear it all now, including the guard byte. */
++ if (size >= AFS_LRALLOCSIZ)
+ memset(apd->ptr, 0, size + 1);
+ else
+ memset(apd->ptr, 0, AFS_LRALLOCSIZ);
+
++ /* Don't tell the caller about the guard byte. */
+ apd->remaining = size;
+
+ return 0;
+@@ -78,7 +81,7 @@ afs_pd_free(struct afs_pdata *apd)
+ if (apd->ptr == NULL)
+ return;
+
+- if (apd->remaining > AFS_LRALLOCSIZ)
++ if (apd->remaining >= AFS_LRALLOCSIZ)
+ osi_Free(apd->ptr, apd->remaining + 1);
+ else
+ osi_FreeLargeSpace(apd->ptr);
+--
+2.8.1
+
--- /dev/null
+From 396240cf070a806b91fea81131d034e1399af1e0 Mon Sep 17 00:00:00 2001
+From: Benjamin Kaduk <kaduk@mit.edu>
+Date: Wed, 9 Mar 2016 19:30:20 -0600
+Subject: [PATCH] OPENAFS-SA-2016-001 group creation by foreign users
+
+CVE-2016-2860:
+
+The ptserver permits foreign-cell users to create groups as if they were
+system:administrators. In particular, groups in the user namespace
+(with no colon) and the system: namespace can be created. No group
+quota is enforced for the creation of these groups, but they will be
+owned by system:administrators and cannot be changed by the user that
+created them. When processing requests from foreign users, the
+creator ID is overwritten with the ID of system:administrators, and
+that field is later used for access control checks in
+CorrectGroupName(), called from CreateEntry().
+
+The access-control bypass is not possible for creating user entries,
+since there is an early check in CreateOK() that only permits
+administrators to create users, using a correct test for whether
+the call is being made by an administrator.
+
+FIXES 132822
+
+[Based on a patch by Jeffrey Altman.]
+
+Change-Id: I77dcf4a2f7d9c770c805a649f2ddc6bee5f83389
+---
+ src/ptserver/ptprocs.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/src/ptserver/ptprocs.c b/src/ptserver/ptprocs.c
+index ae1a562..f9f48fc 100644
+--- a/src/ptserver/ptprocs.c
++++ b/src/ptserver/ptprocs.c
+@@ -345,13 +345,19 @@ newEntry(struct rx_call *call, char aname[], afs_int32 flag, afs_int32 oid,
+ * automatic id assignment.
+ */
+ code = WhoIsThisWithName(call, tt, cid, cname);
+- if (code != 2) { /* 2 specifies that this is a foreign cell request */
+- if (code)
+- ABORT_WITH(tt, PRPERM);
+- admin = IsAMemberOf(tt, *cid, SYSADMINID);
+- } else {
+- admin = ((!restricted && !strcmp(aname, cname))) || IsAMemberOf(tt, *cid, SYSADMINID);
+- oid = *cid = SYSADMINID;
++ if (code && code != 2)
++ ABORT_WITH(tt, PRPERM);
++ admin = IsAMemberOf(tt, *cid, SYSADMINID);
++ if (code == 2 /* foreign cell request */) {
++ if (!restricted && (strcmp(aname, cname) == 0)) {
++ /* can't autoregister while providing an owner id */
++ if (oid != 0)
++ ABORT_WITH(tt, PRPERM);
++
++ admin = 1;
++ oid = SYSADMINID;
++ *cid = SYSADMINID;
++ }
+ }
+ if (!CreateOK(tt, *cid, oid, flag, admin))
+ ABORT_WITH(tt, PRPERM);
+--
+2.8.1
+