diff options
Diffstat (limited to 'usr/src/uts')
-rw-r--r-- | usr/src/uts/common/c2/audit_io.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/fs/doorfs/door_sys.c | 37 | ||||
-rw-r--r-- | usr/src/uts/common/io/dls/dls_mgmt.c | 78 | ||||
-rw-r--r-- | usr/src/uts/common/sys/dls.h | 32 | ||||
-rw-r--r-- | usr/src/uts/common/sys/door.h | 10 | ||||
-rw-r--r-- | usr/src/uts/common/sys/door_data.h | 8 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/ml/modstubs.s | 1 | ||||
-rw-r--r-- | usr/src/uts/sparc/ml/modstubs.s | 1 |
8 files changed, 94 insertions, 76 deletions
diff --git a/usr/src/uts/common/c2/audit_io.c b/usr/src/uts/common/c2/audit_io.c index e498dcdd58..d18a9c9d6a 100644 --- a/usr/src/uts/common/c2/audit_io.c +++ b/usr/src/uts/common/c2/audit_io.c @@ -537,7 +537,8 @@ au_door_upcall(au_kcontext_t *kctx, au_dbuf_t *aubuf) retry = 0; mutex_enter(&(kctx->auk_svc_lock)); - if ((rc = door_upcall(kctx->auk_current_vp, &darg)) != 0) { + rc = door_upcall(kctx->auk_current_vp, &darg, NULL); + if (rc != 0) { mutex_exit(&(kctx->auk_svc_lock)); if (rc == EAGAIN) ticks_to_wait = AGAIN_TICKS; diff --git a/usr/src/uts/common/fs/doorfs/door_sys.c b/usr/src/uts/common/fs/doorfs/door_sys.c index 15aadeb415..bfb941f326 100644 --- a/usr/src/uts/common/fs/doorfs/door_sys.c +++ b/usr/src/uts/common/fs/doorfs/door_sys.c @@ -1639,10 +1639,18 @@ door_ucred(struct ucred_s *uch) DOOR_T_HOLD(ct); mutex_exit(&door_knob); - /* Get the credentials of the calling process */ p = ttoproc(caller); - res = pgetucred(p); + /* + * If the credentials are not specified by the client, get the one + * associated with the calling process. + */ + if (ct->d_cred == NULL) { + res = pgetucred(p); + } else { + res = cred2ucred(ct->d_cred, ct->d_upcall ? + p0.p_pid : p->p_pid, NULL, CRED()); + } mutex_enter(&door_knob); DOOR_T_RELEASE(ct); @@ -2114,7 +2122,7 @@ door_unref(void) dp->door_flags |= DOOR_UNREF_ACTIVE; mutex_exit(&door_knob); - (void) door_upcall(DTOV(dp), &unref_args); + (void) door_upcall(DTOV(dp), &unref_args, NULL); mutex_enter(&door_knob); ASSERT(dp->door_flags & DOOR_UNREF_ACTIVE); @@ -3005,10 +3013,11 @@ door_copy(struct as *as, caddr_t src, caddr_t dest, uint_t len) * in the event of an error, and passed without duplication * otherwise. Note that param->rbuf must be 64-bit aligned in * a 64-bit kernel, since it may be used to store door descriptors - * if they are returned by the server. + * if they are returned by the server. The caller is responsible + * for holding a reference to the cred passed in. */ int -door_upcall(vnode_t *vp, door_arg_t *param) +door_upcall(vnode_t *vp, door_arg_t *param, struct cred *cred) { /* Locals */ door_node_t *dp; @@ -3096,6 +3105,7 @@ door_upcall(vnode_t *vp, door_arg_t *param) } ct->d_upcall = 1; + ct->d_cred = cred; if (param->rsize == 0) ct->d_noresults = 1; else @@ -3253,6 +3263,7 @@ out: ct->d_fpp_size = 0; } + ct->d_cred = NULL; ct->d_upcall = 0; ct->d_noresults = 0; ct->d_buf = NULL; @@ -3304,17 +3315,29 @@ door_list_delete(door_node_t *dp) */ /* - * door_ki_upcall invokes a user-level door server from the kernel. + * door_ki_upcall invokes a user-level door server from the kernel, with + * the credentials associated with curthread. */ int door_ki_upcall(door_handle_t dh, door_arg_t *param) { + return (door_ki_upcall_cred(dh, param, NULL)); +} + +/* + * door_ki_upcall_cred invokes a user-level door server from the kernel with + * the given credentials. If the "cred" argument is NULL, uses the credentials + * associated with current thread. + */ +int +door_ki_upcall_cred(door_handle_t dh, door_arg_t *param, struct cred *cred) +{ file_t *fp = DHTOF(dh); vnode_t *realvp; if (VOP_REALVP(fp->f_vnode, &realvp, NULL)) realvp = fp->f_vnode; - return (door_upcall(realvp, param)); + return (door_upcall(realvp, param, cred)); } /* diff --git a/usr/src/uts/common/io/dls/dls_mgmt.c b/usr/src/uts/common/io/dls/dls_mgmt.c index aff6ba26b1..7a753b2341 100644 --- a/usr/src/uts/common/io/dls/dls_mgmt.c +++ b/usr/src/uts/common/io/dls/dls_mgmt.c @@ -200,12 +200,11 @@ i_dls_mgmt_door_revoked(door_handle_t dh) * Upcall to the datalink management daemon (dlmgmtd). */ static int -i_dls_mgmt_upcall(void *arg, size_t asize, void *rbuf, size_t *rsizep) +i_dls_mgmt_upcall(void *arg, size_t asize, void *rbuf, size_t rsize) { door_arg_t darg, save_arg; - struct dlmgmt_null_retval_s *retvalp; door_handle_t dh; - int err = EINVAL; + int err; int retry = 0; #define MAXRETRYNUM 3 @@ -216,7 +215,7 @@ i_dls_mgmt_upcall(void *arg, size_t asize, void *rbuf, size_t *rsizep) darg.desc_ptr = NULL; darg.desc_num = 0; darg.rbuf = rbuf; - darg.rsize = *rsizep; + darg.rsize = rsize; save_arg = darg; retry: @@ -231,7 +230,7 @@ retry: for (;;) { retry++; - if ((err = door_ki_upcall(dh, &darg)) == 0) + if ((err = door_ki_upcall_cred(dh, &darg, kcred)) == 0) break; /* @@ -283,19 +282,12 @@ retry: goto done; } - if (darg.rsize > *rsizep || darg.rsize < sizeof (uint_t)) { + if (darg.rsize != rsize) { err = EINVAL; goto done; } - /* LINTED E_BAD_PTR_CAST_ALIGN */ - retvalp = (struct dlmgmt_null_retval_s *)darg.rbuf; - if (retvalp->lr_err != 0) { - err = retvalp->lr_err; - goto done; - } - - *rsizep = darg.rsize; + err = ((dlmgmt_retval_t *)rbuf)->lr_err; done: door_ki_rele(dh); @@ -322,7 +314,6 @@ dls_mgmt_create(const char *devname, dev_t dev, datalink_class_t class, { dlmgmt_upcall_arg_create_t create; dlmgmt_create_retval_t retval; - size_t rsize; int err; create.ld_cmd = DLMGMT_CMD_DLS_CREATE; @@ -334,11 +325,10 @@ dls_mgmt_create(const char *devname, dev_t dev, datalink_class_t class, if (strlcpy(create.ld_devname, devname, MAXNAMELEN) >= MAXNAMELEN) return (EINVAL); - rsize = sizeof (retval); - - err = i_dls_mgmt_upcall(&create, sizeof (create), &retval, &rsize); - if (err == 0) + if ((err = i_dls_mgmt_upcall(&create, sizeof (create), &retval, + sizeof (retval))) == 0) { *linkidp = retval.lr_linkid; + } return (err); } @@ -351,14 +341,13 @@ dls_mgmt_destroy(datalink_id_t linkid, boolean_t persist) { dlmgmt_upcall_arg_destroy_t destroy; dlmgmt_destroy_retval_t retval; - size_t rsize; destroy.ld_cmd = DLMGMT_CMD_DLS_DESTROY; destroy.ld_linkid = linkid; destroy.ld_persist = persist; - rsize = sizeof (retval); - return (i_dls_mgmt_upcall(&destroy, sizeof (destroy), &retval, &rsize)); + return (i_dls_mgmt_upcall(&destroy, sizeof (destroy), + &retval, sizeof (retval))); } /* @@ -383,7 +372,6 @@ dls_mgmt_update(const char *devname, uint32_t media, boolean_t novanity, { dlmgmt_upcall_arg_update_t update; dlmgmt_update_retval_t retval; - size_t rsize; int err; update.ld_cmd = DLMGMT_CMD_DLS_UPDATE; @@ -393,10 +381,9 @@ dls_mgmt_update(const char *devname, uint32_t media, boolean_t novanity, update.ld_media = media; update.ld_novanity = novanity; - rsize = sizeof (retval); - err = i_dls_mgmt_upcall(&update, sizeof (update), &retval, &rsize); - if (err == EEXIST) { + if ((err = i_dls_mgmt_upcall(&update, sizeof (update), &retval, + sizeof (retval))) == EEXIST) { *linkidp = retval.lr_linkid; *mediap = retval.lr_media; } else if (err == 0) { @@ -419,16 +406,15 @@ dls_mgmt_get_linkinfo(datalink_id_t linkid, char *link, { dlmgmt_door_getname_t getname; dlmgmt_getname_retval_t retval; - size_t rsize; int err, len; getname.ld_cmd = DLMGMT_CMD_GETNAME; getname.ld_linkid = linkid; - rsize = sizeof (retval); - err = i_dls_mgmt_upcall(&getname, sizeof (getname), &retval, &rsize); - if (err != 0) + if ((err = i_dls_mgmt_upcall(&getname, sizeof (getname), &retval, + sizeof (retval))) != 0) { return (err); + } len = strlen(retval.lr_link); if (len <= 1 || len >= MAXLINKNAMELEN) @@ -455,17 +441,15 @@ dls_mgmt_get_linkid(const char *link, datalink_id_t *linkid) { dlmgmt_door_getlinkid_t getlinkid; dlmgmt_getlinkid_retval_t retval; - size_t rsize; int err; getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID; (void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN); - rsize = sizeof (retval); - err = i_dls_mgmt_upcall(&getlinkid, sizeof (getlinkid), &retval, - &rsize); - if (err == 0) + if ((err = i_dls_mgmt_upcall(&getlinkid, sizeof (getlinkid), &retval, + sizeof (retval))) == 0) { *linkid = retval.lr_linkid; + } return (err); } @@ -475,17 +459,17 @@ dls_mgmt_get_next(datalink_id_t linkid, datalink_class_t class, { dlmgmt_door_getnext_t getnext; dlmgmt_getnext_retval_t retval; - size_t rsize; getnext.ld_cmd = DLMGMT_CMD_GETNEXT; getnext.ld_class = class; getnext.ld_dmedia = dmedia; getnext.ld_flags = flags; getnext.ld_linkid = linkid; - rsize = sizeof (retval); - if (i_dls_mgmt_upcall(&getnext, sizeof (getnext), &retval, &rsize) != 0) + if (i_dls_mgmt_upcall(&getnext, sizeof (getnext), &retval, + sizeof (retval)) != 0) { return (DATALINK_INVALID_LINKID); + } return (retval.lr_linkid); } @@ -495,25 +479,21 @@ i_dls_mgmt_get_linkattr(const datalink_id_t linkid, const char *attr, void *attrval, size_t *attrszp) { dlmgmt_upcall_arg_getattr_t getattr; - dlmgmt_getattr_retval_t *retvalp; - size_t oldsize, size; + dlmgmt_getattr_retval_t retval; int err; getattr.ld_cmd = DLMGMT_CMD_DLS_GETATTR; getattr.ld_linkid = linkid; (void) strlcpy(getattr.ld_attr, attr, MAXLINKATTRLEN); - oldsize = size = *attrszp + sizeof (dlmgmt_getattr_retval_t) - 1; - retvalp = kmem_zalloc(oldsize, KM_SLEEP); - - err = i_dls_mgmt_upcall(&getattr, sizeof (getattr), retvalp, &size); - if (err == 0) { - ASSERT(size <= oldsize); - *attrszp = size + 1 - sizeof (dlmgmt_getattr_retval_t); - bcopy(retvalp->lr_attr, attrval, *attrszp); + if ((err = i_dls_mgmt_upcall(&getattr, sizeof (getattr), &retval, + sizeof (retval))) == 0) { + if (*attrszp < retval.lr_attrsz) + return (EINVAL); + *attrszp = retval.lr_attrsz; + bcopy(retval.lr_attrval, attrval, retval.lr_attrsz); } - kmem_free(retvalp, oldsize); return (err); } diff --git a/usr/src/uts/common/sys/dls.h b/usr/src/uts/common/sys/dls.h index 7b6954e2b4..20f556c86f 100644 --- a/usr/src/uts/common/sys/dls.h +++ b/usr/src/uts/common/sys/dls.h @@ -88,6 +88,7 @@ typedef uint64_t datalink_media_t; B_TRUE : ((uint32_t)((dmedia) & 0xfffffffful) == (media))) #define MAXLINKATTRLEN 32 +#define MAXLINKATTRVALLEN 1024 /* * Link attributes used by the kernel. @@ -131,6 +132,10 @@ typedef uint64_t datalink_media_t; #define DLMGMT_PERSIST 0x02 /* upcall argument */ +typedef struct dlmgmt_door_arg { + uint_t ld_cmd; +} dlmgmt_door_arg_t; + typedef struct dlmgmt_upcall_arg_create { int ld_cmd; datalink_class_t ld_class; @@ -141,18 +146,23 @@ typedef struct dlmgmt_upcall_arg_create { char ld_devname[MAXNAMELEN]; } dlmgmt_upcall_arg_create_t; +/* + * Note: ld_padding is necessary to keep the size of the structure the + * same on amd64 and i386. The same note applies to other ld_padding + * and lr_paddding fields in structures throughout this file. + */ typedef struct dlmgmt_upcall_arg_destroy { int ld_cmd; datalink_id_t ld_linkid; boolean_t ld_persist; - int ld_reserved; + int ld_padding; } dlmgmt_upcall_arg_destroy_t; typedef struct dlmgmt_upcall_arg_update { int ld_cmd; boolean_t ld_novanity; uint32_t ld_media; - uint32_t ld_reserved; + uint32_t ld_padding; char ld_devname[MAXNAMELEN]; } dlmgmt_upcall_arg_update_t; @@ -181,13 +191,19 @@ typedef struct dlmgmt_door_getnext_s { } dlmgmt_door_getnext_t; /* upcall return value */ +typedef struct dlmgmt_retval_s { + uint_t lr_err; /* return error code */ +} dlmgmt_retval_t; + +typedef dlmgmt_retval_t dlmgmt_destroy_retval_t; + struct dlmgmt_linkid_retval_s { uint_t lr_err; datalink_id_t lr_linkid; uint32_t lr_flags; datalink_class_t lr_class; uint32_t lr_media; - uint32_t lr_reserved; + uint32_t lr_padding; }; typedef struct dlmgmt_linkid_retval_s dlmgmt_create_retval_t, @@ -203,16 +219,12 @@ typedef struct dlmgmt_getname_retval_s { uint32_t lr_flags; } dlmgmt_getname_retval_t; -struct dlmgmt_null_retval_s { - uint_t lr_err; -}; - -typedef struct dlmgmt_null_retval_s dlmgmt_destroy_retval_t; - typedef struct dlmgmt_getattr_retval_s { uint_t lr_err; uint_t lr_type; - char lr_attr[1]; + uint_t lr_attrsz; + uint_t lr_padding; + char lr_attrval[MAXLINKATTRVALLEN]; } dlmgmt_getattr_retval_t; #ifdef _KERNEL diff --git a/usr/src/uts/common/sys/door.h b/usr/src/uts/common/sys/door.h index bccb2e4c76..ec7e79c88f 100644 --- a/usr/src/uts/common/sys/door.h +++ b/usr/src/uts/common/sys/door.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -275,7 +274,7 @@ struct file; int door_insert(struct file *, door_desc_t *); int door_finish_dispatch(caddr_t); uintptr_t door_final_sp(uintptr_t, size_t, int); -int door_upcall(vnode_t *, door_arg_t *); +int door_upcall(vnode_t *, door_arg_t *, struct cred *); void door_slam(void); void door_exit(void); void door_revoke_all(void); @@ -294,6 +293,7 @@ extern size_t door_max_arg; * and may change incompatibly in a minor release of Solaris. */ int door_ki_upcall(door_handle_t, door_arg_t *); +int door_ki_upcall_cred(door_handle_t, door_arg_t *, struct cred *); int door_ki_create(void (*)(void *, door_arg_t *, void (**)(void *, void *), void **, int *), void *, door_attr_t, door_handle_t *); diff --git a/usr/src/uts/common/sys/door_data.h b/usr/src/uts/common/sys/door_data.h index 59aa73e5d1..9c36f86a90 100644 --- a/usr/src/uts/common/sys/door_data.h +++ b/usr/src/uts/common/sys/door_data.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -59,6 +58,7 @@ typedef struct door_layout { */ typedef struct door_client { door_arg_t d_args; /* Door arg/results */ + struct cred *d_cred; /* Cred overridden by the client */ caddr_t d_buf; /* Temp buffer for data transfer */ int d_bufsize; /* Size of temp buffer */ int d_fpp_size; /* Number of File ptrs */ diff --git a/usr/src/uts/intel/ia32/ml/modstubs.s b/usr/src/uts/intel/ia32/ml/modstubs.s index e49fe5c4b8..6524fa1bd7 100644 --- a/usr/src/uts/intel/ia32/ml/modstubs.s +++ b/usr/src/uts/intel/ia32/ml/modstubs.s @@ -885,6 +885,7 @@ fcnname/**/_info: \ NO_UNLOAD_STUB(doorfs, door_ki_open, nomod_einval); NO_UNLOAD_STUB(doorfs, door_ki_lookup, nomod_zero); WSTUB(doorfs, door_ki_upcall, nomod_einval); + WSTUB(doorfs, door_ki_upcall_cred, nomod_einval); WSTUB(doorfs, door_ki_hold, nomod_zero); WSTUB(doorfs, door_ki_rele, nomod_zero); WSTUB(doorfs, door_ki_info, nomod_einval); diff --git a/usr/src/uts/sparc/ml/modstubs.s b/usr/src/uts/sparc/ml/modstubs.s index abc8c124f6..22be0e8a44 100644 --- a/usr/src/uts/sparc/ml/modstubs.s +++ b/usr/src/uts/sparc/ml/modstubs.s @@ -806,6 +806,7 @@ stubs_base: NO_UNLOAD_STUB(doorfs, door_ki_open, nomod_einval); NO_UNLOAD_STUB(doorfs, door_ki_lookup, nomod_zero); WSTUB(doorfs, door_ki_upcall, nomod_einval); + WSTUB(doorfs, door_ki_upcall_cred, nomod_einval); WSTUB(doorfs, door_ki_hold, nomod_zero); WSTUB(doorfs, door_ki_rele, nomod_zero); WSTUB(doorfs, door_ki_info, nomod_einval); |