summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/c2/audit_io.c3
-rw-r--r--usr/src/uts/common/fs/doorfs/door_sys.c37
-rw-r--r--usr/src/uts/common/io/dls/dls_mgmt.c78
-rw-r--r--usr/src/uts/common/sys/dls.h32
-rw-r--r--usr/src/uts/common/sys/door.h10
-rw-r--r--usr/src/uts/common/sys/door_data.h8
-rw-r--r--usr/src/uts/intel/ia32/ml/modstubs.s1
-rw-r--r--usr/src/uts/sparc/ml/modstubs.s1
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);