From: Karel Zak Date: Wed, 18 Sep 2013 10:50:35 +0000 (+0200) Subject: libfdisk: fix sectorbuffer usage in dos driver X-Git-Tag: v2.24-rc1~79 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9c825fa026b5c848b1b5ffaa53192f46cdf6d156;p=thirdparty%2Futil-linux.git libfdisk: fix sectorbuffer usage in dos driver Signed-off-by: Karel Zak --- diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index 9081e6ac18..d83da432e6 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -133,6 +133,8 @@ static void partition_set_changed( if (!pe) return; + DBG(LABEL, dbgprint("DOS: setting %zu partition changed", i)); + pe->changed = changed ? 1 : 0; if (changed) fdisk_label_set_changed(cxt->label, 1); @@ -203,6 +205,8 @@ static int read_pte(struct fdisk_context *cxt, int pno, sector_t offset) if (!buf) return -ENOMEM; + DBG(LABEL, dbgprint("DOS: reading pte %d sector buffer %p", pno, buf)); + pe->offset = offset; pe->sectorbuffer = buf; pe->private_sectorbuffer = 1; @@ -241,6 +245,8 @@ static void dos_init(struct fdisk_context *cxt) assert(cxt->label); assert(fdisk_is_disklabel(cxt, DOS)); + DBG(LABEL, dbgprint("DOS: initialize, first sector buffer %p", cxt->firstsector)); + cxt->label->nparts_max = 4; /* default, unlimited number of logical */ l->ext_index = 0; @@ -256,6 +262,7 @@ static void dos_init(struct fdisk_context *cxt) pe->ex_entry = NULL; pe->offset = 0; pe->sectorbuffer = cxt->firstsector; + pe->private_sectorbuffer = 0; pe->changed = 0; } @@ -305,9 +312,13 @@ static void dos_deinit(struct fdisk_label *lb) for (i = 0; i < ARRAY_SIZE(l->ptes); i++) { struct pte *pe = &l->ptes[i]; - if (pe->private_sectorbuffer) + if (pe->private_sectorbuffer && pe->sectorbuffer) { + DBG(LABEL, dbgprint("DOS: freeing pte %zu sector buffer %p", + i, pe->sectorbuffer)); free(pe->sectorbuffer); + } pe->sectorbuffer = NULL; + pe->private_sectorbuffer = 0; } memset(l->ptes, 0, sizeof(l->ptes)); @@ -328,6 +339,8 @@ static int dos_delete_partition(struct fdisk_context *cxt, size_t partnum) if (!pe) return -EINVAL; + DBG(LABEL, dbgprint("DOS: delete partiton %zu", partnum)); + l = self_label(cxt); p = pe->pt_entry; q = pe->ex_entry; @@ -335,6 +348,7 @@ static int dos_delete_partition(struct fdisk_context *cxt, size_t partnum) /* Note that for the fifth partition (partnum == 4) we don't actually decrement partitions. */ if (partnum < 4) { + DBG(LABEL, dbgprint("--> delete primary")); if (IS_EXTENDED(p->sys_ind) && partnum == l->ext_index) { cxt->label->nparts_max = 4; l->ptes[l->ext_index].ex_entry = NULL; @@ -343,13 +357,13 @@ static int dos_delete_partition(struct fdisk_context *cxt, size_t partnum) partition_set_changed(cxt, partnum, 1); clear_partition(p); } else if (!q->sys_ind && partnum > 4) { - /* the last one in the chain - just delete */ + DBG(LABEL, dbgprint("--> delete logical [last in the chain]")); --cxt->label->nparts_max; --partnum; clear_partition(l->ptes[partnum].ex_entry); partition_set_changed(cxt, partnum, 1); } else { - /* not the last one - further ones will be moved down */ + DBG(LABEL, dbgprint("--> delete logical [non-last, move down]")); if (partnum > 4) { /* delete this link in the chain */ p = l->ptes[partnum - 1].ex_entry; @@ -371,10 +385,17 @@ static int dos_delete_partition(struct fdisk_context *cxt, size_t partnum) if (cxt->label->nparts_max > 5) { cxt->label->nparts_max--; + if (l->ptes[partnum].private_sectorbuffer) { + DBG(LABEL, dbgprint("--> freeing pte %zu sector buffer %p", + partnum, l->ptes[partnum].sectorbuffer)); + free(l->ptes[partnum].sectorbuffer); + } while (partnum < cxt->label->nparts_max) { + DBG(LABEL, dbgprint("--> moving pte %zu <-- %zd", partnum, partnum + 1)); l->ptes[partnum] = l->ptes[partnum + 1]; partnum++; } + memset(&l->ptes[partnum], 0, sizeof(struct pte)); } else /* the only logical: clear only */ clear_partition(l->ptes[partnum].pt_entry); @@ -401,6 +422,8 @@ static void read_extended(struct fdisk_context *cxt, int ext) return; } + DBG(LABEL, dbgprint("DOS: REading extended %d", ext)); + while (IS_EXTENDED (p->sys_ind)) { struct pte *pe = self_pte(cxt, cxt->label->nparts_max); @@ -506,6 +529,8 @@ static int dos_create_disklabel(struct fdisk_context *cxt) assert(cxt->label); assert(fdisk_is_disklabel(cxt, DOS)); + DBG(LABEL, dbgprint("DOS: creating new disklabel")); + /* random disk signature */ random_get_bytes(&id, sizeof(id)); @@ -536,6 +561,8 @@ static int dos_set_disklabel_id(struct fdisk_context *cxt) assert(cxt->label); assert(fdisk_is_disklabel(cxt, DOS)); + DBG(LABEL, dbgprint("DOS: setting Id")); + l = self_label(cxt); old = mbr_get_id(cxt->firstsector); rc = fdisk_ask_string(cxt, @@ -601,6 +628,7 @@ static int dos_reset_alignment(struct fdisk_context *cxt) /* overwrite necessary stuff by DOS deprecated stuff */ if (is_dos_compatible(cxt)) { + DBG(LABEL, dbgprint("DOS: reseting alignemnt for DOS-comaptiblem PT")); if (cxt->geom.sectors) cxt->first_lba = cxt->geom.sectors; /* usually 63 */ @@ -771,6 +799,8 @@ static int add_partition(struct fdisk_context *cxt, int n, struct fdisk_parttype first[cxt->label->nparts_max], last[cxt->label->nparts_max]; + DBG(LABEL, dbgprint("DOS: adding partition %d", n)); + sys = t ? t->type : MBR_LINUX_DATA_PARTITION; if (p && p->sys_ind) { @@ -951,6 +981,7 @@ static int add_partition(struct fdisk_context *cxt, int n, struct fdisk_parttype pe4->sectorbuffer = calloc(1, cxt->sector_size); if (!pe4->sectorbuffer) return -ENOMEM; + DBG(LABEL, dbgprint("DOS: add partition, sector buffer %p", pe4->sectorbuffer)); pe4->private_sectorbuffer = 1; pe4->pt_entry = mbr_get_partition(pe4->sectorbuffer, 0); pe4->ex_entry = pe4->pt_entry + 1; @@ -976,6 +1007,7 @@ static int add_logical(struct fdisk_context *cxt) pe->sectorbuffer = calloc(1, cxt->sector_size); if (!pe->sectorbuffer) return -ENOMEM; + DBG(LABEL, dbgprint("DOS: add logical, sector buffer %p", pe->sectorbuffer)); pe->private_sectorbuffer = 1; pe->pt_entry = mbr_get_partition(pe->sectorbuffer, 0); pe->ex_entry = pe->pt_entry + 1;