Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/fs/udf Split out the raw to indexed partitioning code pr...



details:   https://anonhg.NetBSD.org/src/rev/b56302bbeb4f
branches:  trunk
changeset: 761238:b56302bbeb4f
user:      reinoud <reinoud%NetBSD.org@localhost>
date:      Fri Jan 21 20:36:53 2011 +0000

description:
Split out the raw to indexed partitioning code protecting against roque
implementations that use `ramdom' numbers for the physical partitions breaking
lots of implementations. Known curlpit is MicroSoft Windows 7.

Not only the partition mappings need to be protected against this but also the metadata partition files.

diffstat:

 sys/fs/udf/udf_subr.c |  61 ++++++++++++++++++++++++++++++++++----------------
 1 files changed, 41 insertions(+), 20 deletions(-)

diffs (133 lines):

diff -r 87289defc539 -r b56302bbeb4f sys/fs/udf/udf_subr.c
--- a/sys/fs/udf/udf_subr.c     Fri Jan 21 19:27:09 2011 +0000
+++ b/sys/fs/udf/udf_subr.c     Fri Jan 21 20:36:53 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_subr.c,v 1.110 2011/01/13 13:13:31 reinoud Exp $ */
+/* $NetBSD: udf_subr.c,v 1.111 2011/01/21 20:36:53 reinoud Exp $ */
 
 /*
  * Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -29,7 +29,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.110 2011/01/13 13:13:31 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.111 2011/01/21 20:36:53 reinoud Exp $");
 #endif /* not lint */
 
 
@@ -983,6 +983,28 @@
        return vpart_num;
 }
 
+
+/* 
+ * BUGALERT: some rogue implementations use random physical partition
+ * numbers to break other implementations so lookup the number.
+ */
+
+static uint16_t
+udf_find_raw_phys(struct udf_mount *ump, uint16_t raw_phys_part)
+{
+       struct part_desc *part;
+       uint16_t phys_part;
+
+       for (phys_part = 0; phys_part < UDF_PARTITIONS; phys_part++) {
+               part = ump->partitions[phys_part];
+               if (part == NULL)
+                       break;
+               if (udf_rw16(part->part_num) == raw_phys_part)
+                       break;
+       }
+       return phys_part;
+}
+
 /* --------------------------------------------------------------------- */
 
 /* we dont try to be smart; we just record the parts */
@@ -994,7 +1016,6 @@
 static int
 udf_process_vds_descriptor(struct udf_mount *ump, union dscrptr *dscr)
 {
-       struct part_desc *part;
        uint16_t phys_part, raw_phys_part;
 
        DPRINTF(VOLUMES, ("\tprocessing VDS descr %d\n",
@@ -1026,13 +1047,8 @@
                 * the number.
                 */
                raw_phys_part = udf_rw16(dscr->pd.part_num);
-               for (phys_part = 0; phys_part < UDF_PARTITIONS; phys_part++) {
-                       part = ump->partitions[phys_part];
-                       if (part == NULL)
-                               break;
-                       if (udf_rw16(part->part_num) == raw_phys_part)
-                               break;
-               }
+               phys_part = udf_find_raw_phys(ump, raw_phys_part);
+
                if (phys_part == UDF_PARTITIONS) {
                        free(dscr, M_UDFVOLD);
                        return EINVAL;
@@ -1839,7 +1855,6 @@
        /* struct udf_args *args = &ump->mount_args; */
        struct logvol_int_desc *lvint;
        struct udf_logvol_info *lvinfo;
-       struct part_desc *part;
        uint32_t n_pm, mt_l;
        uint8_t *pmap_pos;
        char *domain_name, *map_name;
@@ -1970,13 +1985,7 @@
                 * partition numbers to break other implementations so lookup
                 * the number.
                 */
-               for (phys_part = 0; phys_part < UDF_PARTITIONS; phys_part++) {
-                       part = ump->partitions[phys_part];
-                       if (part == NULL)
-                               continue;
-                       if (udf_rw16(part->part_num) == raw_phys_part)
-                               break;
-               }
+               phys_part = udf_find_raw_phys(ump, raw_phys_part);
 
                DPRINTF(VOLUMES, ("\t%d -> %d(%d) type %d\n", log_part,
                    raw_phys_part, phys_part, pmap_type));
@@ -3116,17 +3125,28 @@
        struct part_map_meta *pmm = &mapping->pmm;
        struct long_ad   icb_loc;
        struct vnode *vp;
+       uint16_t raw_phys_part, phys_part;
        int error;
 
+       /*
+        * BUGALERT: some rogue implementations use random physical
+        * partition numbers to break other implementations so lookup
+        * the number.
+        */
+
        /* extract our allocation parameters set up on format */
        ump->metadata_alloc_unit_size     = udf_rw32(mapping->pmm.alloc_unit_size);
        ump->metadata_alignment_unit_size = udf_rw16(mapping->pmm.alignment_unit_size);
        ump->metadata_flags = mapping->pmm.flags;
 
        DPRINTF(VOLUMES, ("Reading in Metadata files\n"));
-       icb_loc.loc.part_num = pmm->part_num;
+       raw_phys_part = udf_rw16(pmm->part_num);
+       phys_part = udf_find_raw_phys(ump, raw_phys_part);
+
+       icb_loc.loc.part_num = udf_rw16(phys_part);
+
+       DPRINTF(VOLUMES, ("Metadata file\n"));
        icb_loc.loc.lb_num   = pmm->meta_file_lbn;
-       DPRINTF(VOLUMES, ("Metadata file\n"));
        error = udf_get_node(ump, &icb_loc, &ump->metadata_node);
        if (ump->metadata_node) {
                vp = ump->metadata_node->vnode;
@@ -5309,6 +5329,7 @@
        /* garbage check: translate udf_node_icb_loc to sectornr */
        error = udf_translate_vtop(ump, node_icb_loc, &sector, &dummy);
        if (error) {
+               DPRINTF(NODE, ("\tcan't translate icb address!\n"));
                /* no use, this will fail anyway */
                mutex_exit(&ump->get_node_lock);
                return EINVAL;



Home | Main Index | Thread Index | Old Index