diff options
author | Shidokht Yadegari <Shidokht.Yadegari@Sun.COM> | 2010-02-23 11:23:12 -0800 |
---|---|---|
committer | Shidokht Yadegari <Shidokht.Yadegari@Sun.COM> | 2010-02-23 11:23:12 -0800 |
commit | c31fac72a0572e58d0f06438a238d835dee8ffa7 (patch) | |
tree | 0c870c1ee5febab9dbfef0fa9138fcbf7c291de9 | |
parent | 8932b28e77f9b7be3f2de9023636091c1fb9c06c (diff) | |
download | illumos-joyent-c31fac72a0572e58d0f06438a238d835dee8ffa7.tar.gz |
6660997 CMLB_LABEL should use ddi_driver_name(), not devi_binding_name
6768507 Array overrun in cmlb
6430011 division panic on a disk with reported capacity of less than 80k
6920774 issues with CMLB ioctl handling
-rw-r--r-- | usr/src/cmd/format/auto_sense.c | 8 | ||||
-rw-r--r-- | usr/src/uts/common/io/cmlb.c | 60 | ||||
-rw-r--r-- | usr/src/uts/common/sys/cmlb_impl.h | 4 |
3 files changed, 59 insertions, 13 deletions
diff --git a/usr/src/cmd/format/auto_sense.c b/usr/src/cmd/format/auto_sense.c index 27fb82520d..f96dd6146d 100644 --- a/usr/src/cmd/format/auto_sense.c +++ b/usr/src/cmd/format/auto_sense.c @@ -2280,7 +2280,13 @@ compute_chs_values(diskaddr_t total_capacity, diskaddr_t usable_capacity, { /* Unlabeled SCSI floppy device */ - if (total_capacity <= 0x1000) { + if (total_capacity < 160) { + /* Less than 80K */ + *nheadp = 1; + *pcylp = total_capacity; + *nsectp = 1; + return; + } else if (total_capacity <= 0x1000) { *nheadp = 2; *pcylp = 80; *nsectp = total_capacity / (80 * 2); diff --git a/usr/src/uts/common/io/cmlb.c b/usr/src/uts/common/io/cmlb.c index 62025c7cdf..54ac010bce 100644 --- a/usr/src/uts/common/io/cmlb.c +++ b/usr/src/uts/common/io/cmlb.c @@ -247,6 +247,12 @@ static i_ddi_prop_dyn_t cmlb_prop_dyn[] = { }; /* + * This implies an upper limit of 8192 GPT partitions + * in one transfer for GUID Partition Entry Array. + */ +len_t cmlb_tg_max_efi_xfer = 1024 * 1024; + +/* * External kernel interfaces */ extern struct mod_ops mod_miscops; @@ -359,9 +365,9 @@ static int cmlb_dkio_extpartinfo(struct cmlb_lun *cl, dev_t dev, caddr_t arg, #endif static void cmlb_dbg(uint_t comp, struct cmlb_lun *cl, const char *fmt, ...); -static void cmlb_v_log(dev_info_t *dev, char *label, uint_t level, +static void cmlb_v_log(dev_info_t *dev, const char *label, uint_t level, const char *fmt, va_list ap); -static void cmlb_log(dev_info_t *dev, char *label, uint_t level, +static void cmlb_log(dev_info_t *dev, const char *label, uint_t level, const char *fmt, ...); int @@ -431,7 +437,7 @@ cmlb_dbg(uint_t comp, struct cmlb_lun *cl, const char *fmt, ...) * so that this module does not depend on scsi module. */ static void -cmlb_log(dev_info_t *dev, char *label, uint_t level, const char *fmt, ...) +cmlb_log(dev_info_t *dev, const char *label, uint_t level, const char *fmt, ...) { va_list ap; @@ -441,7 +447,7 @@ cmlb_log(dev_info_t *dev, char *label, uint_t level, const char *fmt, ...) } static void -cmlb_v_log(dev_info_t *dev, char *label, uint_t level, const char *fmt, +cmlb_v_log(dev_info_t *dev, const char *label, uint_t level, const char *fmt, va_list ap) { static char name[256]; @@ -1067,10 +1073,10 @@ cmlb_partinfo(cmlb_handle_t cmlbhandle, int part, diskaddr_t *nblocksp, cl->cl_map[part].dkl_nblk; if (tagp != NULL) - if (cl->cl_cur_labeltype == CMLB_LABEL_EFI) - *tagp = V_UNASSIGNED; - else - *tagp = cl->cl_vtoc.v_part[part].p_tag; + *tagp = + ((cl->cl_cur_labeltype == CMLB_LABEL_EFI) || + (part >= NDKMAP)) ? V_UNASSIGNED : + cl->cl_vtoc.v_part[part].p_tag; rval = 0; } @@ -1813,7 +1819,13 @@ cmlb_convert_geometry(struct cmlb_lun *cl, diskaddr_t capacity, ASSERT(mutex_owned(CMLB_MUTEX(cl))); /* Unlabeled SCSI floppy device */ - if (capacity <= 0x1000) { + if (capacity < 160) { + /* Less than 80K */ + cl_g->dkg_nhead = 1; + cl_g->dkg_ncyl = capacity; + cl_g->dkg_nsect = 1; + return; + } else if (capacity <= 0x1000) { cl_g->dkg_nhead = 2; cl_g->dkg_ncyl = 80; cl_g->dkg_nsect = capacity / (cl_g->dkg_nhead * cl_g->dkg_ncyl); @@ -3300,7 +3312,12 @@ cmlb_build_default_label(struct cmlb_lun *cl, void *tg_cookie) cl->cl_g.dkg_nsect = cl->cl_blockcount; } } else { - if (cl->cl_blockcount <= 0x1000) { + if (cl->cl_blockcount < 160) { + /* Less than 80K */ + cl->cl_g.dkg_nhead = 1; + cl->cl_g.dkg_ncyl = cl->cl_blockcount; + cl->cl_g.dkg_nsect = 1; + } else if (cl->cl_blockcount <= 0x1000) { /* unlabeled SCSI floppy device */ cl->cl_g.dkg_nhead = 2; cl->cl_g.dkg_ncyl = 80; @@ -4081,6 +4098,12 @@ cmlb_dkio_get_extvtoc(struct cmlb_lun *cl, caddr_t arg, int flag, return (rval); } + +/* + * This routine implements the DKIOCGETEFI ioctl. This ioctl is currently + * used to read the GPT Partition Table Header (primary/backup), the GUID + * partition Entry Array (primary/backup), and the MBR. + */ static int cmlb_dkio_get_efi(struct cmlb_lun *cl, caddr_t arg, int flag, void *tg_cookie) { @@ -4094,6 +4117,9 @@ cmlb_dkio_get_efi(struct cmlb_lun *cl, caddr_t arg, int flag, void *tg_cookie) user_efi.dki_data = (void *)(uintptr_t)user_efi.dki_data_64; + if (user_efi.dki_length > cmlb_tg_max_efi_xfer) + return (EINVAL); + tgt_lba = user_efi.dki_lba; mutex_enter(CMLB_MUTEX(cl)); @@ -4884,6 +4910,12 @@ exit: return (rval); } +/* + * This routine implements the DKIOCSETEFI ioctl. This ioctl is currently + * used to write (or clear) the GPT Partition Table header (primary/backup) + * and GUID partition Entry Array (primary/backup). It is also used to write + * the Protective MBR. + */ static int cmlb_dkio_set_efi(struct cmlb_lun *cl, dev_t dev, caddr_t arg, int flag, void *tg_cookie) @@ -4902,6 +4934,9 @@ cmlb_dkio_set_efi(struct cmlb_lun *cl, dev_t dev, caddr_t arg, int flag, user_efi.dki_data = (void *)(uintptr_t)user_efi.dki_data_64; + if (user_efi.dki_length > cmlb_tg_max_efi_xfer) + return (EINVAL); + buffer = kmem_alloc(user_efi.dki_length, KM_SLEEP); if (ddi_copyin(user_efi.dki_data, buffer, user_efi.dki_length, flag)) { rval = EFAULT; @@ -5203,6 +5238,11 @@ cmlb_setup_default_geometry(struct cmlb_lun *cl, void *tg_cookie) cl->cl_g.dkg_ncyl = 1; cl->cl_g.dkg_nhead = 1; cl->cl_g.dkg_nsect = cl->cl_blockcount; + } else if (cl->cl_blockcount < 160) { + /* Less than 80K */ + cl->cl_g.dkg_nhead = 1; + cl->cl_g.dkg_ncyl = cl->cl_blockcount; + cl->cl_g.dkg_nsect = 1; } else if (cl->cl_blockcount <= 0x1000) { /* Needed for unlabeled SCSI floppies. */ cl->cl_g.dkg_nhead = 2; diff --git a/usr/src/uts/common/sys/cmlb_impl.h b/usr/src/uts/common/sys/cmlb_impl.h index 1927123457..47ee3ab7bd 100644 --- a/usr/src/uts/common/sys/cmlb_impl.h +++ b/usr/src/uts/common/sys/cmlb_impl.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -75,7 +75,7 @@ extern "C" { #define CMLB_MUTEX(cl) (&((cl)->cl_mutex)) #define CMLB_DEVINFO(cl) ((cl)->cl_devi) -#define CMLB_LABEL(cl) (DEVI(((cl)->cl_devi))->devi_binding_name) +#define CMLB_LABEL(cl) (ddi_driver_name((cl->cl_devi))) #define ISREMOVABLE(cl) (cl->cl_is_removable) |