Pull out a few common subexpressions. I think this makes the code
easier to read. Some byte swaps are left, when they are only used once.

Then use mallocarray for bounds checking.

Also observe the following:
+               if (ghsize < GPTMINHDRSIZE && ghsize > DEV_BSIZE)
I'm pretty sure that should be an ||, otherwise it's never true.


Index: subr_disk.c
===================================================================
RCS file: /cvs/src/sys/kern/subr_disk.c,v
retrieving revision 1.170
diff -u -p -r1.170 subr_disk.c
--- subr_disk.c 14 Sep 2014 14:17:25 -0000      1.170
+++ subr_disk.c 2 Nov 2014 02:40:18 -0000
@@ -647,6 +647,11 @@ readgptlabel(struct buf *bp, void (*stra
         */
        for (part_blkno = GPTSECTOR; ; part_blkno = gh.gh_lba_alt, 
            altheader = 1) {
+               uint32_t ghsize;
+               uint32_t ghpartsize;
+               uint32_t ghpartnum;
+               size_t gpsz;
+
                /* read header record */
                bp->b_blkno = DL_BLKTOSEC(lp, part_blkno) * DL_BLKSPERSEC(lp);
                offset = DL_BLKOFFSET(lp, part_blkno);
@@ -665,6 +670,10 @@ readgptlabel(struct buf *bp, void (*stra
                }
 
                bcopy(bp->b_data + offset, &gh, sizeof(gh));
+               ghsize = letoh32(gh.gh_size);
+               ghpartsize = letoh32(gh.gh_part_size);
+               ghpartnum = letoh32(gh.gh_part_num);
+
 
                if (letoh64(gh.gh_sig) != GPTSIGNATURE)
                        return (EINVAL);
@@ -693,8 +702,7 @@ readgptlabel(struct buf *bp, void (*stra
                 * Header size must be greater than or equal to 92 and less
                 * than or equal to the logical block size.
                 */
-               if (letoh32(gh.gh_size) < GPTMINHDRSIZE
-                   && letoh32(gh.gh_size) > DEV_BSIZE)
+               if (ghsize < GPTMINHDRSIZE && ghsize > DEV_BSIZE)
                        return (EINVAL);
 
                if (letoh64(gh.gh_lba_start) >= DL_GETDSIZE(lp) ||
@@ -706,8 +714,8 @@ readgptlabel(struct buf *bp, void (*stra
                * Size per partition entry shall be 128*(2**n) with n >= 0.
                * We don't support partition entries larger than block size.
                */
-               if (letoh32(gh.gh_part_size) % GPTMINPARTSIZE
-                   || letoh32(gh.gh_part_size) > DEV_BSIZE
+               if (ghpartsize % GPTMINPARTSIZE
+                   || ghpartsize > DEV_BSIZE
                    || GPT_PARTSPERSEC(&gh) == 0) {
                        DPRINTF("invalid partition size\n");
                        return (EINVAL);
@@ -721,16 +729,16 @@ readgptlabel(struct buf *bp, void (*stra
                }
 
                /* read GPT partition entry array */
-               gpsz = letoh32(gh.gh_part_num) * sizeof(struct gpt_partition);
-               gp = malloc(gpsz, M_DEVBUF, M_NOWAIT|M_ZERO);
+               gp = mallocarray(ghpartnum, sizeof(struct gpt_partition), 
M_DEVBUF, M_NOWAIT|M_ZERO);
                if (gp == NULL)
                        return (ENOMEM);
+               gpsz = ghpartnum * sizeof(struct gpt_partition);
 
                /*
                * XXX: Fails if # of partition entries is no multiple of
                * GPT_PARTSPERSEC(&gh)
                */
-               for (i = 0; i < letoh32(gh.gh_part_num) / GPT_PARTSPERSEC(&gh);
+               for (i = 0; i < ghpartnum / GPT_PARTSPERSEC(&gh);
                     i++) {
                        part_blkno = letoh64(gh.gh_part_lba) + i;
                        /* read partition record */

Reply via email to