Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset d8513177 in mainline


Ignore:
Timestamp:
2015-11-03T21:31:53Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
eed70f1
Parents:
ff381a7
Message:

Initialize EBR for empty partition chain when creating extended partition. Fix logical partition size. When creating partition in liblabel, check index and block range are within bounds and free.

Location:
uspace/lib
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/fdisk/src/fdisk.c

    rff381a7 rd8513177  
    10891089        vpspec->hdr_blocks = hdrb;
    10901090        vpspec->block0 = fblock0 + hdrb;
    1091         vpspec->nblocks = act_blocks;
     1091        vpspec->nblocks = act_blocks - hdrb;
    10921092        vpspec->pkind = pspec->pkind;
    10931093
  • uspace/lib/label/src/gpt.c

    rff381a7 rd8513177  
    5757static int gpt_suggest_ptype(label_t *, label_pcnt_t, label_ptype_t *);
    5858
     59static int gpt_check_free_idx(label_t *, int);
     60static int gpt_check_free_range(label_t *, uint64_t, uint64_t);
     61
    5962static void gpt_unused_pte(gpt_entry_t *);
    6063static int gpt_part_to_pte(label_part_t *, gpt_entry_t *);
     
    608611        }
    609612
    610         /* XXX Verify index, block0, nblocks */
    611 
    612         if (pspec->index < 1 || pspec->index > label->pri_entries) {
     613        /* Verify index is within bounds and free */
     614        rc = gpt_check_free_idx(label, pspec->index);
     615        if (rc != EOK) {
     616                rc = EINVAL;
     617                goto error;
     618        }
     619
     620        /* Verify range is within bounds and free */
     621        rc = gpt_check_free_range(label, pspec->block0, pspec->nblocks);
     622        if (rc != EOK) {
    613623                rc = EINVAL;
    614624                goto error;
     
    711721}
    712722
     723/** Verify that the specified index is valid and free. */
     724static int gpt_check_free_idx(label_t *label, int index)
     725{
     726        label_part_t *part;
     727
     728        if (index < 1 || index > label->pri_entries)
     729                return EINVAL;
     730
     731        part = gpt_part_first(label);
     732        while (part != NULL) {
     733                if (part->index == index)
     734                        return EEXIST;
     735                part = gpt_part_next(part);
     736        }
     737
     738        return EOK;
     739}
     740
     741/** Determine if two block address ranges overlap. */
     742static bool gpt_overlap(uint64_t a0, uint64_t an, uint64_t b0, uint64_t bn)
     743{
     744        return !(a0 + an <= b0 || b0 + bn <= a0);
     745}
     746
     747static int gpt_check_free_range(label_t *label, uint64_t block0,
     748    uint64_t nblocks)
     749{
     750        label_part_t *part;
     751
     752        if (block0 < label->ablock0)
     753                return EINVAL;
     754        if (block0 + nblocks > label->ablock0 + label->anblocks)
     755                return EINVAL;
     756
     757        part = gpt_part_first(label);
     758        while (part != NULL) {
     759                if (gpt_overlap(block0, nblocks, part->block0, part->nblocks))
     760                        return EEXIST;
     761                part = gpt_part_next(part);
     762        }
     763
     764        return EOK;
     765}
     766
    713767static void gpt_unused_pte(gpt_entry_t *pte)
    714768{
  • uspace/lib/label/src/mbr.c

    rff381a7 rd8513177  
    5656static int mbr_suggest_ptype(label_t *, label_pcnt_t, label_ptype_t *);
    5757
     58static int mbr_check_free_idx(label_t *, int);
     59static int mbr_check_free_pri_range(label_t *, uint64_t, uint64_t);
     60static int mbr_check_free_log_range(label_t *, uint64_t, uint64_t, uint64_t);
     61
    5862static void mbr_unused_pte(mbr_pte_t *);
    5963static int mbr_part_to_pte(label_part_t *, mbr_pte_t *);
     
    486490}
    487491
     492static label_part_t *mbr_pri_part_first(label_t *label)
     493{
     494        link_t *link;
     495
     496        link = list_first(&label->pri_parts);
     497        if (link == NULL)
     498                return NULL;
     499
     500        return list_get_instance(link, label_part_t, lpri);
     501}
     502
     503static label_part_t *mbr_pri_part_next(label_part_t *part)
     504{
     505        link_t *link;
     506
     507        link = list_next(&part->lpri, &part->label->pri_parts);
     508        if (link == NULL)
     509                return NULL;
     510
     511        return list_get_instance(link, label_part_t, lpri);
     512}
     513
    488514static void mbr_part_get_info(label_part_t *part, label_part_info_t *pinfo)
    489515{
     
    515541        if (part == NULL)
    516542                return ENOMEM;
    517 
    518543
    519544        /* XXX Check if index is used */
     
    551576        if (pspec->pkind != lpk_logical) {
    552577                /* Primary or extended partition */
    553                 /* XXX Verify index, block0, nblocks */
    554 
    555                 if (pspec->index < 1 || pspec->index > label->pri_entries) {
     578
     579                /* Verify index is within bounds and free */
     580                rc = mbr_check_free_idx(label, pspec->index);
     581                if (rc != EOK) {
     582                        rc = EINVAL;
     583                        goto error;
     584                }
     585
     586                /* Verify range is within bounds and free */
     587                rc = mbr_check_free_pri_range(label, pspec->block0, pspec->nblocks);
     588                if (rc != EOK) {
    556589                        rc = EINVAL;
    557590                        goto error;
     
    575608                }
    576609
     610                if (pspec->pkind == lpk_extended) {
     611                        label->ext_part = part;
     612
     613                        /* Create EBR for empty partition chain */
     614                        rc = mbr_ebr_create(label, NULL);
     615                        if (rc != EOK) {
     616                                label->ext_part = NULL;
     617                                rc = EIO;
     618                                goto error;
     619                        }
     620                }
     621
    577622                list_append(&part->lparts, &label->parts);
    578623                list_append(&part->lpri, &label->pri_parts);
    579 
    580                 if (pspec->pkind == lpk_extended)
    581                         label->ext_part = part;
    582624        } else {
     625                /* Verify range is within bounds and free */
     626                rc = mbr_check_free_log_range(label, pspec->hdr_blocks,
     627                    pspec->block0, pspec->nblocks);
     628                if (rc != EOK) {
     629                        rc = EINVAL;
     630                        goto error;
     631                }
     632
    583633                /* Logical partition */
    584634                rc = mbr_log_part_insert(label, part);
     
    736786}
    737787
     788/** Determine if two block address ranges overlap. */
     789static bool mbr_overlap(uint64_t a0, uint64_t an, uint64_t b0, uint64_t bn)
     790{
     791        return !(a0 + an <= b0 || b0 + bn <= a0);
     792}
     793
     794/** Verify that the specified index is valid and free. */
     795static int mbr_check_free_idx(label_t *label, int index)
     796{
     797        label_part_t *part;
     798
     799        if (index < 1 || index > label->pri_entries)
     800                return EINVAL;
     801
     802        part = mbr_pri_part_first(label);
     803        while (part != NULL) {
     804                if (part->index == index)
     805                        return EEXIST;
     806                part = mbr_pri_part_next(part);
     807        }
     808
     809        return EOK;
     810}
     811
     812static int mbr_check_free_pri_range(label_t *label, uint64_t block0,
     813    uint64_t nblocks)
     814{
     815        label_part_t *part;
     816
     817        if (block0 < label->ablock0)
     818                return EINVAL;
     819        if (block0 + nblocks > label->ablock0 + label->anblocks)
     820                return EINVAL;
     821
     822        part = mbr_pri_part_first(label);
     823        while (part != NULL) {
     824                if (mbr_overlap(block0, nblocks, part->block0, part->nblocks))
     825                        return EEXIST;
     826                part = mbr_pri_part_next(part);
     827        }
     828
     829        return EOK;
     830}
     831
     832static int mbr_check_free_log_range(label_t *label, uint64_t hdr_blocks,
     833    uint64_t block0, uint64_t nblocks)
     834{
     835        label_part_t *part;
     836
     837        if (block0 - hdr_blocks < label->ext_part->block0)
     838                return EINVAL;
     839        if (block0 + nblocks > label->ext_part->block0 + label->ext_part->nblocks)
     840                return EINVAL;
     841
     842        part = mbr_log_part_first(label);
     843        while (part != NULL) {
     844                if (mbr_overlap(block0 - hdr_blocks, nblocks + hdr_blocks,
     845                    part->block0 - part->hdr_blocks, part->nblocks + part->hdr_blocks))
     846                        return EEXIST;
     847                part = mbr_log_part_next(part);
     848        }
     849
     850        return EOK;
     851}
     852
    738853
    739854static void mbr_unused_pte(mbr_pte_t *pte)
     
    9241039}
    9251040
    926 /** Create EBR for partition. */
     1041/** Create EBR for partition.
     1042 *
     1043 * @param label Label
     1044 * @param part Partition for which to create EBR or @c NULL to create
     1045 *        EBR for empty partition chain
     1046 * @return EOK on success or non-zero error code
     1047 */
    9271048static int mbr_ebr_create(label_t *label, label_part_t *part)
    9281049{
     
    9351056                return ENOMEM;
    9361057
    937         mbr_log_part_to_ptes(part, &br->pte[mbr_ebr_pte_this],
    938             &br->pte[mbr_ebr_pte_next]);
     1058        if (part != NULL) {
     1059                ba = part->block0 - part->hdr_blocks;
     1060                mbr_log_part_to_ptes(part, &br->pte[mbr_ebr_pte_this],
     1061                    &br->pte[mbr_ebr_pte_next]);
     1062        } else {
     1063                ba = label->ext_part->block0;
     1064        }
     1065
    9391066        br->signature = host2uint16_t_le(mbr_br_signature);
    940 
    941         ba = part->block0 - part->hdr_blocks;
    9421067
    9431068        rc = block_write_direct(label->svc_id, ba, 1, br);
Note: See TracChangeset for help on using the changeset viewer.