Mercurial > illumos > illumos-gate
changeset 10599:28d1f04d24a6
6826304 modload: sscanf unbounded copies should be constrained
6827539 pattern quote preprocessing fix in 6612207 too aggressive
6837756 SUNWdcopy postinstall script problem results in broken /etc/driver_aliases
6844097 Possible security issue w/add_drv et al using /tmp for lock files
6877673 add_drv fails with a permissions entry with a minor name including a comma
author | Jerry Gilliam <Jerry.Gilliam@Sun.COM> |
---|---|
date | Mon, 21 Sep 2009 18:02:54 -0700 |
parents | 6f30db2c2cd0 |
children | 687e6ace87ba |
files | usr/src/cmd/modload/add_drv.c usr/src/cmd/modload/addrem.h usr/src/cmd/modload/drvsubr.c usr/src/cmd/modload/errmsg.h usr/src/pkgdefs/SUNWad810/postinstall.tmpl usr/src/pkgdefs/SUNWadixp/postinstall.tmpl usr/src/pkgdefs/SUNWatge/postinstall.tmpl usr/src/pkgdefs/SUNWaudiocmi/postinstall.tmpl usr/src/pkgdefs/SUNWaudiols/postinstall.tmpl usr/src/pkgdefs/SUNWbfe/postinstall.tmpl usr/src/pkgdefs/SUNWdcopy/postinstall.tmpl usr/src/pkgdefs/SUNWfipe/postinstall.tmpl |
diffstat | 12 files changed, 265 insertions(+), 113 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/modload/add_drv.c Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/cmd/modload/add_drv.c Mon Sep 21 18:02:54 2009 -0700 @@ -538,8 +538,7 @@ char *driver_name, char *perm_list) { - return (append_to_file(driver_name, perm_list, minor_perm, - ',', ":", 0)); + return (append_to_minor_perm(driver_name, perm_list, minor_perm)); }
--- a/usr/src/cmd/modload/addrem.h Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/cmd/modload/addrem.h Mon Sep 21 18:02:54 2009 -0700 @@ -125,6 +125,7 @@ extern char *get_entry(char *, char *, char, int); extern int build_filenames(char *); extern int append_to_file(char *, char *, char *, char, char *, int); +extern int append_to_minor_perm(char *, char *, char *); extern int get_major_no(char *, char *); extern int get_driver_name(int, char *, char *); extern int delete_entry(char *, char *, char *, char *);
--- a/usr/src/cmd/modload/drvsubr.c Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/cmd/modload/drvsubr.c Mon Sep 21 18:02:54 2009 -0700 @@ -42,8 +42,26 @@ #include "errmsg.h" #include "plcysubr.h" +/* + * Macros to produce a quoted string containing the value of a + * preprocessor macro. For example, if SIZE is defined to be 256, + * VAL2STR(SIZE) is "256". This is used to construct format + * strings for scanf-family functions below. + * Note: For format string use, the argument to VAL2STR() must + * be a numeric constant that is one less than the size of the + * corresponding data buffer. + */ +#define VAL2STR_QUOTE(x) #x +#define VAL2STR(x) VAL2STR_QUOTE(x) + +/* + * Convenience macro to determine if a character is a quote + */ +#define isquote(c) (((c) == '"') || ((c) == '\'')) + + static char *add_rem_lock; /* lock file */ -static char *tmphold; /* temperary file for updating */ +static char *tmphold; /* temporary file for updating */ static int add_rem_lock_fd = -1; static int get_cached_n_to_m_file(char *filename, char ***cache); @@ -108,7 +126,7 @@ char *entry_separator, int quoted) { - int i, len, line_len; + int len, line_len; int fpint; char *current_head, *previous_head; char *line, *one_entry; @@ -149,24 +167,98 @@ */ do { - - for (i = 0; i <= len; i++) - one_entry[i] = 0; - + bzero(one_entry, len + 1); bzero(line, line_len); current_head = get_entry(previous_head, one_entry, list_separator, quoted); previous_head = current_head; - (void) strlcpy(line, driver_name, line_len); - (void) strlcat(line, entry_separator, line_len); - if (quoted) - (void) strlcat(line, "\"", line_len); - (void) strlcat(line, one_entry, line_len); - if (quoted) - (void) strlcat(line, "\"", line_len); - (void) strlcat(line, "\n", line_len); + (void) snprintf(line, line_len, + quoted ? "%s%s\"%s\"\n" : "%s%s%s\n", + driver_name, entry_separator, one_entry); + + if ((fputs(line, fp)) == EOF) { + perror(NULL); + (void) fprintf(stderr, gettext(ERR_NO_UPDATE), + filename); + } + + } while (*current_head != '\0'); + + + (void) fflush(fp); + + fpint = fileno(fp); + (void) fsync(fpint); + + (void) fclose(fp); + + free(one_entry); + free(line); + + return (NOERR); +} + +/* + * open file + * for each entry in list + * where list entries are separated by <list_separator> + * append entry : driver_name <entry_separator> entry + * close file + * return error/noerr + */ +int +append_to_minor_perm( + char *driver_name, + char *entry_list, + char *filename) +{ + int len, line_len; + int fpint; + char *current_head, *previous_head; + char *line, *one_entry; + FILE *fp; + + if ((fp = fopen(filename, "a")) == NULL) { + perror(NULL); + (void) fprintf(stderr, gettext(ERR_CANT_ACCESS_FILE), + filename); + return (ERROR); + } + + len = strlen(entry_list); + + one_entry = calloc(len + 1, 1); + if (one_entry == NULL) { + (void) fprintf(stderr, gettext(ERR_NO_UPDATE), filename); + (void) fprintf(stderr, gettext(ERR_NO_MEM)); + (void) fclose(fp); + return (ERROR); + } + + previous_head = entry_list; + + line_len = strlen(driver_name) + len + 4; + line = calloc(line_len, 1); + if (line == NULL) { + (void) fprintf(stderr, gettext(ERR_NO_MEM)); + (void) fclose(fp); + err_exit(); + } + + /* + * get one entry at a time from list and append to <filename> file + */ + do { + bzero(one_entry, len + 1); + bzero(line, line_len); + + current_head = get_perm_entry(previous_head, one_entry); + previous_head = current_head; + + (void) snprintf(line, line_len, "%s:%s\n", + driver_name, one_entry); if ((fputs(line, fp)) == EOF) { perror(NULL); @@ -201,7 +293,7 @@ int n; /* skip any leading white space */ - while (*line && ((*line == ' ') || (*line == '\t'))) + while (*line && isspace(*line)) line++; /* * Find separator for driver name, either space or colon @@ -213,14 +305,12 @@ return (0); token++; /* skip leading white space and quotes */ - while (*token && (*token == ' ' || *token == '\t' || - *token == '"' || *token == '\'')) + while (*token && (isspace(*token) || isquote(*token))) token++; /* strip trailing newline, white space and quotes */ n = strlen(token); p = token + n-1; - while (n > 0 && (*p == '\n' || *p == ' ' || *p == '\t' || - *p == '"' || *p == '\'')) { + while (n > 0 && (*p == '\n' || isspace(*p) || isquote(*p))) { *p-- = 0; n--; } @@ -256,7 +346,8 @@ int drvr_found = 0; boolean_t nomatch = B_TRUE; char *newfile, *tptr, *cp; - char line[MAX_DBFILE_ENTRY], drv[FILENAME_MAX + 1]; + char line[MAX_DBFILE_ENTRY]; + char drv[FILENAME_MAX + 1]; FILE *fp, *newfp; struct group *sysgrp; char *copy; /* same size as line */ @@ -269,7 +360,7 @@ */ if (match) { cp = match; - while (*cp && (*cp == '"' || *cp == '\'')) + while (*cp && (isspace(*cp))) cp++; i = strlen(cp); if (i > 0) { @@ -278,12 +369,11 @@ (void) fprintf(stderr, gettext(ERR_NO_MEM)); return (ERROR); } - if ((cp = strchr(match2, '\'')) != NULL) - *cp = 0; - if ((cp = strchr(match2, '"')) != NULL) - *cp = 0; - if ((cp = strchr(match2, ' ')) != NULL) - *cp = 0; + i = strlen(match2) - 1; + while (i >= 0 && (isspace(match2[i]))) { + match2[i] = 0; + i--; + } } if (match2 == NULL || (strlen(match2) == 0)) { (void) fprintf(stderr, @@ -351,8 +441,7 @@ } /* get the driver name */ - /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ - if (sscanf(copy, "%s", drv) != 1) { + if (sscanf(copy, "%" VAL2STR(FILENAME_MAX) "s", drv) != 1) { (void) fprintf(stderr, gettext(ERR_BAD_LINE), oldfile, line); status = ERROR; @@ -545,8 +634,10 @@ if (is_blank(line)) continue; /* sanity-check */ - /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ - if (sscanf(line, "%s%s", drv, entry) != 2) { + if (sscanf(line, + "%" VAL2STR(FILENAME_MAX) "s" /* drv */ + "%" VAL2STR(FILENAME_MAX) "s", /* entry */ + drv, entry) != 2) { (void) fprintf(stderr, gettext(ERR_BAD_LINE), filename, line); continue; @@ -587,8 +678,10 @@ if (is_blank(line)) continue; /* sanity-check */ - /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ - if (sscanf(line, "%s%s", drv, entry) != 2) { + if (sscanf(line, + "%" VAL2STR(FILENAME_MAX) "s" /* drv */ + "%" VAL2STR(FILENAME_MAX) "s", /* entry */ + drv, entry) != 2) { (void) fprintf(stderr, gettext(ERR_BAD_LINE), filename, line); continue; @@ -714,7 +807,7 @@ ptr = prev_member; /* skip white space */ - while (*ptr == '\t' || *ptr == ' ') + while (isspace(*ptr)) ptr++; /* if unquote skip leading quote */ @@ -725,8 +818,7 @@ /* read thru the current entry looking for end, separator, or unquote */ while (*ptr && - (*ptr != separator) && - ((separator != ' ') || (*ptr != '\t')) && + (*ptr != separator) && (!isspace(*ptr)) && (!quoted || (*ptr != '"'))) { *current_entry++ = *ptr++; } @@ -738,9 +830,56 @@ ptr++; /* skip over trailing quote */ /* skip white space */ - while (*ptr == '\t' || *ptr == ' ') { + while (isspace(*ptr)) ptr++; + + return (ptr); +} + +/* + * A parser specific to the add_drv "-m permission" syntax: + * + * -m '<minor-name> <permissions> <owner> <group>', ... + * + * One entry is parsed starting at prev_member and returned + * in the string pointed at by current_entry. A pointer + * to the entry following is returned. + */ +char * +get_perm_entry( + char *prev_member, + char *current_entry) +{ + char *ptr; + int nfields = 0; + int maxfields = 4; /* fields in a permissions format */ + + ptr = prev_member; + while (isspace(*ptr)) + ptr++; + + while (*ptr) { + /* comma allowed in minor name token only */ + if (*ptr == ',' && nfields > 0) { + break; + } else if (isspace(*ptr)) { + *current_entry++ = *ptr++; + while (isspace(*ptr)) + ptr++; + if (++nfields == maxfields) + break; + } else + *current_entry++ = *ptr++; } + *current_entry = '\0'; + + while (isspace(*ptr)) + ptr++; + if (*ptr == ',') { + ptr++; /* skip over optional trailing comma */ + } + while (isspace(*ptr)) + ptr++; return (ptr); } @@ -751,9 +890,11 @@ struct flock lock; /* - * attempt to create the lock file + * Attempt to create the lock file. Open the file itself, + * and not a symlink to some other file. */ - add_rem_lock_fd = open(add_rem_lock, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); + add_rem_lock_fd = open(add_rem_lock, + O_CREAT|O_RDWR|O_NOFOLLOW|O_NOLINKS, S_IRUSR|S_IWUSR); if (add_rem_lock_fd < 0) { (void) fprintf(stderr, gettext(ERR_CREAT_LOCK), add_rem_lock, strerror(errno)); @@ -1262,16 +1403,19 @@ int update_minor_entry(char *driver_name, char *perm_list) { - FILE *fp; - FILE *newfp; + FILE *fp; + FILE *newfp; + int match = 0; + char line[MAX_DBFILE_ENTRY]; + char drv[FILENAME_MAX + 1]; + char minor[FILENAME_MAX + 1]; + char perm[OPT_LEN + 1]; + char own[OPT_LEN + 1]; + char grp[OPT_LEN + 1]; + int status = NOERR, i; + char *newfile, *tptr; + char *cp, *dup, *drv_minor; struct group *sysgrp; - int match = 0; - char line[MAX_DBFILE_ENTRY], *cp, *dup; - char drv[FILENAME_MAX + 1], *drv_minor; - char minor[FILENAME_MAX + 1], perm[OPT_LEN + 1]; - char own[OPT_LEN + 1], grp[OPT_LEN + 1]; - int status = NOERR, i; - char *newfile, *tptr; if ((fp = fopen(minor_perm, "r")) == NULL) { perror(NULL); @@ -1308,8 +1452,12 @@ return (ERROR); } - /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ - if (sscanf(perm_list, "%s%s%s%s", minor, perm, own, grp) != 4) { + if (sscanf(perm_list, + "%" VAL2STR(FILENAME_MAX) "s" /* minor */ + "%" VAL2STR(OPT_LEN) "s" /* perm */ + "%" VAL2STR(OPT_LEN) "s" /* own */ + "%" VAL2STR(OPT_LEN) "s", /* grp */ + minor, perm, own, grp) != 4) { status = ERROR; } @@ -1336,8 +1484,7 @@ } /* get the driver name */ - /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ - if (sscanf(dup, "%s", drv) != 1) { + if (sscanf(dup, "%" VAL2STR(FILENAME_MAX) "s", drv) != 1) { (void) fprintf(stderr, gettext(ERR_BAD_LINE), minor_perm, line); status = ERROR; @@ -1483,8 +1630,7 @@ if (is_blank(line)) continue; /* sanity-check */ - /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ - if (sscanf(line, "%s", drv) != 1) { + if (sscanf(line, "%" VAL2STR(FILENAME_MAX) "s", drv) != 1) { (void) fprintf(stderr, gettext(ERR_BAD_LINE), oldfile, line); } @@ -1534,7 +1680,7 @@ char *current_head; char *previous_head; char *one_entry; - int i, len, scan_stat; + int len, scan_stat; char minor[FILENAME_MAX + 1]; char perm[OPT_LEN + 1]; char own[OPT_LEN + 1]; @@ -1543,14 +1689,10 @@ int status = NOERR; int intperm; - len = strlen(perm_list); - - if (len == 0) { + if ((len = strlen(perm_list)) == 0) return (ERROR); - } - one_entry = calloc(len + 1, 1); - if (one_entry == NULL) { + if ((one_entry = calloc(len + 1, 1)) == NULL) { (void) fprintf(stderr, gettext(ERR_NO_MEM)); return (ERROR); } @@ -1559,16 +1701,17 @@ current_head = perm_list; while (*current_head != '\0') { - - for (i = 0; i <= len; i++) - one_entry[i] = 0; - - current_head = get_entry(previous_head, one_entry, ',', 0); + bzero(one_entry, len + 1); + current_head = get_perm_entry(previous_head, one_entry); previous_head = current_head; - /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ - scan_stat = sscanf(one_entry, "%s%s%s%s%s", minor, perm, own, - grp, dumb); + scan_stat = sscanf(one_entry, + "%" VAL2STR(FILENAME_MAX) "s" /* minor */ + "%" VAL2STR(OPT_LEN) "s" /* perm */ + "%" VAL2STR(OPT_LEN) "s" /* own */ + "%" VAL2STR(OPT_LEN) "s" /* grp */ + "%" VAL2STR(OPT_LEN) "s", /* dumb */ + minor, perm, own, grp, dumb); if (scan_stat < 4) { (void) fprintf(stderr, gettext(ERR_MIS_TOK), @@ -1799,8 +1942,10 @@ if (is_blank(line)) continue; /* sanity-check */ - /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ - if (sscanf(line, "%s %s", drv, alias) != 2) + if (sscanf(line, + "%" VAL2STR(FILENAME_MAX) "s" /* drv */ + "%" VAL2STR(FILENAME_MAX) "s", /* alias */ + drv, alias) != 2) (void) fprintf(stderr, gettext(ERR_BAD_LINE), driver_aliases, line); @@ -1892,8 +2037,10 @@ if (is_blank(line)) continue; /* sanity-check */ - /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ - if (sscanf(line, "%s %s", drv, alias) != 2) + if (sscanf(line, + "%" VAL2STR(FILENAME_MAX) "s" /* drv */ + "%" VAL2STR(FILENAME_MAX) "s", /* alias */ + drv, alias) != 2) (void) fprintf(stderr, gettext(ERR_BAD_LINE), driver_aliases, line); @@ -2234,8 +2381,8 @@ if (is_blank(line)) continue; /* sanity-check */ - /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ - if (sscanf(line, "%s %llu", drv, &dnum) != 2) { + if (sscanf(line, + "%" VAL2STR(FILENAME_MAX) "s %llu", drv, &dnum) != 2) { (void) fprintf(stderr, gettext(ERR_BAD_LINE), filename, line); (void) fclose(fp);
--- a/usr/src/cmd/modload/errmsg.h Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/cmd/modload/errmsg.h Mon Sep 21 18:02:54 2009 -0700 @@ -100,8 +100,10 @@ "larger\nthan the maximum allowed value %u.\n" #define ERR_CREAT_LOCK "Failed to create lock file(%s): %s\n" +#define ERR_STAT_LOCK "Failed to stat lock file(%s): %s\n" #define ERR_LOCK "Failed to lock the lock file(%s): %s\n" #define ERR_UNLOCK "Failed to unlock the lock file(%s): %s\n" +#define ERR_OWNER_LOCK "Lock file(%s) not owned by user\n" #define ERR_LOCATION \ "Warning: %s-bit version of driver found at %s.\n"
--- a/usr/src/pkgdefs/SUNWad810/postinstall.tmpl Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/pkgdefs/SUNWad810/postinstall.tmpl Mon Sep 21 18:02:54 2009 -0700 @@ -28,28 +28,28 @@ include drv_utils I810_ALIASES="\ - \"pci1022,7445\" \ - \"pci1022,746d\" \ - \"pci1039,7012\" \ - \"pci8086,2415\" \ - \"pci8086,2425\" \ - \"pci8086,2445\" \ - \"pci8086,2485\" \ - \"pci8086,24c5\" \ - \"pci8086,24d5\" \ - \"pci8086,266e\" \ - \"pci8086,25a6\" \ - \"pci8086,2698\" \ - \"pci8086,27de\" \ - \"pci8086,7195\" \ - \"pci10de,1b1\" \ - \"pci10de,6a\" \ - \"pci10de,8a\" \ - \"pci10de,da\" \ - \"pci10de,ea\" \ - \"pci10de,59\" \ - \"pci10de,3a\" \ - \"pci10de,26b\" \ + '\"pci1022,7445\"' \ + '\"pci1022,746d\"' \ + '\"pci1039,7012\"' \ + '\"pci8086,2415\"' \ + '\"pci8086,2425\"' \ + '\"pci8086,2445\"' \ + '\"pci8086,2485\"' \ + '\"pci8086,24c5\"' \ + '\"pci8086,24d5\"' \ + '\"pci8086,266e\"' \ + '\"pci8086,25a6\"' \ + '\"pci8086,2698\"' \ + '\"pci8086,27de\"' \ + '\"pci8086,7195\"' \ + '\"pci10de,1b1\"' \ + '\"pci10de,6a\"' \ + '\"pci10de,8a\"' \ + '\"pci10de,da\"' \ + '\"pci10de,ea\"' \ + '\"pci10de,59\"' \ + '\"pci10de,3a\"' \ + '\"pci10de,26b\"' \ " pkg_drvadd -i "${I810_ALIASES}" audio810 || exit 1
--- a/usr/src/pkgdefs/SUNWadixp/postinstall.tmpl Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/pkgdefs/SUNWadixp/postinstall.tmpl Mon Sep 21 18:02:54 2009 -0700 @@ -33,9 +33,9 @@ # hardware to confirm with. # IXP_ALIASES="\ - \"pci1002,4370\" \ - \"pci1002,4361\" \ - \"pci1002,4341\" \ + '\"pci1002,4370\"' \ + '\"pci1002,4361\"' \ + '\"pci1002,4341\"' \ " pkg_drvadd -i "${IXP_ALIASES}" audioixp || exit 1
--- a/usr/src/pkgdefs/SUNWatge/postinstall.tmpl Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/pkgdefs/SUNWatge/postinstall.tmpl Mon Sep 21 18:02:54 2009 -0700 @@ -25,4 +25,4 @@ include drv_utils -pkg_drvadd -i "pciex1969,1026" atge || exit 1 +pkg_drvadd -i '"pciex1969,1026"' atge || exit 1
--- a/usr/src/pkgdefs/SUNWaudiocmi/postinstall.tmpl Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/pkgdefs/SUNWaudiocmi/postinstall.tmpl Mon Sep 21 18:02:54 2009 -0700 @@ -28,9 +28,9 @@ include drv_utils AUDIOCMI_ALIASES="\ - \"pci13f6,111\" \ - \"pci13f6,100\" \ - \"pci13f6,101\" \ + '\"pci13f6,111\"' \ + '\"pci13f6,100\"' \ + '\"pci13f6,101\"' \ " pkg_drvadd -i "${AUDIOCMI_ALIASES}" audiocmi || exit 1
--- a/usr/src/pkgdefs/SUNWaudiols/postinstall.tmpl Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/pkgdefs/SUNWaudiols/postinstall.tmpl Mon Sep 21 18:02:54 2009 -0700 @@ -28,7 +28,7 @@ include drv_utils AUDIOLS_ALIASES="\ - \"pci1102,7\" \ + '\"pci1102,7\"' \ " pkg_drvadd -i "${AUDIOLS_ALIASES}" audiols || exit 1
--- a/usr/src/pkgdefs/SUNWbfe/postinstall.tmpl Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/pkgdefs/SUNWbfe/postinstall.tmpl Mon Sep 21 18:02:54 2009 -0700 @@ -25,4 +25,4 @@ include drv_utils -pkg_drvadd -i "pci14e4,170c" bfe || exit 1 +pkg_drvadd -i '"pci14e4,170c"' bfe || exit 1
--- a/usr/src/pkgdefs/SUNWdcopy/postinstall.tmpl Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/pkgdefs/SUNWdcopy/postinstall.tmpl Mon Sep 21 18:02:54 2009 -0700 @@ -19,13 +19,16 @@ # # CDDL HEADER END # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # include drv_utils -CB1="pciex8086,1a38 pciex8086,360b" -CB2="pciex8086,402f" +CB_ALIASES="\ + '\"pciex8086,1a38\"' \ + '\"pciex8086,360b\"' \ + '\"pciex8086,402f\"' \ + " -pkg_drvadd -i "$CB1 $CB2" ioat || exit 1 +pkg_drvadd -i "${CB_ALIASES}" ioat || exit 1
--- a/usr/src/pkgdefs/SUNWfipe/postinstall.tmpl Mon Sep 21 16:47:51 2009 -0700 +++ b/usr/src/pkgdefs/SUNWfipe/postinstall.tmpl Mon Sep 21 18:02:54 2009 -0700 @@ -28,6 +28,6 @@ include drv_utils -FIPE_ALIAS="pci8086,360c pci8086,25f0" +FIPE_ALIAS="'\"pci8086,360c\"' '\"pci8086,25f0\"'" pkg_drvadd -i "$FIPE_ALIAS" fipe || exit 1