Author: markj
Date: Fri Sep 25 13:28:57 2020
New Revision: 366155
URL: https://svnweb.freebsd.org/changeset/base/366155

Log:
  MFC r366005:
  udf: Validate the full file entry length
  
  PR:   248613

Modified:
  stable/11/sys/fs/udf/udf_vfsops.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/fs/udf/udf_vfsops.c
==============================================================================
--- stable/11/sys/fs/udf/udf_vfsops.c   Fri Sep 25 13:24:29 2020        
(r366154)
+++ stable/11/sys/fs/udf/udf_vfsops.c   Fri Sep 25 13:28:57 2020        
(r366155)
@@ -588,6 +588,7 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struc
        struct vnode *vp;
        struct udf_node *unode;
        struct file_entry *fe;
+       uint32_t lea, lad;
        int error, sector, size;
 
        error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL);
@@ -643,31 +644,37 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struc
        devvp = udfmp->im_devvp;
        if ((error = RDSECTOR(devvp, sector, udfmp->bsize, &bp)) != 0) {
                printf("Cannot read sector %d\n", sector);
-               vgone(vp);
-               vput(vp);
-               brelse(bp);
-               *vpp = NULL;
-               return (error);
+               goto error;
        }
 
+       /*
+        * File entry length validation.
+        */
        fe = (struct file_entry *)bp->b_data;
        if (udf_checktag(&fe->tag, TAGID_FENTRY)) {
                printf("Invalid file entry!\n");
-               vgone(vp);
-               vput(vp);
-               brelse(bp);
-               *vpp = NULL;
-               return (ENOMEM);
+               error = ENOMEM;
+               goto error;
        }
-       size = UDF_FENTRY_SIZE + le32toh(fe->l_ea) + le32toh(fe->l_ad);
+       lea = le32toh(fe->l_ea);
+       lad = le32toh(fe->l_ad);
+       if (lea > udfmp->bsize || lad > udfmp->bsize) {
+               printf("Invalid EA and AD lengths %u, %u\n", lea, lad);
+               error = EIO;
+               goto error;
+       }
+       size = UDF_FENTRY_SIZE + lea + lad;
+       if (size > udfmp->bsize) {
+               printf("Invalid file entry size %u\n", size);
+               error = EIO;
+               goto error;
+       }
+
        unode->fentry = malloc(size, M_UDFFENTRY, M_NOWAIT | M_ZERO);
        if (unode->fentry == NULL) {
                printf("Cannot allocate file entry block\n");
-               vgone(vp);
-               vput(vp);
-               brelse(bp);
-               *vpp = NULL;
-               return (ENOMEM);
+               error = ENOMEM;
+               goto error;
        }
 
        bcopy(bp->b_data, unode->fentry, size);
@@ -712,6 +719,13 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struc
        *vpp = vp;
 
        return (0);
+
+error:
+       vgone(vp);
+       vput(vp);
+       brelse(bp);
+       *vpp = NULL;
+       return (error);
 }
 
 static int
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to