From 47ec069fb2d6d3b8d39dcb95e9d1a364d13679a1 Mon Sep 17 00:00:00 2001 From: yang_zhuang_zhuang <1162011203@qq.com> Date: Mon, 1 Mar 2021 18:47:22 +0800 Subject: [PATCH] Fix memleak in fdisk_script_read_file Fix heap-buffer-overflow in fdisk_partname Fix integer overflow in partno_from_devname --- ...isk-add-support-for-parttype-aliases.patch | 133 ++++ ...trutils-fix-floating-point-exception.patch | 24 + ...partition-type-aliases-and-shortcuts.patch | 642 ++++++++++++++++++ ...k-another-parse_line-nameval-cleanup.patch | 63 ++ ...o-from-255f5f4c770ebd46a38b58975bd33.patch | 24 + ...disk-make-fdisk_partname-more-robust.patch | 22 + ...don-t-use-sector-size-if-not-specifi.patch | 78 +++ ...isk-script-fix-possible-memory-leaks.patch | 75 ++ ...-script-fix-possible-partno-overflow.patch | 42 ++ ...-script-make-sure-label-is-specified.patch | 68 ++ ...ab-parser-for-badly-terminated-lines.patch | 66 ++ util-linux.spec | 19 +- 12 files changed, 1255 insertions(+), 1 deletion(-) create mode 100644 backport-fdisk-add-support-for-parttype-aliases.patch create mode 100644 backport-lib-strutils-fix-floating-point-exception.patch create mode 100644 backport-libfdisk-add-partition-type-aliases-and-shortcuts.patch create mode 100644 backport-libfdisk-another-parse_line-nameval-cleanup.patch create mode 100644 backport-libfdisk-fix-typo-from-255f5f4c770ebd46a38b58975bd33.patch create mode 100644 backport-libfdisk-make-fdisk_partname-more-robust.patch create mode 100644 backport-libfdisk-script-don-t-use-sector-size-if-not-specifi.patch create mode 100644 backport-libfdisk-script-fix-possible-memory-leaks.patch create mode 100644 backport-libfdisk-script-fix-possible-partno-overflow.patch create mode 100644 backport-libfdisk-script-make-sure-label-is-specified.patch create mode 100644 backport-libmount-fix-tab-parser-for-badly-terminated-lines.patch diff --git a/backport-fdisk-add-support-for-parttype-aliases.patch b/backport-fdisk-add-support-for-parttype-aliases.patch new file mode 100644 index 0000000..5645906 --- /dev/null +++ b/backport-fdisk-add-support-for-parttype-aliases.patch @@ -0,0 +1,133 @@ +From 006607abb5c0bc40f1f94da94abb14f0668d8205 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Tue, 3 Mar 2020 16:10:02 +0100 +Subject: [PATCH] fdisk: add support for parttype aliases + +* add list of supported aliases to 'l' and 'L' output +* support aliases in 't' dialog + +For example (use 'swap' to set 0x82 partition type): + + Command (m for help): t + Selected partition 1 + Hex code or alias (type L to list all): swap + Changed type of partition 'Linux' to 'Linux swap / Solaris'. + +Note that the aliases are evaluated as the last possibility if user's +input dues not match up with any partition type. This is necessary for +backward compatibility. + +This patch does NOT introduce shortcuts (.e.g. 'S' for swap) to +fdisk(8) due to collisions with already used dialog keys. + +Addresses: https://github.com/karelzak/util-linux/issues/958 +Signed-off-by: Karel Zak +--- + disk-utils/fdisk.c | 50 +++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 41 insertions(+), 9 deletions(-) + +diff --git a/disk-utils/fdisk.c b/disk-utils/fdisk.c +index a539c70ef..17d60b1a9 100644 +--- a/disk-utils/fdisk.c ++++ b/disk-utils/fdisk.c +@@ -480,9 +480,15 @@ static struct fdisk_parttype *ask_partition_type(struct fdisk_context *cxt, int + return NULL; + + *canceled = 0; +- q = fdisk_label_has_code_parttypes(lb) ? +- _("Hex code (type L to list all codes): ") : +- _("Partition type (type L to list all types): "); ++ ++ if (fdisk_label_has_parttypes_shortcuts(lb)) ++ q = fdisk_label_has_code_parttypes(lb) ? ++ _("Hex code or alias (type L to list all): ") : ++ _("Partition type or alias (type L to list all): "); ++ else ++ q = fdisk_label_has_code_parttypes(lb) ? ++ _("Hex code (type L to list all codes): ") : ++ _("Partition type (type L to list all types): "); + do { + char buf[256] = { '\0' }; + int rc = get_user_reply(q, buf, sizeof(buf)); +@@ -496,8 +502,10 @@ static struct fdisk_parttype *ask_partition_type(struct fdisk_context *cxt, int + if (buf[1] == '\0' && toupper(*buf) == 'L') + list_partition_types(cxt); + else if (*buf) { +- struct fdisk_parttype *t = fdisk_label_parse_parttype(lb, buf); +- ++ struct fdisk_parttype *t = fdisk_label_advparse_parttype(lb, buf, ++ FDISK_PARTTYPE_PARSE_DATA ++ | FDISK_PARTTYPE_PARSE_ALIAS ++ | FDISK_PARTTYPE_PARSE_SEQNUM); + if (!t) + fdisk_info(cxt, _("Failed to parse '%s' partition type."), buf); + return t; +@@ -510,8 +518,9 @@ static struct fdisk_parttype *ask_partition_type(struct fdisk_context *cxt, int + + void list_partition_types(struct fdisk_context *cxt) + { +- size_t ntypes = 0; ++ size_t ntypes = 0, next = 0; + struct fdisk_label *lb; ++ int pager = 0; + + assert(cxt); + lb = fdisk_get_label(cxt, NULL); +@@ -525,7 +534,7 @@ void list_partition_types(struct fdisk_context *cxt) + /* + * Prints in 4 columns in format + */ +- size_t last[4], done = 0, next = 0, size; ++ size_t last[4], done = 0, size; + int i; + + size = ntypes; +@@ -562,6 +571,7 @@ void list_partition_types(struct fdisk_context *cxt) + } + } while (done < last[0]); + ++ putchar('\n'); + } else { + /* + * Prints 1 column in format +@@ -569,6 +579,7 @@ void list_partition_types(struct fdisk_context *cxt) + size_t i; + + pager_open(); ++ pager = 1; + + for (i = 0; i < ntypes; i++) { + const struct fdisk_parttype *t = fdisk_label_get_parttype(lb, i); +@@ -577,9 +588,30 @@ void list_partition_types(struct fdisk_context *cxt) + fdisk_parttype_get_string(t)); + } + +- pager_close(); + } +- putchar('\n'); ++ ++ ++ /* ++ * Aliases ++ */ ++ if (fdisk_label_has_parttypes_shortcuts(lb)) { ++ const char *alias = NULL, *typestr = NULL; ++ int rc = 0; ++ ++ fputs(_("\nAliases:\n"), stdout); ++ ++ for (next = 0; rc == 0 || rc == 2; next++) { ++ /* rc: <0 error, 0 success, 1 end, 2 deprecated */ ++ rc = fdisk_label_get_parttype_shortcut(lb, ++ next, &typestr, NULL, &alias); ++ if (rc == 0) ++ printf(" %-14s - %s\n", alias, typestr); ++ } ++ } ++ ++ if (pager) ++ pager_close(); ++ + } + + void toggle_dos_compatibility_flag(struct fdisk_context *cxt) diff --git a/backport-lib-strutils-fix-floating-point-exception.patch b/backport-lib-strutils-fix-floating-point-exception.patch new file mode 100644 index 0000000..cdb8f1b --- /dev/null +++ b/backport-lib-strutils-fix-floating-point-exception.patch @@ -0,0 +1,24 @@ +From 1186cdf336e9d29089de54ff59dba6d2ee1bd803 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Tue, 28 Apr 2020 12:28:59 +0200 +Subject: [PATCH] lib/strutils: fix floating point exception + +Addresses: https://github.com/karelzak/util-linux/issues/1017 +Signed-off-by: Karel Zak +--- + lib/strutils.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/strutils.c b/lib/strutils.c +index e1629fb56..609ef0860 100644 +--- a/lib/strutils.c ++++ b/lib/strutils.c +@@ -195,7 +195,7 @@ int parse_size(const char *str, uintmax_t *res, int *power) + frac /= 10; /* remove last digit from frac */ + frac_poz *= 10; + +- if (seg) ++ if (seg && seg_div / seg) + x += frac_base / (seg_div / seg); + } while (frac); + } diff --git a/backport-libfdisk-add-partition-type-aliases-and-shortcuts.patch b/backport-libfdisk-add-partition-type-aliases-and-shortcuts.patch new file mode 100644 index 0000000..8d186fe --- /dev/null +++ b/backport-libfdisk-add-partition-type-aliases-and-shortcuts.patch @@ -0,0 +1,642 @@ +From f94e753b35cf7a8bdd3a27edb72e094917757334 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Tue, 3 Mar 2020 15:59:49 +0100 +Subject: [PATCH] libfdisk: add partition type aliases and shortcuts + +Now, the type shortcuts are supported for sfdisk scripts only. + +Unfortunately, the current implementation is not generic enough +and it's also fragile as 'E' shortcut is in collision with 0x0E +type for MBR. The another issue is 'L' which makes shortcuts useless +for fdisk where 'L' is used for another purpose in dialogs. + +This patch introduces partition type aliases as extension to +shortcuts. The definition of the shortcut is part of the label +definition and it's not more hardcoded in sfdisk script code. + +This patch also introduces 'Ex' shortcut as replacement for (now +deprecated) 'E'. + +Signed-off-by: Karel Zak +--- + libfdisk/src/dos.c | 16 +++ + libfdisk/src/fdiskP.h | 17 +++ + libfdisk/src/gpt.c | 13 ++ + libfdisk/src/libfdisk.h.in | 36 ++++++ + libfdisk/src/libfdisk.sym | 3 + + libfdisk/src/parttype.c | 236 ++++++++++++++++++++++++++++++------- + libfdisk/src/script.c | 94 ++------------- + 7 files changed, 291 insertions(+), 124 deletions(-) + +diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c +index ae06e179d..a79912e8b 100644 +--- a/libfdisk/src/dos.c ++++ b/libfdisk/src/dos.c +@@ -70,6 +70,18 @@ static struct fdisk_parttype dos_parttypes[] = { + #include "pt-mbr-partnames.h" + }; + ++static const struct fdisk_shortcut dos_parttype_cuts[] = ++{ ++ { .shortcut = "L", .alias = "linux", .data = "83" }, ++ { .shortcut = "S", .alias = "swap", .data = "82" }, ++ { .shortcut = "E", .alias = "extended", .data = "05", .deprecated = 1 }, /* collision with 0x0e type */ ++ { .shortcut = "Ex",.alias = "extended", .data = "05" }, /* MBR extended */ ++ { .shortcut = "U", .alias = "uefi", .data = "EF" }, /* UEFI system */ ++ { .shortcut = "R", .alias = "raid", .data = "FD" }, /* Linux RAID */ ++ { .shortcut = "V", .alias = "lvm", .data = "8E" }, /* LVM */ ++ { .shortcut = "X", .alias = "linuxex", .data = "85" } /* Linux extended */ ++}; ++ + #define set_hsc(h,s,c,sector) { \ + s = sector % cxt->geom.sectors + 1; \ + sector /= cxt->geom.sectors; \ +@@ -2556,8 +2568,12 @@ struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt __attribute__ + lb->name = "dos"; + lb->id = FDISK_DISKLABEL_DOS; + lb->op = &dos_operations; ++ + lb->parttypes = dos_parttypes; + lb->nparttypes = ARRAY_SIZE(dos_parttypes) - 1; ++ lb->parttype_cuts = dos_parttype_cuts; ++ lb->nparttype_cuts = ARRAY_SIZE(dos_parttype_cuts); ++ + lb->fields = dos_fields; + lb->nfields = ARRAY_SIZE(dos_fields); + +diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h +index ec07f1fc8..f291c08b6 100644 +--- a/libfdisk/src/fdiskP.h ++++ b/libfdisk/src/fdiskP.h +@@ -123,6 +123,17 @@ enum { + #define fdisk_parttype_is_invisible(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_INVISIBLE)) + #define fdisk_parttype_is_allocated(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_ALLOCATED)) + ++/* ++ * Shortcut (used for partition types) ++ */ ++struct fdisk_shortcut { ++ const char *shortcut; /* shortcut, usually one letter (e.h. "H") */ ++ const char *alias; /* human readable alias (e.g. "home") */ ++ const char *data; /* for example partition type */ ++ ++ unsigned int deprecated : 1; ++}; ++ + struct fdisk_partition { + int refcount; /* reference counter */ + +@@ -278,6 +289,9 @@ struct fdisk_label { + struct fdisk_parttype *parttypes; /* supported partitions types */ + size_t nparttypes; /* number of items in parttypes[] */ + ++ const struct fdisk_shortcut *parttype_cuts; /* partition type shortcuts */ ++ size_t nparttype_cuts; /* number of items in parttype_cuts */ ++ + size_t nparts_max; /* maximal number of partitions */ + size_t nparts_cur; /* number of currently used partitions */ + +@@ -519,4 +533,7 @@ int fdisk_do_wipe(struct fdisk_context *cxt); + int fdisk_has_wipe_area(struct fdisk_context *cxt, uint64_t start, uint64_t size); + int fdisk_check_collisions(struct fdisk_context *cxt); + ++/* parttype.c */ ++const char *fdisk_label_translate_type_shortcut(const struct fdisk_label *lb, char *cut); ++ + #endif /* _LIBFDISK_PRIVATE_H */ +diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c +index 4915b9a37..25555a395 100644 +--- a/libfdisk/src/gpt.c ++++ b/libfdisk/src/gpt.c +@@ -156,6 +156,16 @@ static struct fdisk_parttype gpt_parttypes[] = + #include "pt-gpt-partnames.h" + }; + ++static const struct fdisk_shortcut gpt_parttype_cuts[] = ++{ ++ { .shortcut = "L", .alias = "linux", .data = "0FC63DAF-8483-4772-8E79-3D69D8477DE4" }, /* Linux */ ++ { .shortcut = "S", .alias = "swap", .data = "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F" }, /* Swap */ ++ { .shortcut = "H", .alias = "home", .data = "933AC7E1-2EB4-4F13-B844-0E14E2AEF915" }, /* Home */ ++ { .shortcut = "U", .alias = "uefi", .data = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" }, /* UEFI system */ ++ { .shortcut = "R", .alias = "raid", .data = "A19D880F-05FC-4D3B-A006-743F0F84911E" }, /* Linux RAID */ ++ { .shortcut = "V", .alias = "lvm", .data = "E6D6D379-F507-44C2-A23C-238F2A3DF928" } /* LVM */ ++}; ++ + #define alignment_required(_x) ((_x)->grain != (_x)->sector_size) + + /* gpt_entry macros */ +@@ -3134,8 +3144,11 @@ struct fdisk_label *fdisk_new_gpt_label(struct fdisk_context *cxt __attribute__ + lb->name = "gpt"; + lb->id = FDISK_DISKLABEL_GPT; + lb->op = &gpt_operations; ++ + lb->parttypes = gpt_parttypes; + lb->nparttypes = ARRAY_SIZE(gpt_parttypes); ++ lb->parttype_cuts = gpt_parttype_cuts; ++ lb->nparttype_cuts = ARRAY_SIZE(gpt_parttype_cuts); + + lb->fields = gpt_fields; + lb->nfields = ARRAY_SIZE(gpt_fields); +diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in +index 89fad448e..bf05290f9 100644 +--- a/libfdisk/src/libfdisk.h.in ++++ b/libfdisk/src/libfdisk.h.in +@@ -264,7 +264,13 @@ int fdisk_parttype_set_typestr(struct fdisk_parttype *t, const char *str); + int fdisk_parttype_set_code(struct fdisk_parttype *t, int code); + size_t fdisk_label_get_nparttypes(const struct fdisk_label *lb); + struct fdisk_parttype *fdisk_label_get_parttype(const struct fdisk_label *lb, size_t n); ++int fdisk_label_get_parttype_shortcut( ++ const struct fdisk_label *lb, size_t n, ++ const char **typestr, ++ const char **shortcut, ++ const char **alias); + int fdisk_label_has_code_parttypes(const struct fdisk_label *lb); ++int fdisk_label_has_parttypes_shortcuts(const struct fdisk_label *lb); + struct fdisk_parttype *fdisk_label_get_parttype_from_code( + const struct fdisk_label *lb, + unsigned int code); +@@ -277,6 +283,36 @@ struct fdisk_parttype *fdisk_copy_parttype(const struct fdisk_parttype *type); + struct fdisk_parttype *fdisk_label_parse_parttype( + const struct fdisk_label *lb, + const char *str); ++struct fdisk_parttype *fdisk_label_advparse_parttype( ++ const struct fdisk_label *lb, ++ const char *str, ++ int flags); ++ ++/** ++ * fdisk_parttype_parser_flags: ++ * @FDISK_PARTTYPE_PARSE_DATA: parse hex or UUID from string ++ * @FDISK_PARTTYPE_PARSE_DATALAST: try hex or UUID as the last possibility (don't use!) ++ * @FDISK_PARTTYPE_PARSE_SHORTCUT: try input interpret as type shortcut (e.g 'L' for linux partition) ++ * @FDISK_PARTTYPE_PARSE_ALIAS: try input interpret as type alias (e.g. 'linux' for linux partition) ++ * @FDISK_PARTTYPE_PARSE_DEPRECATED: accept also deprecated aliases and shortcuts ++ * @FDISK_PARTTYPE_PARSE_DEFAULT: recommended flags for new code ++ * @FDISK_PARTTYPE_PARSE_NOUNKNOWN: ignore unknown types ++ */ ++enum fdisk_parttype_parser_flags { ++ FDISK_PARTTYPE_PARSE_DATA = (1 << 1), ++ FDISK_PARTTYPE_PARSE_DATALAST = (1 << 2), ++ FDISK_PARTTYPE_PARSE_SHORTCUT = (1 << 3), ++ FDISK_PARTTYPE_PARSE_ALIAS = (1 << 4), ++ FDISK_PARTTYPE_PARSE_DEPRECATED = (1 << 5), ++ FDISK_PARTTYPE_PARSE_NOUNKNOWN = (1 << 6), ++ FDISK_PARTTYPE_PARSE_SEQNUM = (1 << 7), ++ ++ FDISK_PARTTYPE_PARSE_DEFAULT = (FDISK_PARTTYPE_PARSE_DATA | \ ++ FDISK_PARTTYPE_PARSE_SHORTCUT | \ ++ FDISK_PARTTYPE_PARSE_ALIAS | \ ++ FDISK_PARTTYPE_PARSE_SEQNUM ) ++}; ++ + const char *fdisk_parttype_get_string(const struct fdisk_parttype *t); + unsigned int fdisk_parttype_get_code(const struct fdisk_parttype *t); + const char *fdisk_parttype_get_name(const struct fdisk_parttype *t); +diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym +index 96fcadd..4a5ba0b 100644 +--- a/libfdisk/src/libfdisk.sym ++++ b/libfdisk/src/libfdisk.sym +@@ -307,4 +307,7 @@ FDISK_2.33 { + FDISK_2.35 { + fdisk_script_set_table; + fdisk_assign_device_by_fd; ++ fdisk_label_has_parttypes_shortcuts; ++ fdisk_label_advparse_parttype; ++ fdisk_label_get_parttype_shortcut; + } FDISK_2.33; +diff --git a/libfdisk/src/parttype.c b/libfdisk/src/parttype.c +index d5ad434f0..36d12216d 100644 +--- a/libfdisk/src/parttype.c ++++ b/libfdisk/src/parttype.c +@@ -145,6 +145,41 @@ struct fdisk_parttype *fdisk_label_get_parttype(const struct fdisk_label *lb, si + return &lb->parttypes[n]; + } + ++/** ++ * fdisk_label_get_parttype_shortcut: ++ * @lb: label ++ * @n: number ++ * @typestr: returns type as string ++ * @shortcut: returns type shortcut string ++ * @alias: returns type alias string ++ * ++ * Returns: return 0 on success, <0 on error, 2 for deprecated alias, 1 for @n out of range ++ * ++ * Since: v2.36 ++ */ ++int fdisk_label_get_parttype_shortcut(const struct fdisk_label *lb, size_t n, ++ const char **typestr, const char **shortcut, const char **alias) ++{ ++ const struct fdisk_shortcut *sc; ++ ++ if (!lb) ++ return -EINVAL; ++ if (n >= lb->nparttype_cuts) ++ return 1; ++ ++ sc = &lb->parttype_cuts[n]; ++ if (typestr) ++ *typestr = sc->data; ++ if (shortcut) ++ *shortcut = sc->shortcut; ++ if (alias) ++ *alias = sc->alias; ++ ++ return sc->deprecated == 1 ? 2 : 0; ++ ++} ++ ++ + /** + * fdisk_label_has_code_parttypes: + * @lb: label +@@ -161,6 +196,20 @@ int fdisk_label_has_code_parttypes(const struct fdisk_label *lb) + return 1; + } + ++/** ++ * fdisk_label_has_parttypes_shortcuts ++ * @lb: label ++ * ++ * Returns: 1 if the label support shortuts/aliases for partition types or 0. ++ * ++ * Since: 2.36 ++ */ ++int fdisk_label_has_parttypes_shortcuts(const struct fdisk_label *lb) ++{ ++ assert(lb); ++ return lb->nparttype_cuts ? 1 : 0; ++} ++ + + /** + * fdisk_label_get_parttype_from_code: +@@ -266,79 +315,186 @@ struct fdisk_parttype *fdisk_copy_parttype(const struct fdisk_parttype *type) + return t; + } + +-/** +- * fdisk_label_parse_parttype: +- * @lb: label +- * @str: string to parse from +- * +- * Parses partition type from @str according to the label. The function returns +- * a pointer to static table of the partition types, or newly allocated +- * partition type for unknown types (see fdisk_parttype_is_unknown(). It's +- * safe to call fdisk_unref_parttype() for all results. +- * +- * Returns: pointer to type or NULL on error. +- */ +-struct fdisk_parttype *fdisk_label_parse_parttype( ++static struct fdisk_parttype *parttype_from_data( + const struct fdisk_label *lb, +- const char *str) ++ const char *str, ++ unsigned int *xcode, ++ int use_seqnum) + { + struct fdisk_parttype *types, *ret = NULL; + char *end = NULL; + + assert(lb); ++ assert(str); + ++ if (xcode) ++ *xcode = 0; + if (!lb->nparttypes) + return NULL; + +- DBG(LABEL, ul_debugobj(lb, "parsing '%s' (%s) partition type", +- str, lb->name)); ++ DBG(LABEL, ul_debugobj(lb, " parsing '%s' data", str)); + types = lb->parttypes; + + if (types[0].typestr == NULL) { +- unsigned int code = 0; ++ unsigned int code; + +- DBG(LABEL, ul_debugobj(lb, " parsing hex")); ++ DBG(LABEL, ul_debugobj(lb, " +hex")); + + errno = 0; + code = strtol(str, &end, 16); + + if (errno || *end != '\0') { +- DBG(LABEL, ul_debugobj(lb, "parsing failed: %m")); ++ DBG(LABEL, ul_debugobj(lb, " failed: %m")); + return NULL; + } ++ if (xcode) ++ *xcode = code; + ret = fdisk_label_get_parttype_from_code(lb, code); +- if (ret) +- goto done; +- +- ret = fdisk_new_unknown_parttype(code, NULL); + } else { +- int i; +- +- DBG(LABEL, ul_debugobj(lb, " parsing string")); ++ DBG(LABEL, ul_debugobj(lb, " +string")); + + /* maybe specified by type string (e.g. UUID) */ + ret = fdisk_label_get_parttype_from_string(lb, str); +- if (ret) +- goto done; + +- /* maybe specified by order number */ +- errno = 0; +- i = strtol(str, &end, 0); +- if (errno == 0 && *end == '\0' && i > 0 +- && i - 1 < (int) lb->nparttypes) { +- ret = &types[i - 1]; +- goto done; +- } ++ if (!ret) { ++ /* maybe specified by order number */ ++ int i; ++ ++ errno = 0; ++ i = strtol(str, &end, 0); + +- ret = fdisk_new_unknown_parttype(0, str); ++ if (use_seqnum && errno == 0 ++ && *end == '\0' && i > 0 ++ && i - 1 < (int) lb->nparttypes) ++ ret = &types[i - 1]; ++ } + } + +-done: +- DBG(PARTTYPE, ul_debugobj(ret, "returns parsed '%s' [%s] partition type", +- ret->name, ret->typestr ? : "")); ++ if (ret) ++ DBG(PARTTYPE, ul_debugobj(ret, " result '%s'", ret->name)); + return ret; + } + ++static struct fdisk_parttype *parttype_from_shortcut( ++ const struct fdisk_label *lb, ++ const char *str, int deprecated) ++{ ++ size_t i; ++ ++ DBG(LABEL, ul_debugobj(lb, " parsing '%s' shortcut", str)); ++ ++ for (i = 0; i < lb->nparttype_cuts; i++) { ++ const struct fdisk_shortcut *sc = &lb->parttype_cuts[i]; ++ ++ if (sc->deprecated && !deprecated) ++ continue; ++ if (sc->shortcut && strcmp(sc->shortcut, str) == 0) ++ return parttype_from_data(lb, sc->data, NULL, 0); ++ } ++ return NULL; ++} ++ ++static struct fdisk_parttype *parttype_from_alias( ++ const struct fdisk_label *lb, ++ const char *str, int deprecated) ++{ ++ size_t i; ++ ++ DBG(LABEL, ul_debugobj(lb, " parsing '%s' alias", str)); ++ ++ for (i = 0; i < lb->nparttype_cuts; i++) { ++ const struct fdisk_shortcut *sc = &lb->parttype_cuts[i]; ++ ++ if (sc->deprecated && !deprecated) ++ continue; ++ if (sc->alias && strcmp(sc->alias, str) == 0) ++ return parttype_from_data(lb, sc->data, NULL, 0); ++ } ++ return NULL; ++} ++ ++/** ++ * fdisk_label_advparse_parttype: ++ * @lb: label ++ * @str: string to parse from ++ * @flags: FDISK_PARTTYPE_PARSE_* ++ * ++ * This function is advanced partition types parser. It parses partition type ++ * from @str according to the label. The function returns a pointer to static ++ * table of the partition types, or newly allocated partition type for unknown ++ * types (see fdisk_parttype_is_unknown(). It's safe to call fdisk_unref_parttype() ++ * for all results. ++ * ++ * The @str may be type data (hex code or UUID), alias or shortcut. For GPT ++ * also sequence number of the type in the list of the supported types. ++ * ++ * Returns: pointer to type or NULL on error. ++ */ ++struct fdisk_parttype *fdisk_label_advparse_parttype( ++ const struct fdisk_label *lb, ++ const char *str, ++ int flags) ++{ ++ struct fdisk_parttype *res = NULL; ++ unsigned int code = 0; ++ ++ if (!lb->nparttypes) ++ return NULL; ++ ++ DBG(LABEL, ul_debugobj(lb, "parsing '%s' (%s) type", str, lb->name)); ++ ++ if ((flags & FDISK_PARTTYPE_PARSE_DATA) ++ && !(flags & FDISK_PARTTYPE_PARSE_DATALAST)) ++ res = parttype_from_data(lb, str, &code, ++ flags & FDISK_PARTTYPE_PARSE_SEQNUM); ++ ++ if (!res && (flags & FDISK_PARTTYPE_PARSE_ALIAS)) ++ res = parttype_from_alias(lb, str, ++ flags & FDISK_PARTTYPE_PARSE_DEPRECATED); ++ ++ if (!res && (flags & FDISK_PARTTYPE_PARSE_SHORTCUT)) ++ res = parttype_from_shortcut(lb, str, ++ flags & FDISK_PARTTYPE_PARSE_DEPRECATED); ++ ++ if (!res && (flags & FDISK_PARTTYPE_PARSE_DATA) ++ && (flags & FDISK_PARTTYPE_PARSE_DATALAST)) ++ res = parttype_from_data(lb, str, &code, ++ flags & FDISK_PARTTYPE_PARSE_SEQNUM); ++ ++ if (!res && !(flags & FDISK_PARTTYPE_PARSE_NOUNKNOWN)) { ++ if (lb->parttypes[0].typestr) ++ res = fdisk_new_unknown_parttype(0, str); ++ else ++ res = fdisk_new_unknown_parttype(code, NULL); ++ } ++ ++ if (res) ++ DBG(PARTTYPE, ul_debugobj(res, "returns parsed '%s' [%s] partition type", ++ res->name, res->typestr ? : "")); ++ return res; ++} ++ ++/** ++ * fdisk_label_parse_parttype: ++ * @lb: label ++ * @str: string to parse from (type name, UUID, etc.) ++ * ++ * Parses partition type from @str according to the label. The function returns ++ * a pointer to static table of the partition types, or newly allocated ++ * partition type for unknown types (see fdisk_parttype_is_unknown(). It's ++ * safe to call fdisk_unref_parttype() for all results. ++ * ++ * Note that for GPT it accepts sequence number of UUID. ++ * ++ * Returns: pointer to type or NULL on error. ++ */ ++struct fdisk_parttype *fdisk_label_parse_parttype( ++ const struct fdisk_label *lb, ++ const char *str) ++{ ++ return fdisk_label_advparse_parttype(lb, str, FDISK_PARTTYPE_PARSE_DATA); ++} ++ + /** + * fdisk_parttype_get_string: + * @t: type +diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c +index 6f66f88b9..e73c8dcdb 100644 +--- a/libfdisk/src/script.c ++++ b/libfdisk/src/script.c +@@ -61,9 +61,6 @@ struct fdisk_script { + force_label : 1; /* label: specified */ + }; + +-static struct fdisk_parttype *translate_type_shortcuts(struct fdisk_script *dp, char *str); +- +- + static void fdisk_script_free_header(struct fdisk_scriptheader *fi) + { + if (!fi) +@@ -969,6 +966,11 @@ static int partno_from_devname(char *s) + return pno - 1; + } + ++#define FDISK_SCRIPT_PARTTYPE_PARSE_FLAGS \ ++ (FDISK_PARTTYPE_PARSE_DATA | FDISK_PARTTYPE_PARSE_DATALAST | \ ++ FDISK_PARTTYPE_PARSE_SHORTCUT | FDISK_PARTTYPE_PARSE_ALIAS | \ ++ FDISK_PARTTYPE_PARSE_DEPRECATED) ++ + /* dump format + * : start=, size=, type=, ... + */ +@@ -1069,19 +1071,14 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) + if (rc) + break; + +- pa->type = translate_type_shortcuts(dp, type); +- if (!pa->type) +- pa->type = fdisk_label_parse_parttype( +- script_get_label(dp), type); ++ pa->type = fdisk_label_advparse_parttype(script_get_label(dp), ++ type, FDISK_SCRIPT_PARTTYPE_PARSE_FLAGS); + free(type); + + if (!pa->type) { + rc = -EINVAL; +- fdisk_unref_parttype(pa->type); +- pa->type = NULL; + break; + } +- + } else { + DBG(SCRIPT, ul_debugobj(dp, "script parse error: unknown field '%s'", p)); + rc = -EINVAL; +@@ -1098,71 +1095,6 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) + return rc; + } + +-/* original sfdisk supports partition types shortcuts like 'L' = Linux native +- */ +-static struct fdisk_parttype *translate_type_shortcuts(struct fdisk_script *dp, char *str) +-{ +- struct fdisk_label *lb; +- const char *type = NULL; +- +- if (strlen(str) != 1) +- return NULL; +- +- lb = script_get_label(dp); +- if (!lb) +- return NULL; +- +- if (lb->id == FDISK_DISKLABEL_DOS) { +- switch (*str) { +- case 'L': /* Linux */ +- type = "83"; +- break; +- case 'S': /* Swap */ +- type = "82"; +- break; +- case 'E': /* Dos extended */ +- type = "05"; +- break; +- case 'X': /* Linux extended */ +- type = "85"; +- break; +- case 'U': /* UEFI system */ +- type = "EF"; +- break; +- case 'R': /* Linux RAID */ +- type = "FD"; +- break; +- case 'V': /* LVM */ +- type = "8E"; +- break; +- +- } +- } else if (lb->id == FDISK_DISKLABEL_GPT) { +- switch (*str) { +- case 'L': /* Linux */ +- type = "0FC63DAF-8483-4772-8E79-3D69D8477DE4"; +- break; +- case 'S': /* Swap */ +- type = "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F"; +- break; +- case 'H': /* Home */ +- type = "933AC7E1-2EB4-4F13-B844-0E14E2AEF915"; +- break; +- case 'U': /* UEFI system */ +- type = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"; +- break; +- case 'R': /* Linux RAID */ +- type = "A19D880F-05FC-4D3B-A006-743F0F84911E"; +- break; +- case 'V': /* LVM */ +- type = "E6D6D379-F507-44C2-A23C-238F2A3DF928"; +- break; +- } +- } +- +- return type ? fdisk_label_parse_parttype(lb, type) : NULL; +-} +- + #define TK_PLUS 1 + #define TK_MINUS -1 + +@@ -1257,18 +1189,12 @@ static int parse_line_valcommas(struct fdisk_script *dp, char *s) + if (rc) + break; + +- pa->type = translate_type_shortcuts(dp, str); +- if (!pa->type) +- pa->type = fdisk_label_parse_parttype( +- script_get_label(dp), str); ++ pa->type = fdisk_label_advparse_parttype(script_get_label(dp), ++ str, FDISK_SCRIPT_PARTTYPE_PARSE_FLAGS); + free(str); + +- if (!pa->type) { ++ if (!pa->type) + rc = -EINVAL; +- fdisk_unref_parttype(pa->type); +- pa->type = NULL; +- break; +- } + break; + case ITEM_BOOTABLE: + if (*p == ',' || *p == ';') diff --git a/backport-libfdisk-another-parse_line-nameval-cleanup.patch b/backport-libfdisk-another-parse_line-nameval-cleanup.patch new file mode 100644 index 0000000..5b3ac2d --- /dev/null +++ b/backport-libfdisk-another-parse_line-nameval-cleanup.patch @@ -0,0 +1,63 @@ +From d8f35960ae0daa5d8b8231d22a6e967f5fcadb31 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Thu, 13 Aug 2020 10:13:01 +0200 +Subject: [PATCH] libfdisk: another parse_line_nameval() cleanup + +--- + libfdisk/src/script.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c +index 81d425945..4d9835f59 100644 +--- a/libfdisk/src/script.c ++++ b/libfdisk/src/script.c +@@ -939,7 +939,7 @@ static int next_number(char **s, uint64_t *num, int *power) + + static int next_string(char **s, char **str) + { +- char *tk; ++ char *tk, *p = NULL; + int rc = -EINVAL; + + assert(s); +@@ -947,9 +947,11 @@ static int next_string(char **s, char **str) + + tk = next_token(s); + if (tk) { +- *str = strdup(tk); +- rc = !*str ? -ENOMEM : 0; ++ p = strdup(tk); ++ rc = p ? 0 : -ENOMEM; + } ++ ++ *str = p; + return rc; + } + +@@ -1086,18 +1088,19 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) + !strncasecmp(p, "Id=", 3)) { /* backward compatibility */ + char *type = NULL; + ++ fdisk_unref_parttype(pa->type); ++ pa->type = NULL; ++ + p += ((*p == 'I' || *p == 'i') ? 3 : 5); /* "Id=", "type=" */ + + rc = next_string(&p, &type); +- if (rc) +- break; +- +- fdisk_unref_parttype(pa->type); +- pa->type = fdisk_label_advparse_parttype(script_get_label(dp), ++ if (rc == 0) { ++ pa->type = fdisk_label_advparse_parttype(script_get_label(dp), + type, FDISK_SCRIPT_PARTTYPE_PARSE_FLAGS); ++ if (!pa->type) ++ rc = -EINVAL; ++ } + free(type); +- if (!pa->type) +- rc = -EINVAL; + } else { + DBG(SCRIPT, ul_debugobj(dp, "script parse error: unknown field '%s'", p)); + rc = -EINVAL; diff --git a/backport-libfdisk-fix-typo-from-255f5f4c770ebd46a38b58975bd33.patch b/backport-libfdisk-fix-typo-from-255f5f4c770ebd46a38b58975bd33.patch new file mode 100644 index 0000000..aedf120 --- /dev/null +++ b/backport-libfdisk-fix-typo-from-255f5f4c770ebd46a38b58975bd33.patch @@ -0,0 +1,24 @@ +From 3b87a9af494b4ecc2ed3aa544f1a2f8df6789354 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Wed, 12 Aug 2020 19:48:47 +0200 +Subject: [PATCH] libfdisk: fix typo from + 255f5f4c770ebd46a38b58975bd33e33ae87ed24 + +Signed-off-by: Karel Zak +--- + libfdisk/src/parttype.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libfdisk/src/parttype.c b/libfdisk/src/parttype.c +index ec5debca7..72c5e3613 100644 +--- a/libfdisk/src/parttype.c ++++ b/libfdisk/src/parttype.c +@@ -438,7 +438,7 @@ struct fdisk_parttype *fdisk_label_advparse_parttype( + struct fdisk_parttype *res = NULL; + unsigned int code = 0; + +- if (!lb || lb->nparttypes) ++ if (!lb || !lb->nparttypes) + return NULL; + + DBG(LABEL, ul_debugobj(lb, "parsing '%s' (%s) type", str, lb->name)); diff --git a/backport-libfdisk-make-fdisk_partname-more-robust.patch b/backport-libfdisk-make-fdisk_partname-more-robust.patch new file mode 100644 index 0000000..89990e8 --- /dev/null +++ b/backport-libfdisk-make-fdisk_partname-more-robust.patch @@ -0,0 +1,22 @@ +From 9f03ad60e58f7bdcac6a1046471a3374550ee384 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Thu, 13 Aug 2020 10:12:01 +0200 +Subject: [PATCH] libfdisk: make fdisk_partname() more robust + +--- + libfdisk/src/utils.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libfdisk/src/utils.c b/libfdisk/src/utils.c +index 6056e7f1f..38ad23393 100644 +--- a/libfdisk/src/utils.c ++++ b/libfdisk/src/utils.c +@@ -142,7 +142,7 @@ char *fdisk_partname(const char *dev, size_t partno) + + /* devfs kludge - note: fdisk partition names are not supposed + to equal kernel names, so there is no reason to do this */ +- if (strcmp(dev + w - 4, "disc") == 0) { ++ if (endswith(dev, "disc")) { + w -= 4; + p = "part"; + } diff --git a/backport-libfdisk-script-don-t-use-sector-size-if-not-specifi.patch b/backport-libfdisk-script-don-t-use-sector-size-if-not-specifi.patch new file mode 100644 index 0000000..a36a28e --- /dev/null +++ b/backport-libfdisk-script-don-t-use-sector-size-if-not-specifi.patch @@ -0,0 +1,78 @@ +From 8bbc11f12ffb7adfc188b7b8885e74d40bd54713 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Wed, 12 Aug 2020 15:59:38 +0200 +Subject: [PATCH] libfdisk: (script) don't use sector size if not specified + +This is probably bad script API use, but better be safe than sorry. + +Signed-off-by: Karel Zak +--- + libfdisk/src/script.c | 30 ++++++++++++++++++++++++------ + 1 file changed, 24 insertions(+), 6 deletions(-) + +diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c +index d18ba5737..2a3d1b818 100644 +--- a/libfdisk/src/script.c ++++ b/libfdisk/src/script.c +@@ -1032,8 +1032,13 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) + p += 6; + rc = next_number(&p, &num, &pow); + if (!rc) { +- if (pow) /* specified as */ ++ if (pow) { /* specified as */ ++ if (!dp->cxt->sector_size) { ++ rc = -EINVAL; ++ break; ++ } + num /= dp->cxt->sector_size; ++ } + fdisk_partition_set_start(pa, num); + fdisk_partition_start_follow_default(pa, 0); + } +@@ -1043,9 +1048,13 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) + p += 5; + rc = next_number(&p, &num, &pow); + if (!rc) { +- if (pow) /* specified as */ ++ if (pow) { /* specified as */ ++ if (!dp->cxt->sector_size) { ++ rc = -EINVAL; ++ break; ++ } + num /= dp->cxt->sector_size; +- else /* specified as number of sectors */ ++ } else /* specified as number of sectors */ + fdisk_partition_size_explicit(pa, 1); + fdisk_partition_set_size(pa, num); + fdisk_partition_end_follow_default(pa, 0); +@@ -1159,8 +1168,13 @@ static int parse_line_valcommas(struct fdisk_script *dp, char *s) + + rc = next_number(&p, &num, &pow); + if (!rc) { +- if (pow) /* specified as */ ++ if (pow) { /* specified as */ ++ if (!dp->cxt->sector_size) { ++ rc = -EINVAL; ++ break; ++ } + num /= dp->cxt->sector_size; ++ } + fdisk_partition_set_start(pa, num); + pa->movestart = sign == TK_MINUS ? FDISK_MOVE_DOWN : + sign == TK_PLUS ? FDISK_MOVE_UP : +@@ -1179,9 +1193,13 @@ static int parse_line_valcommas(struct fdisk_script *dp, char *s) + int pow = 0; + rc = next_number(&p, &num, &pow); + if (!rc) { +- if (pow) /* specified as */ ++ if (pow) { /* specified as */ ++ if (!dp->cxt->sector_size) { ++ rc = -EINVAL; ++ break; ++ } + num /= dp->cxt->sector_size; +- else /* specified as number of sectors */ ++ } else /* specified as number of sectors */ + fdisk_partition_size_explicit(pa, 1); + fdisk_partition_set_size(pa, num); + pa->resize = sign == TK_MINUS ? FDISK_RESIZE_REDUCE : diff --git a/backport-libfdisk-script-fix-possible-memory-leaks.patch b/backport-libfdisk-script-fix-possible-memory-leaks.patch new file mode 100644 index 0000000..87ad5ac --- /dev/null +++ b/backport-libfdisk-script-fix-possible-memory-leaks.patch @@ -0,0 +1,75 @@ +From 678d03cc8a9c665ba989b098a9be903ede72f554 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Thu, 13 Aug 2020 13:48:28 +0200 +Subject: [PATCH] libfdisk: (script) fix possible memory leaks + +Signed-off-by: Karel Zak +--- + libfdisk/src/script.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c +index 4d9835f59..74ff43b73 100644 +--- a/libfdisk/src/script.c ++++ b/libfdisk/src/script.c +@@ -640,6 +640,7 @@ static int write_file_json(struct fdisk_script *dp, FILE *f) + fputs("\"node\":", f); + fputs_quoted_json(p, f); + nvars++; ++ free(p); + } + + if (fdisk_partition_has_start(pa)) { +@@ -741,6 +742,7 @@ static int write_file_sfdisk(struct fdisk_script *dp, FILE *f) + if (p) { + DBG(SCRIPT, ul_debugobj(dp, "write %s entry", p)); + fprintf(f, "%s :", p); ++ free(p); + } else + fprintf(f, "%zu :", pa->partno + 1); + +@@ -1072,14 +1074,17 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) + + } else if (!strncasecmp(p, "attrs=", 6)) { + p += 6; ++ free(pa->attrs); + rc = next_string(&p, &pa->attrs); + + } else if (!strncasecmp(p, "uuid=", 5)) { + p += 5; ++ free(pa->uuid); + rc = next_string(&p, &pa->uuid); + + } else if (!strncasecmp(p, "name=", 5)) { + p += 5; ++ free(pa->name); + rc = next_string(&p, &pa->name); + if (!rc) + unhexmangle_string(pa->name); +@@ -1128,7 +1133,7 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) + static int parse_line_valcommas(struct fdisk_script *dp, char *s) + { + int rc = 0; +- char *p = s, *str; ++ char *p = s; + struct fdisk_partition *pa; + enum { ITEM_START, ITEM_SIZE, ITEM_TYPE, ITEM_BOOTABLE }; + int item = -1; +@@ -1213,6 +1218,9 @@ static int parse_line_valcommas(struct fdisk_script *dp, char *s) + } + break; + case ITEM_TYPE: ++ { ++ char *str = NULL; ++ + if (*p == ',' || *p == ';' || alone_sign(sign, p)) + break; /* use default type */ + +@@ -1227,6 +1235,7 @@ static int parse_line_valcommas(struct fdisk_script *dp, char *s) + if (!pa->type) + rc = -EINVAL; + break; ++ } + case ITEM_BOOTABLE: + if (*p == ',' || *p == ';') + break; diff --git a/backport-libfdisk-script-fix-possible-partno-overflow.patch b/backport-libfdisk-script-fix-possible-partno-overflow.patch new file mode 100644 index 0000000..b643797 --- /dev/null +++ b/backport-libfdisk-script-fix-possible-partno-overflow.patch @@ -0,0 +1,42 @@ +From 1f50296c0f2384f474e3bbd92926edea53c3bace Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Fri, 14 Aug 2020 11:13:50 +0200 +Subject: [PATCH] libfdisk: (script) fix possible partno overflow + +Addresses: https://oss-fuzz.com/testcase-detail/5740890480705536 +Signed-off-by: Karel Zak +--- + libfdisk/src/script.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c +index 74ff43b73..37a5a3edc 100644 +--- a/libfdisk/src/script.c ++++ b/libfdisk/src/script.c +@@ -959,7 +959,7 @@ static int next_string(char **s, char **str) + + static int partno_from_devname(char *s) + { +- int pno; ++ intmax_t num; + size_t sz; + char *end, *p; + +@@ -975,10 +975,15 @@ static int partno_from_devname(char *s) + return -1; + end = NULL; + errno = 0; +- pno = strtol(p, &end, 10); ++ num = strtol(p, &end, 10); + if (errno || !end || p == end) + return -1; +- return pno - 1; ++ ++ if (num < INT32_MIN || num > INT32_MAX) { ++ errno = ERANGE; ++ return -1; ++ } ++ return num - 1; + } + + #define FDISK_SCRIPT_PARTTYPE_PARSE_FLAGS \ diff --git a/backport-libfdisk-script-make-sure-label-is-specified.patch b/backport-libfdisk-script-make-sure-label-is-specified.patch new file mode 100644 index 0000000..2a01a28 --- /dev/null +++ b/backport-libfdisk-script-make-sure-label-is-specified.patch @@ -0,0 +1,68 @@ +From 255f5f4c770ebd46a38b58975bd33e33ae87ed24 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Wed, 12 Aug 2020 15:52:53 +0200 +Subject: [PATCH] libfdisk: (script) make sure label is specified + +and unref type if already specified (unlikely, but be paranoid) + +Signed-off-by: Karel Zak +--- + libfdisk/src/parttype.c | 2 +- + libfdisk/src/script.c | 10 ++++------ + 2 files changed, 5 insertions(+), 7 deletions(-) + +diff --git a/libfdisk/src/parttype.c b/libfdisk/src/parttype.c +index e3eb0cffa..ec5debca7 100644 +--- a/libfdisk/src/parttype.c ++++ b/libfdisk/src/parttype.c +@@ -438,7 +438,7 @@ struct fdisk_parttype *fdisk_label_advparse_parttype( + struct fdisk_parttype *res = NULL; + unsigned int code = 0; + +- if (!lb->nparttypes) ++ if (!lb || lb->nparttypes) + return NULL; + + DBG(LABEL, ul_debugobj(lb, "parsing '%s' (%s) type", str, lb->name)); +diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c +index 051fa326e..d18ba5737 100644 +--- a/libfdisk/src/script.c ++++ b/libfdisk/src/script.c +@@ -1075,7 +1075,7 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) + + } else if (!strncasecmp(p, "type=", 5) || + !strncasecmp(p, "Id=", 3)) { /* backward compatibility */ +- char *type; ++ char *type = NULL; + + p += ((*p == 'I' || *p == 'i') ? 3 : 5); /* "Id=", "type=" */ + +@@ -1083,14 +1083,12 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) + if (rc) + break; + ++ fdisk_unref_parttype(pa->type); + pa->type = fdisk_label_advparse_parttype(script_get_label(dp), + type, FDISK_SCRIPT_PARTTYPE_PARSE_FLAGS); + free(type); +- +- if (!pa->type) { ++ if (!pa->type) + rc = -EINVAL; +- break; +- } + } else { + DBG(SCRIPT, ul_debugobj(dp, "script parse error: unknown field '%s'", p)); + rc = -EINVAL; +@@ -1201,10 +1199,10 @@ static int parse_line_valcommas(struct fdisk_script *dp, char *s) + if (rc) + break; + ++ fdisk_unref_parttype(pa->type); + pa->type = fdisk_label_advparse_parttype(script_get_label(dp), + str, FDISK_SCRIPT_PARTTYPE_PARSE_FLAGS); + free(str); +- + if (!pa->type) + rc = -EINVAL; + break; diff --git a/backport-libmount-fix-tab-parser-for-badly-terminated-lines.patch b/backport-libmount-fix-tab-parser-for-badly-terminated-lines.patch new file mode 100644 index 0000000..e3dea87 --- /dev/null +++ b/backport-libmount-fix-tab-parser-for-badly-terminated-lines.patch @@ -0,0 +1,66 @@ +From 72f783d0ea5297e3fab22a93574aa63f421c5f69 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Mon, 17 Aug 2020 16:33:59 +0200 +Subject: [PATCH] libmount: fix tab parser for badly terminated lines + +Signed-off-by: Karel Zak +--- + libmount/src/tab_parse.c | 26 +++++++++++--------------- + 1 file changed, 11 insertions(+), 15 deletions(-) + +diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c +index fa2d31b81..329987bcb 100644 +--- a/libmount/src/tab_parse.c ++++ b/libmount/src/tab_parse.c +@@ -481,7 +481,7 @@ static int is_terminated_by_blank(const char *str) + if (p == str) + return 1; /* only '\n' */ + p--; +- while (p >= str && (*p == ' ' || *p == '\t')) ++ while (p > str && (*p == ' ' || *p == '\t')) + p--; + return *p == '\n' ? 1 : 0; + } +@@ -553,22 +553,16 @@ static int mnt_table_parse_next(struct libmnt_parser *pa, + pa->line++; + s = strchr(pa->buf, '\n'); + if (!s) { ++ DBG(TAB, ul_debugobj(tb, "%s:%zu: no final newline", ++ pa->filename, pa->line)); ++ + /* Missing final newline? Otherwise an extremely */ + /* long line - assume file was corrupted */ +- if (feof(pa->f)) { +- DBG(TAB, ul_debugobj(tb, +- "%s: no final newline", pa->filename)); +- s = strchr(pa->buf, '\0'); +- } else { +- DBG(TAB, ul_debugobj(tb, +- "%s:%zu: missing newline at line", +- pa->filename, pa->line)); +- goto err; +- } +- } ++ if (feof(pa->f)) ++ s = memchr(pa->buf, '\0', pa->bufsiz); + + /* comments parser */ +- if (tb->comms ++ } else if (tb->comms + && (tb->fmt == MNT_FMT_GUESS || tb->fmt == MNT_FMT_FSTAB) + && is_comment_line(pa->buf)) { + do { +@@ -584,9 +578,11 @@ static int mnt_table_parse_next(struct libmnt_parser *pa, + + } + ++ if (!s) ++ goto err; + *s = '\0'; +- if (--s >= pa->buf && *s == '\r') +- *s = '\0'; ++ if (s > pa->buf && *(s - 1) == '\r') ++ *(--s) = '\0'; + s = (char *) skip_blank(pa->buf); + } while (*s == '\0' || *s == '#'); + diff --git a/util-linux.spec b/util-linux.spec index 77d3a21..11d6d64 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -2,7 +2,7 @@ Name: util-linux Version: 2.35.2 -Release: 3 +Release: 4 Summary: A random collection of Linux utilities License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain URL: https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git @@ -40,6 +40,18 @@ Patch2: libmount-try-read-only-mount-on-write-protected-supe.patch Patch3: libmount-parser-fix-memory-leak-on-error-before-end-.patch Patch4: tests-Fix-mountpoint-test-failure-in-build-chroots.patch +Patch5: backport-libfdisk-add-partition-type-aliases-and-shortcuts.patch +Patch6: backport-fdisk-add-support-for-parttype-aliases.patch +Patch7: backport-lib-strutils-fix-floating-point-exception.patch +Patch8: backport-libfdisk-script-make-sure-label-is-specified.patch +Patch9: backport-libfdisk-script-don-t-use-sector-size-if-not-specifi.patch +Patch10: backport-libfdisk-fix-typo-from-255f5f4c770ebd46a38b58975bd33.patch +Patch11: backport-libfdisk-make-fdisk_partname-more-robust.patch +Patch12: backport-libfdisk-another-parse_line-nameval-cleanup.patch +Patch13: backport-libfdisk-script-fix-possible-memory-leaks.patch +Patch14: backport-libfdisk-script-fix-possible-partno-overflow.patch +Patch15: backport-libmount-fix-tab-parser-for-badly-terminated-lines.patch + Patch9000: Add-check-to-resolve-uname26-version-test-failed.patch %description @@ -385,6 +397,11 @@ fi %{_mandir}/man8/{swapoff.8*,swapon.8*,switch_root.8*,umount.8*,wdctl.8.gz,wipefs.8*,zramctl.8*} %changelog +* Mon Mar 1 2021 yangzhuangzhuang - 2.35.2-4 +- Fix memleak in fdisk_script_read_file + Fix heap-buffer-overflow in fdisk_partname + Fix integer overflow in partno_from_devname + * Mon Jan 18 2021 Liquor - 2.35.2-3 - Remove pam_console dependency -- Gitee