Print this page
10100 Illumos is confused about calloc() arguments


   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright 2014 Toomas Soome <tsoome@me.com>
  26  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.

  27  */
  28 
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <errno.h>
  32 #include <strings.h>
  33 #include <unistd.h>
  34 #include <smbios.h>
  35 #include <uuid/uuid.h>
  36 #include <libintl.h>
  37 #include <sys/types.h>
  38 #include <sys/dkio.h>
  39 #include <sys/vtoc.h>
  40 #include <sys/mhd.h>
  41 #include <sys/param.h>
  42 #include <sys/dktp/fdisk.h>
  43 #include <sys/efi_partition.h>
  44 #include <sys/byteorder.h>
  45 #include <sys/ddi.h>
  46 


 171         }
 172 
 173         nblocks = NBLOCKS(nparts, lbsize);
 174         if ((nblocks * lbsize) < EFI_MIN_ARRAY_SIZE + lbsize) {
 175                 /* 16K plus one block for the GPT */
 176                 nblocks = EFI_MIN_ARRAY_SIZE / lbsize + 1;
 177         }
 178 
 179         if (nparts > MAX_PARTS) {
 180                 if (efi_debug) {
 181                         (void) fprintf(stderr,
 182                         "the maximum number of partitions supported is %lu\n",
 183                             MAX_PARTS);
 184                 }
 185                 return (-1);
 186         }
 187 
 188         length = sizeof (struct dk_gpt) +
 189             sizeof (struct dk_part) * (nparts - 1);
 190 
 191         if ((*vtoc = calloc(length, 1)) == NULL)
 192                 return (-1);
 193 
 194         vptr = *vtoc;
 195 
 196         vptr->efi_version = EFI_VERSION_CURRENT;
 197         vptr->efi_lbasize = lbsize;
 198         vptr->efi_nparts = nparts;
 199         /*
 200          * add one block here for the PMBR; on disks with a 512 byte
 201          * block size and 128 or fewer partitions, efi_first_u_lba
 202          * should work out to "34"
 203          */
 204         vptr->efi_first_u_lba = nblocks + 1;
 205         vptr->efi_last_lba = capacity - 1;
 206         vptr->efi_altern_lba = capacity -1;
 207         vptr->efi_last_u_lba = vptr->efi_last_lba - nblocks;
 208 
 209         (void) uuid_generate((uchar_t *)&uuid);
 210         UUID_LE_CONVERT(vptr->efi_disk_uguid, uuid);
 211         return (0);
 212 }
 213 
 214 /*
 215  * Read EFI - return partition number upon success.
 216  */
 217 int
 218 efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
 219 {
 220         int                     rval;
 221         uint32_t                nparts;
 222         int                     length;
 223         struct mboot            *mbr;
 224         struct ipart            *ipart;
 225         diskaddr_t              capacity;
 226         uint_t                  lbsize;
 227         int                     i;
 228 
 229         if (read_disk_info(fd, &capacity, &lbsize) != 0)
 230                 return (VT_ERROR);
 231 
 232         if ((mbr = calloc(lbsize, 1)) == NULL)
 233                 return (VT_ERROR);
 234 
 235         if ((ioctl(fd, DKIOCGMBOOT, (caddr_t)mbr)) == -1) {
 236                 free(mbr);
 237                 return (VT_ERROR);
 238         }
 239 
 240         if (mbr->signature != MBB_MAGIC) {
 241                 free(mbr);
 242                 return (VT_EINVAL);
 243         }
 244         ipart = (struct ipart *)(uintptr_t)mbr->parts;
 245 
 246         /* Check if we have partition with ID EFI_PMBR */
 247         for (i = 0; i < FD_NUMPART; i++) {
 248                 if (ipart[i].systid == EFI_PMBR)
 249                         break;
 250         }
 251         free(mbr);
 252         if (i == FD_NUMPART)
 253                 return (VT_EINVAL);
 254 
 255         /* figure out the number of entries that would fit into 16K */
 256         nparts = EFI_MIN_ARRAY_SIZE / sizeof (efi_gpe_t);
 257         length = (int) sizeof (struct dk_gpt) +
 258             (int) sizeof (struct dk_part) * (nparts - 1);
 259         if ((*vtoc = calloc(length, 1)) == NULL)
 260                 return (VT_ERROR);
 261 
 262         (*vtoc)->efi_nparts = nparts;
 263         rval = efi_read(fd, *vtoc);
 264 
 265         if ((rval == VT_EINVAL) && (*vtoc)->efi_nparts > nparts) {
 266                 void *tmp;
 267                 length = (int) sizeof (struct dk_gpt) +
 268                     (int) sizeof (struct dk_part) *
 269                     ((*vtoc)->efi_nparts - 1);
 270                 nparts = (*vtoc)->efi_nparts;
 271                 if ((tmp = realloc(*vtoc, length)) == NULL) {
 272                         free (*vtoc);
 273                         *vtoc = NULL;
 274                         return (VT_ERROR);
 275                 } else {
 276                         *vtoc = tmp;
 277                         rval = efi_read(fd, *vtoc);
 278                 }
 279         }


 406                 }
 407                 disk_info.dki_lbsize = DEV_BSIZE;
 408         }
 409         /*
 410          * Read the EFI GPT to figure out how many partitions we need
 411          * to deal with.
 412          */
 413         dk_ioc.dki_lba = 1;
 414         if (NBLOCKS(vtoc->efi_nparts, disk_info.dki_lbsize) < 34) {
 415                 label_len = EFI_MIN_ARRAY_SIZE + disk_info.dki_lbsize;
 416         } else {
 417                 label_len = vtoc->efi_nparts * (int) sizeof (efi_gpe_t) +
 418                     disk_info.dki_lbsize;
 419                 if (label_len % disk_info.dki_lbsize) {
 420                         /* pad to physical sector size */
 421                         label_len += disk_info.dki_lbsize;
 422                         label_len &= ~(disk_info.dki_lbsize - 1);
 423                 }
 424         }
 425 
 426         if ((dk_ioc.dki_data = calloc(label_len, 1)) == NULL)
 427                 return (VT_ERROR);
 428 
 429         dk_ioc.dki_length = disk_info.dki_lbsize;
 430         user_length = vtoc->efi_nparts;
 431         efi = dk_ioc.dki_data;
 432         if ((rval = check_label(fd, &dk_ioc)) == VT_EINVAL) {
 433                 /*
 434                  * No valid label here; try the alternate. Note that here
 435                  * we just read GPT header and save it into dk_ioc.data,
 436                  * Later, we will read GUID partition entry array if we
 437                  * can get valid GPT header.
 438                  */
 439 
 440                 /*
 441                  * This is a workaround for legacy systems. In the past, the
 442                  * last sector of SCSI disk was invisible on x86 platform. At
 443                  * that time, backup label was saved on the next to the last
 444                  * sector. It is possible for users to move a disk from previous
 445                  * solaris system to present system. Here, we attempt to search
 446                  * legacy backup EFI label first.


1003         dk_ioc.dki_lba = 1;
1004         if (NBLOCKS(vtoc->efi_nparts, vtoc->efi_lbasize) < 34) {
1005                 dk_ioc.dki_length = EFI_MIN_ARRAY_SIZE + vtoc->efi_lbasize;
1006         } else {
1007                 dk_ioc.dki_length = NBLOCKS(vtoc->efi_nparts,
1008                     vtoc->efi_lbasize) *
1009                     vtoc->efi_lbasize;
1010         }
1011 
1012         /*
1013          * the number of blocks occupied by GUID partition entry array
1014          */
1015         nblocks = dk_ioc.dki_length / vtoc->efi_lbasize - 1;
1016 
1017         /*
1018          * Backup GPT header is located on the block after GUID
1019          * partition entry array. Here, we calculate the address
1020          * for backup GPT header.
1021          */
1022         lba_backup_gpt_hdr = vtoc->efi_last_u_lba + 1 + nblocks;
1023         if ((dk_ioc.dki_data = calloc(dk_ioc.dki_length, 1)) == NULL)
1024                 return (VT_ERROR);
1025 
1026         efi = dk_ioc.dki_data;
1027 
1028         /* stuff user's input into EFI struct */
1029         efi->efi_gpt_Signature = LE_64(EFI_SIGNATURE);
1030         efi->efi_gpt_Revision = LE_32(vtoc->efi_version); /* 0x02000100 */
1031         efi->efi_gpt_HeaderSize = LE_32(sizeof (struct efi_gpt));
1032         efi->efi_gpt_Reserved1 = 0;
1033         efi->efi_gpt_MyLBA = LE_64(1ULL);
1034         efi->efi_gpt_AlternateLBA = LE_64(lba_backup_gpt_hdr);
1035         efi->efi_gpt_FirstUsableLBA = LE_64(vtoc->efi_first_u_lba);
1036         efi->efi_gpt_LastUsableLBA = LE_64(vtoc->efi_last_u_lba);
1037         efi->efi_gpt_PartitionEntryLBA = LE_64(2ULL);
1038         efi->efi_gpt_NumberOfPartitionEntries = LE_32(vtoc->efi_nparts);
1039         efi->efi_gpt_SizeOfPartitionEntry = LE_32(sizeof (struct efi_gpe));
1040         UUID_LE_CONVERT(efi->efi_gpt_DiskGUID, vtoc->efi_disk_uguid);
1041 
1042         /* LINTED -- always longlong aligned */
1043         efi_parts = (efi_gpe_t *)((char *)dk_ioc.dki_data + vtoc->efi_lbasize);




   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright 2014 Toomas Soome <tsoome@me.com>
  26  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  27  * Copyright (c) 2018, Joyent, Inc.
  28  */
  29 
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 #include <errno.h>
  33 #include <strings.h>
  34 #include <unistd.h>
  35 #include <smbios.h>
  36 #include <uuid/uuid.h>
  37 #include <libintl.h>
  38 #include <sys/types.h>
  39 #include <sys/dkio.h>
  40 #include <sys/vtoc.h>
  41 #include <sys/mhd.h>
  42 #include <sys/param.h>
  43 #include <sys/dktp/fdisk.h>
  44 #include <sys/efi_partition.h>
  45 #include <sys/byteorder.h>
  46 #include <sys/ddi.h>
  47 


 172         }
 173 
 174         nblocks = NBLOCKS(nparts, lbsize);
 175         if ((nblocks * lbsize) < EFI_MIN_ARRAY_SIZE + lbsize) {
 176                 /* 16K plus one block for the GPT */
 177                 nblocks = EFI_MIN_ARRAY_SIZE / lbsize + 1;
 178         }
 179 
 180         if (nparts > MAX_PARTS) {
 181                 if (efi_debug) {
 182                         (void) fprintf(stderr,
 183                         "the maximum number of partitions supported is %lu\n",
 184                             MAX_PARTS);
 185                 }
 186                 return (-1);
 187         }
 188 
 189         length = sizeof (struct dk_gpt) +
 190             sizeof (struct dk_part) * (nparts - 1);
 191 
 192         if ((*vtoc = calloc(1, length)) == NULL)
 193                 return (-1);
 194 
 195         vptr = *vtoc;
 196 
 197         vptr->efi_version = EFI_VERSION_CURRENT;
 198         vptr->efi_lbasize = lbsize;
 199         vptr->efi_nparts = nparts;
 200         /*
 201          * add one block here for the PMBR; on disks with a 512 byte
 202          * block size and 128 or fewer partitions, efi_first_u_lba
 203          * should work out to "34"
 204          */
 205         vptr->efi_first_u_lba = nblocks + 1;
 206         vptr->efi_last_lba = capacity - 1;
 207         vptr->efi_altern_lba = capacity -1;
 208         vptr->efi_last_u_lba = vptr->efi_last_lba - nblocks;
 209 
 210         (void) uuid_generate((uchar_t *)&uuid);
 211         UUID_LE_CONVERT(vptr->efi_disk_uguid, uuid);
 212         return (0);
 213 }
 214 
 215 /*
 216  * Read EFI - return partition number upon success.
 217  */
 218 int
 219 efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
 220 {
 221         int                     rval;
 222         uint32_t                nparts;
 223         int                     length;
 224         struct mboot            *mbr;
 225         struct ipart            *ipart;
 226         diskaddr_t              capacity;
 227         uint_t                  lbsize;
 228         int                     i;
 229 
 230         if (read_disk_info(fd, &capacity, &lbsize) != 0)
 231                 return (VT_ERROR);
 232 
 233         if ((mbr = calloc(1, lbsize)) == NULL)
 234                 return (VT_ERROR);
 235 
 236         if ((ioctl(fd, DKIOCGMBOOT, (caddr_t)mbr)) == -1) {
 237                 free(mbr);
 238                 return (VT_ERROR);
 239         }
 240 
 241         if (mbr->signature != MBB_MAGIC) {
 242                 free(mbr);
 243                 return (VT_EINVAL);
 244         }
 245         ipart = (struct ipart *)(uintptr_t)mbr->parts;
 246 
 247         /* Check if we have partition with ID EFI_PMBR */
 248         for (i = 0; i < FD_NUMPART; i++) {
 249                 if (ipart[i].systid == EFI_PMBR)
 250                         break;
 251         }
 252         free(mbr);
 253         if (i == FD_NUMPART)
 254                 return (VT_EINVAL);
 255 
 256         /* figure out the number of entries that would fit into 16K */
 257         nparts = EFI_MIN_ARRAY_SIZE / sizeof (efi_gpe_t);
 258         length = (int) sizeof (struct dk_gpt) +
 259             (int) sizeof (struct dk_part) * (nparts - 1);
 260         if ((*vtoc = calloc(1, length)) == NULL)
 261                 return (VT_ERROR);
 262 
 263         (*vtoc)->efi_nparts = nparts;
 264         rval = efi_read(fd, *vtoc);
 265 
 266         if ((rval == VT_EINVAL) && (*vtoc)->efi_nparts > nparts) {
 267                 void *tmp;
 268                 length = (int) sizeof (struct dk_gpt) +
 269                     (int) sizeof (struct dk_part) *
 270                     ((*vtoc)->efi_nparts - 1);
 271                 nparts = (*vtoc)->efi_nparts;
 272                 if ((tmp = realloc(*vtoc, length)) == NULL) {
 273                         free (*vtoc);
 274                         *vtoc = NULL;
 275                         return (VT_ERROR);
 276                 } else {
 277                         *vtoc = tmp;
 278                         rval = efi_read(fd, *vtoc);
 279                 }
 280         }


 407                 }
 408                 disk_info.dki_lbsize = DEV_BSIZE;
 409         }
 410         /*
 411          * Read the EFI GPT to figure out how many partitions we need
 412          * to deal with.
 413          */
 414         dk_ioc.dki_lba = 1;
 415         if (NBLOCKS(vtoc->efi_nparts, disk_info.dki_lbsize) < 34) {
 416                 label_len = EFI_MIN_ARRAY_SIZE + disk_info.dki_lbsize;
 417         } else {
 418                 label_len = vtoc->efi_nparts * (int) sizeof (efi_gpe_t) +
 419                     disk_info.dki_lbsize;
 420                 if (label_len % disk_info.dki_lbsize) {
 421                         /* pad to physical sector size */
 422                         label_len += disk_info.dki_lbsize;
 423                         label_len &= ~(disk_info.dki_lbsize - 1);
 424                 }
 425         }
 426 
 427         if ((dk_ioc.dki_data = calloc(1, label_len)) == NULL)
 428                 return (VT_ERROR);
 429 
 430         dk_ioc.dki_length = disk_info.dki_lbsize;
 431         user_length = vtoc->efi_nparts;
 432         efi = dk_ioc.dki_data;
 433         if ((rval = check_label(fd, &dk_ioc)) == VT_EINVAL) {
 434                 /*
 435                  * No valid label here; try the alternate. Note that here
 436                  * we just read GPT header and save it into dk_ioc.data,
 437                  * Later, we will read GUID partition entry array if we
 438                  * can get valid GPT header.
 439                  */
 440 
 441                 /*
 442                  * This is a workaround for legacy systems. In the past, the
 443                  * last sector of SCSI disk was invisible on x86 platform. At
 444                  * that time, backup label was saved on the next to the last
 445                  * sector. It is possible for users to move a disk from previous
 446                  * solaris system to present system. Here, we attempt to search
 447                  * legacy backup EFI label first.


1004         dk_ioc.dki_lba = 1;
1005         if (NBLOCKS(vtoc->efi_nparts, vtoc->efi_lbasize) < 34) {
1006                 dk_ioc.dki_length = EFI_MIN_ARRAY_SIZE + vtoc->efi_lbasize;
1007         } else {
1008                 dk_ioc.dki_length = NBLOCKS(vtoc->efi_nparts,
1009                     vtoc->efi_lbasize) *
1010                     vtoc->efi_lbasize;
1011         }
1012 
1013         /*
1014          * the number of blocks occupied by GUID partition entry array
1015          */
1016         nblocks = dk_ioc.dki_length / vtoc->efi_lbasize - 1;
1017 
1018         /*
1019          * Backup GPT header is located on the block after GUID
1020          * partition entry array. Here, we calculate the address
1021          * for backup GPT header.
1022          */
1023         lba_backup_gpt_hdr = vtoc->efi_last_u_lba + 1 + nblocks;
1024         if ((dk_ioc.dki_data = calloc(1, dk_ioc.dki_length)) == NULL)
1025                 return (VT_ERROR);
1026 
1027         efi = dk_ioc.dki_data;
1028 
1029         /* stuff user's input into EFI struct */
1030         efi->efi_gpt_Signature = LE_64(EFI_SIGNATURE);
1031         efi->efi_gpt_Revision = LE_32(vtoc->efi_version); /* 0x02000100 */
1032         efi->efi_gpt_HeaderSize = LE_32(sizeof (struct efi_gpt));
1033         efi->efi_gpt_Reserved1 = 0;
1034         efi->efi_gpt_MyLBA = LE_64(1ULL);
1035         efi->efi_gpt_AlternateLBA = LE_64(lba_backup_gpt_hdr);
1036         efi->efi_gpt_FirstUsableLBA = LE_64(vtoc->efi_first_u_lba);
1037         efi->efi_gpt_LastUsableLBA = LE_64(vtoc->efi_last_u_lba);
1038         efi->efi_gpt_PartitionEntryLBA = LE_64(2ULL);
1039         efi->efi_gpt_NumberOfPartitionEntries = LE_32(vtoc->efi_nparts);
1040         efi->efi_gpt_SizeOfPartitionEntry = LE_32(sizeof (struct efi_gpe));
1041         UUID_LE_CONVERT(efi->efi_gpt_DiskGUID, vtoc->efi_disk_uguid);
1042 
1043         /* LINTED -- always longlong aligned */
1044         efi_parts = (efi_gpe_t *)((char *)dk_ioc.dki_data + vtoc->efi_lbasize);