afs: pioctl kernel memory overrun
[openafs.git] / src / afs / afs_pioctl.c
index 4efcd51..948809d 100644 (file)
@@ -55,8 +55,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);
@@ -64,11 +65,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;
@@ -80,7 +83,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);