diff options
author | Jan Parcel <Jan.Parcel@Sun.COM> | 2010-05-10 14:25:28 -0700 |
---|---|---|
committer | Jan Parcel <Jan.Parcel@Sun.COM> | 2010-05-10 14:25:28 -0700 |
commit | 399f067736e659e2754e97190952abea40f1d0d6 (patch) | |
tree | 8cfd9e3973d6264b7ad1ee548beaa131e19ec9dc | |
parent | d618d68dcf9c6c8f2c1e2fbbd4de1de0cf30150e (diff) | |
download | illumos-gate-399f067736e659e2754e97190952abea40f1d0d6.tar.gz |
6946546 Fix for 6868082 devfsadm must rely on device_maps breaks add_allocatable on Trusted Extensions
-rw-r--r-- | usr/src/lib/libbsm/common/devalloc.c | 220 | ||||
-rw-r--r-- | usr/src/lib/libbsm/common/getdment.c | 35 |
2 files changed, 190 insertions, 65 deletions
diff --git a/usr/src/lib/libbsm/common/devalloc.c b/usr/src/lib/libbsm/common/devalloc.c index cdeaf322f3..f28f91766a 100644 --- a/usr/src/lib/libbsm/common/devalloc.c +++ b/usr/src/lib/libbsm/common/devalloc.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <stdlib.h> @@ -41,6 +40,7 @@ #include <syslog.h> #include <bsm/devices.h> #include <bsm/devalloc.h> +#include <tsol/label.h> #define DA_DEFS "/etc/security/tsol/devalloc_defaults" @@ -565,27 +565,92 @@ _build_defattrs(da_args *dargs, strentry_t **head_defent) } /* + * We have to handle the "standard" types in devlist differently than + * other devices, which are not covered by our auto-naming conventions. + * + * buf must be a buffer of size DA_MAX_NAME + 1 + */ +int +da_std_type(da_args *dargs, char *namebuf) +{ + char *type = dargs->devinfo->devtype; + int system_labeled; + + system_labeled = is_system_labeled(); + + /* check safely for sizes */ + if (strcmp(DA_AUDIO_TYPE, type) == 0) { + (void) strlcpy(namebuf, DA_AUDIO_NAME, DA_MAXNAME); + return (1); + } + if (strcmp(DA_CD_TYPE, type) == 0) { + if (system_labeled) + (void) strlcpy(namebuf, DA_CD_NAME, DA_MAXNAME); + else + (void) strlcpy(namebuf, DA_CD_TYPE, DA_MAXNAME); + return (1); + } + if (strcmp(DA_FLOPPY_TYPE, type) == 0) { + if (system_labeled) + (void) strlcpy(namebuf, DA_FLOPPY_NAME, DA_MAXNAME); + else + (void) strlcpy(namebuf, DA_FLOPPY_TYPE, DA_MAXNAME); + return (1); + } + if (strcmp(DA_TAPE_TYPE, type) == 0) { + if (system_labeled) + (void) strlcpy(namebuf, DA_TAPE_NAME, DA_MAXNAME); + else + (void) strlcpy(namebuf, DA_TAPE_TYPE, DA_MAXNAME); + return (1); + } + if (strcmp(DA_RMDISK_TYPE, type) == 0) { + (void) strlcpy(namebuf, DA_RMDISK_NAME, DA_MAXNAME); + return (1); + } + namebuf[0] = '\0'; + return (0); +} + +/* + * allocatable: returns + * -1 if no auths field, + * 0 if not allocatable (marked '*') + * 1 if not marked '*' + */ +static int +allocatable(da_args *dargs) +{ + + if (!dargs->devinfo->devauths) + return (-1); + if (strcmp("*", dargs->devinfo->devauths) == 0) + return (0); + return (1); +} + +/* * _rebuild_lists - * - * If dargs->optflag & DA_EVENT, does not assume the dargs list is - * complete or completely believable, since devfsadm caches - * ONLY what it has been exposed to via syseventd. + * If dargs->optflag & DA_EVENT, does not assume the dargs list is + * complete or completely believable, since devfsadm caches + * ONLY what it has been exposed to via syseventd. * * Cycles through all the entries in the /etc files, stores them - * in memory, takes note of device->dname numbers (i.e. rmdisk0, - * rmdisk12) + * in memory, takes note of device->dname numbers (e.g. rmdisk0, + * rmdisk12) * - * Cycles through again, adds dargs entry + * Cycles through again, adds dargs entry * with the name tname%d (lowest unused number for the device type) * to the list of things for the caller to write out to a file, - * IFF it is a new entry. + * IFF it is a new entry. * - * It is an error for it to already be there. + * It is an error for it to already be there, if it is allocatable. * * Add: - * Returns 0 if successful and 2 on error. - * Remove: - * Returns 0 if not found, 1 if found, 2 on error. + * Returns 0 if successful and 2 on error. + * Remove: + * Returns 0 if not found, 1 if found, 2 on error. */ static int _rebuild_lists(da_args *dargs, strentry_t **head_devallocp, @@ -597,12 +662,15 @@ _rebuild_lists(da_args *dargs, strentry_t **head_devallocp, strentry_t *tail_str; strentry_t *tmp_str; uint64_t tmp_bitmap = 0; - int tmp = 0; - char new_devname[DA_MAXNAME + 1]; - char errmsg[DA_MAXNAME + 1 + (PATH_MAX * 2) + 80]; + uint_t tmp = 0; char *realname; - int suffix = DA_MAX_DEVNO + 1; + int suffix; int found = 0; + int stdtype = 1; + int is_allocatable = 1; + char new_devname[DA_MAXNAME + 1]; + char defname[DA_MAXNAME + 1]; /* default name for type */ + char errmsg[DA_MAXNAME + 1 + (PATH_MAX * 2) + 80]; if (dargs->optflag & (DA_MAPS_ONLY | DA_ALLOC_ONLY)) return (2); @@ -610,11 +678,17 @@ _rebuild_lists(da_args *dargs, strentry_t **head_devallocp, if (dargs->optflag & DA_FORCE) return (2); + if (dargs->optflag & DA_ADD) { + stdtype = da_std_type(dargs, defname); + is_allocatable = allocatable(dargs); + } + /* read both files, maps first so we can compare actual devices */ /* build device_maps */ setdmapent(); while ((devmapp = getdmapent()) != NULL) { + suffix = DA_MAX_DEVNO + 1; if ((rc = dmap_matchtype(devmapp, dargs->devinfo->devtype)) == 1) { if (dargs->optflag & DA_REMOVE) { @@ -632,7 +706,9 @@ _rebuild_lists(da_args *dargs, strentry_t **head_devallocp, } if (strstr(realname, dargs->devinfo->devlist) != NULL) { - if (dargs->devinfo->devname != NULL) + /* if need to free and safe to free */ + if (dargs->devinfo->devname != NULL && + (dargs->optflag & DA_EVENT) != 0) free(dargs->devinfo->devname); dargs->devinfo->devname = strdup(devmapp->dmap_devname); @@ -650,19 +726,25 @@ _rebuild_lists(da_args *dargs, strentry_t **head_devallocp, if (rc == 0) { /* * Same type, different device. Record - * device suffix already in use. + * device suffix already in use, if + * applicable. */ - if (suffix > DA_MAX_DEVNO) { - freedmapent(devmapp); - enddmapent(); - return (2); - } - tmp_bitmap |= (uint64_t)(1LL << suffix); + if ((suffix < DA_MAX_DEVNO && + suffix != -1) && stdtype) + tmp_bitmap |= + (uint64_t)(1LL << suffix); + } else if ((rc == 1) && !is_allocatable) { + rc = 0; } else { /* - * Match on add is an error + * Match allocatable on add is an error * or mapping attempt returned error */ + (void) snprintf(errmsg, sizeof (errmsg), + "Cannot add %s on node %s", + dargs->devinfo->devtype, + devmapp->dmap_devname); + syslog(LOG_ERR, "%s", errmsg); freedmapent(devmapp); enddmapent(); return (2); @@ -670,8 +752,27 @@ _rebuild_lists(da_args *dargs, strentry_t **head_devallocp, } else /* add other transaction types as needed */ return (2); - - } /* if same type */ + } else if ((dargs->optflag & DA_ADD) && + (stdtype || is_allocatable) && + dmap_exact_dev(devmapp, dargs->devinfo->devlist, + &suffix)) { + /* + * no dups w/o DA_FORCE, even if type differs, + * if there is a chance this operation is + * machine-driven. The 5 "standard types" + * can be machine-driven adds, and tend to + * be allocatable. + */ + (void) snprintf(errmsg, sizeof (errmsg), + "Cannot add %s on node %s type %s", + dargs->devinfo->devtype, + devmapp->dmap_devname, + devmapp->dmap_devtype); + syslog(LOG_ERR, "%s", errmsg); + freedmapent(devmapp); + enddmapent(); + return (2); + } tmp_str = _dmap2strentry(devmapp); if (tmp_str == NULL) { @@ -700,11 +801,13 @@ _rebuild_lists(da_args *dargs, strentry_t **head_devallocp, if (dargs->optflag & DA_ADD) { + int len; /* - * Since we got here from an event, we know the stored - * devname is a useless guess, since the files had not - * been read when the name was chosen, and we don't keep - * them anywhere else that is sufficiently definitive. + * If we got here from an event, or from devfsadm, + * we know the stored devname is a useless guess, + * since the files had not been read when the name + * was chosen, and we don't keep them anywhere else + * that is sufficiently definitive. */ for (tmp = 0; tmp <= DA_MAX_DEVNO; tmp++) @@ -714,11 +817,22 @@ _rebuild_lists(da_args *dargs, strentry_t **head_devallocp, if (tmp > DA_MAX_DEVNO) return (2); - (void) snprintf(new_devname, DA_MAXNAME + 1, "%s%u", - dargs->devinfo->devtype, tmp); - if (dargs->devinfo->devname != NULL) - free(dargs->devinfo->devname); - dargs->devinfo->devname = strdup(new_devname); + /* + * Let the caller choose the name unless BOTH the name and + * device type one of: cdrom, floppy, audio, rmdisk, or tape. + * (or sr, fd for unlabeled) + */ + len = strlen(defname); + if (stdtype && + (strncmp(dargs->devinfo->devname, defname, len) == 0)) { + (void) snprintf(new_devname, DA_MAXNAME + 1, "%s%u", + defname, tmp); + /* if need to free and safe to free */ + if (dargs->devinfo->devname != NULL && + (dargs->optflag & DA_EVENT) != 0) + free(dargs->devinfo->devname); + dargs->devinfo->devname = strdup(new_devname); + } } /* @@ -772,6 +886,7 @@ _rebuild_lists(da_args *dargs, strentry_t **head_devallocp, return (0); /* Successful DA_ADD */ } + /* * _build_lists - * Cycles through all the entries, stores them in memory. removes entries @@ -784,6 +899,7 @@ _build_lists(da_args *dargs, strentry_t **head_devallocp, strentry_t **head_devmapp) { int rc = 0; + int found = 0; devalloc_t *devallocp; devmap_t *devmapp; strentry_t *tail_str; @@ -796,15 +912,7 @@ _build_lists(da_args *dargs, strentry_t **head_devallocp, setdaent(); while ((devallocp = getdaent()) != NULL) { rc = da_match(devallocp, dargs); - if (rc && dargs->optflag & DA_ADD && - !(dargs->optflag & DA_FORCE)) { - /* - * During DA_ADD, we keep an existing entry unless - * we have DA_FORCE set to override that entry. - */ - dargs->optflag |= DA_NO_OVERRIDE; - rc = 0; - } + /* if in _build_lists and DA_ADD is set, so is DA_FORCE */ if (rc == 0) { tmp_str = _da2strentry(dargs, devallocp); if (tmp_str == NULL) { @@ -820,7 +928,9 @@ _build_lists(da_args *dargs, strentry_t **head_devallocp, tail_str->se_next = tmp_str; tail_str = tmp_str; } - } + } else if (rc == 1) + found = 1; + freedaent(devallocp); } enddaent(); @@ -834,15 +944,6 @@ dmap_only: setdmapent(); while ((devmapp = getdmapent()) != NULL) { rc = dm_match(devmapp, dargs); - if (rc && dargs->optflag & DA_ADD && - !(dargs->optflag & DA_FORCE)) { - /* - * During DA_ADD, we keep an existing entry unless - * we have DA_FORCE set to override that entry. - */ - dargs->optflag |= DA_NO_OVERRIDE; - rc = 0; - } if (rc == 0) { tmp_str = _dmap2strentry(devmapp); if (tmp_str == NULL) { @@ -863,6 +964,9 @@ dmap_only: } enddmapent(); + /* later code cleanup may cause the use of "found" in other cases */ + if (dargs->optflag & DA_REMOVE) + return (found); return (rc); } @@ -1387,8 +1491,8 @@ da_update_defattrs(da_args *dargs) /* * da_update_device - * Writes existing entries and the SINGLE change requested by da_args, - * to device_allocate and device_maps. - * Returns 0 on success, -1 on error. + * to device_allocate and device_maps. + * Returns 0 on success, -1 on error. */ int da_update_device(da_args *dargs) diff --git a/usr/src/lib/libbsm/common/getdment.c b/usr/src/lib/libbsm/common/getdment.c index 35d22b4830..3f1953d956 100644 --- a/usr/src/lib/libbsm/common/getdment.c +++ b/usr/src/lib/libbsm/common/getdment.c @@ -19,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * */ #include <string.h> @@ -54,6 +54,7 @@ static struct _dmapbuff { devmap_t *dmap_interpret(char *, devmap_t *); static devmap_t *dmap_interpretf(char *, devmap_t *); static devmap_t *dmap_dlexpand(devmap_t *); +static int dmap_resolve_link(char *devpath, char **devfs_path); int dmap_matchdev(devmap_t *, char *); int dmap_matchname(devmap_t *, char *); @@ -284,9 +285,7 @@ getdmaptype(char *type) /* * dmap_match_one_dev - * Checks if the specified devmap_t contains strings - * for the same logical link as the device specified. - * This guarantees that the beginnings of a devlist build - * match a more-complete devlist for the same device. + * for the same link as the device specified. * * Returns 1 for a match, else returns 0. */ @@ -295,6 +294,9 @@ dmap_match_one_dev(devmap_t *dmap, char *dev) { char **dva; char *dv; + char *dmap_link; + char *dev_link; + char stage_link[PATH_MAX + 1]; if (dmap->dmap_devarray == NULL) return (0); @@ -303,6 +305,22 @@ dmap_match_one_dev(devmap_t *dmap, char *dev) if (strstr(dev, dv) != NULL) return (1); } + /* check if both refer to same physical device */ + (void) strncpy(stage_link, dmap->dmap_devarray[0], sizeof (stage_link)); + if (dmap_resolve_link(stage_link, &dmap_link) != 0) + return (0); + (void) strncpy(stage_link, dev, sizeof (stage_link)); + if (dmap_resolve_link(stage_link, &dev_link) != 0) { + free(dmap_link); + return (0); + } + if (strcmp(dev_link, dmap_link) == 0) { + free(dmap_link); + free(dev_link); + return (1); + } + free(dmap_link); + free(dev_link); return (0); } @@ -328,8 +346,11 @@ dmap_matchdev(devmap_t *dmap, char *dev) } /* - * Requires a match of the /dev/?dsk links, not just the logical devname + * Requires a match of the /dev/? links, not just the logical devname * Returns 1 for match found, 0 for match not found, 2 for invalid arguments. + * + * Also looks for an instance number at the end of the logical name, and + * puts instance or -1 into *num. */ int dmap_exact_dev(devmap_t *dmap, char *dev, int *num) @@ -341,7 +362,7 @@ dmap_exact_dev(devmap_t *dmap, char *dev, int *num) dv = dmap->dmap_devname; dv += strcspn(dmap->dmap_devname, "0123456789"); if (sscanf(dv, "%d", num) != 1) - return (2); + *num = -1; /* during some add processes, dev can be shorter than dmap */ return (dmap_match_one_dev(dmap, dev)); } |