Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102962922
D37888.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D37888.diff
View Options
diff --git a/sys/kgssapi/gss_delete_sec_context.c.vnetkgssapi b/sys/kgssapi/gss_delete_sec_context.c
--- a/sys/kgssapi/gss_delete_sec_context.c.vnetkgssapi
+++ b/sys/kgssapi/gss_delete_sec_context.c
@@ -31,6 +31,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/kobj.h>
#include <sys/lock.h>
@@ -54,8 +55,12 @@
*minor_status = 0;
- if (!kgss_gssd_handle)
+ KGSS_CURVNET_SET_QUIET(KGSS_TD_TO_VNET(curthread));
+ if (!KGSS_VNET(kgss_gssd_handle)) {
+ KGSS_CURVNET_RESTORE();
return (GSS_S_FAILURE);
+ }
+ KGSS_CURVNET_RESTORE();
if (*context_handle) {
ctx = *context_handle;
diff --git a/sys/kgssapi/gss_impl.c.vnetkgssapi b/sys/kgssapi/gss_impl.c
--- a/sys/kgssapi/gss_impl.c.vnetkgssapi
+++ b/sys/kgssapi/gss_impl.c
@@ -31,13 +31,16 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/kobj.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/osd.h>
#include <sys/priv.h>
+#include <sys/proc.h>
#include <sys/syscall.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
@@ -62,9 +65,10 @@
};
struct kgss_mech_list kgss_mechs;
-CLIENT *kgss_gssd_handle;
struct mtx kgss_gssd_lock;
+KGSS_VNET_DEFINE(CLIENT *, kgss_gssd_handle) = NULL;
+
static int
kgss_load(void)
{
@@ -134,10 +138,12 @@
} else
cl = NULL;
+ KGSS_CURVNET_SET_QUIET(KGSS_TD_TO_VNET(curthread));
mtx_lock(&kgss_gssd_lock);
- oldcl = kgss_gssd_handle;
- kgss_gssd_handle = cl;
+ oldcl = KGSS_VNET(kgss_gssd_handle);
+ KGSS_VNET(kgss_gssd_handle) = cl;
mtx_unlock(&kgss_gssd_lock);
+ KGSS_CURVNET_RESTORE();
if (oldcl != NULL) {
CLNT_CLOSE(oldcl);
@@ -249,12 +255,16 @@
enum clnt_stat stat;
OM_uint32 maj_stat;
- if (!kgss_gssd_handle)
+ KGSS_CURVNET_SET_QUIET(KGSS_TD_TO_VNET(curthread));
+ if (!KGSS_VNET(kgss_gssd_handle)) {
+ KGSS_CURVNET_RESTORE();
return (GSS_S_FAILURE);
+ }
args.ctx = ctx->handle;
bzero(&res, sizeof(res));
- stat = gssd_export_sec_context_1(&args, &res, kgss_gssd_handle);
+ stat = gssd_export_sec_context_1(&args, &res, KGSS_VNET(kgss_gssd_handle));
+ KGSS_CURVNET_RESTORE();
if (stat != RPC_SUCCESS) {
return (GSS_S_FAILURE);
}
@@ -288,11 +298,13 @@
{
CLIENT *cl;
+ KGSS_CURVNET_SET_QUIET(KGSS_TD_TO_VNET(curthread));
mtx_lock(&kgss_gssd_lock);
- cl = kgss_gssd_handle;
+ cl = KGSS_VNET(kgss_gssd_handle);
if (cl != NULL)
CLNT_ACQUIRE(cl);
mtx_unlock(&kgss_gssd_lock);
+ KGSS_CURVNET_RESTORE();
return (cl);
}
@@ -303,6 +315,11 @@
kgssapi_modevent(module_t mod, int type, void *data)
{
int error = 0;
+#ifdef VNET_NFSD
+ osd_method_t methods[PR_MAXMETHOD] = {
+ [PR_METHOD_REMOVE] = rpcgss_prison_cleanup,
+ };
+#endif
switch (type) {
case MOD_LOAD:
@@ -331,6 +348,11 @@
rpc_gss_svc_max_data_length;
mtx_init(&kgss_gssd_lock, "kgss_gssd_lock", NULL, MTX_DEF);
error = kgss_load();
+#ifdef VNET_NFSD
+ /* XXX-BZ OSD to VNET? */
+ if (error == 0)
+ osd_jail_register(NULL, methods);
+#endif
break;
case MOD_UNLOAD:
kgss_unload();
diff --git a/sys/kgssapi/gss_release_cred.c.vnetkgssapi b/sys/kgssapi/gss_release_cred.c
--- a/sys/kgssapi/gss_release_cred.c.vnetkgssapi
+++ b/sys/kgssapi/gss_release_cred.c
@@ -31,6 +31,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/kobj.h>
#include <sys/lock.h>
@@ -52,8 +53,12 @@
*minor_status = 0;
- if (!kgss_gssd_handle)
+ KGSS_CURVNET_SET_QUIET(KGSS_TD_TO_VNET(curthread));
+ if (!KGSS_VNET(kgss_gssd_handle)) {
+ KGSS_CURVNET_RESTORE();
return (GSS_S_FAILURE);
+ }
+ KGSS_CURVNET_RESTORE();
if (*cred_handle) {
args.cred = (*cred_handle)->handle;
diff --git a/sys/kgssapi/gss_release_name.c.vnetkgssapi b/sys/kgssapi/gss_release_name.c
--- a/sys/kgssapi/gss_release_name.c.vnetkgssapi
+++ b/sys/kgssapi/gss_release_name.c
@@ -31,6 +31,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/kobj.h>
#include <sys/lock.h>
@@ -53,8 +54,12 @@
*minor_status = 0;
- if (!kgss_gssd_handle)
+ KGSS_CURVNET_SET_QUIET(KGSS_TD_TO_VNET(curthread));
+ if (!KGSS_VNET(kgss_gssd_handle)) {
+ KGSS_CURVNET_RESTORE();
return (GSS_S_FAILURE);
+ }
+ KGSS_CURVNET_RESTORE();
if (*input_name) {
name = *input_name;
diff --git a/sys/kgssapi/gssapi_impl.h.vnetkgssapi b/sys/kgssapi/gssapi_impl.h
--- a/sys/kgssapi/gssapi_impl.h.vnetkgssapi
+++ b/sys/kgssapi/gssapi_impl.h
@@ -54,9 +54,41 @@
};
LIST_HEAD(kgss_mech_list, kgss_mech);
-extern CLIENT *kgss_gssd_handle;
+/* Macros for VNET_NFSD. */
+#ifdef VNET_NFSD
+#if !defined(VIMAGE)
+options VNET_NFSD also requires options VIMAGE
+#endif
+/* Just define the VNET_KGSSxxx() macros as VNETxxx() macros. */
+#define KGSS_VNET_DEFINE(t, n) VNET_DEFINE(t, n)
+#define KGSS_VNET_DEFINE_STATIC(t, n) VNET_DEFINE_STATIC(t, n)
+#define KGSS_VNET_DECLARE(t, n) VNET_DECLARE(t, n)
+#define KGSS_VNET(n) VNET(n)
+
+#define KGSS_CURVNET_SET(n) CURVNET_SET(n)
+#define KGSS_CURVNET_SET_QUIET(n) CURVNET_SET_QUIET(n)
+#define KGSS_CURVNET_RESTORE() CURVNET_RESTORE()
+#define KGSS_TD_TO_VNET(n) TD_TO_VNET(n)
+
+/* Osd cleanup function. */
+int rpcgss_prison_cleanup(void *obj, void *data __unused);
+#else /* !VNET_NFSD */
+/* Define the KGSS_VNET macros similar to !VIMAGE. */
+#define KGSS_VNET_DEFINE(t, n) t n
+#define KGSS_VNET_DEFINE_STATIC(t, n) static t n
+#define KGSS_VNET_DECLARE(t, n) extern t n
+#define KGSS_VNET(n) (n)
+
+#define KGSS_CURVNET_SET(n)
+#define KGSS_CURVNET_SET_QUIET(n)
+#define KGSS_CURVNET_RESTORE()
+#define KGSS_TD_TO_VNET(n) NULL
+#endif /* VNET_NFSD */
+
extern struct mtx kgss_gssd_lock;
extern struct kgss_mech_list kgss_mechs;
+
+KGSS_VNET_DECLARE(CLIENT *, kgss_gssd_handle);
CLIENT *kgss_gssd_client(void);
int kgss_oid_equal(const gss_OID oid1, const gss_OID oid2);
diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c.vnetkgssapi b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
--- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c.vnetkgssapi
+++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
@@ -81,6 +81,7 @@
#include <rpc/rpc.h>
#include <rpc/rpcsec_gss.h>
+#include <rpc/krpc.h>
#include "rpcsec_gss_int.h"
@@ -102,8 +103,9 @@
SLIST_ENTRY(svc_rpc_gss_callback) cb_link;
rpc_gss_callback_t cb_callback;
};
-static SLIST_HEAD(svc_rpc_gss_callback_list, svc_rpc_gss_callback)
- svc_rpc_gss_callbacks = SLIST_HEAD_INITIALIZER(svc_rpc_gss_callbacks);
+SLIST_HEAD(svc_rpc_gss_callback_list, svc_rpc_gss_callback);
+KGSS_VNET_DEFINE_STATIC(struct svc_rpc_gss_callback_list,
+ svc_rpc_gss_callbacks) = SLIST_HEAD_INITIALIZER(svc_rpc_gss_callbacks);
struct svc_rpc_gss_svc_name {
SLIST_ENTRY(svc_rpc_gss_svc_name) sn_link;
@@ -114,8 +116,9 @@
u_int sn_program;
u_int sn_version;
};
-static SLIST_HEAD(svc_rpc_gss_svc_name_list, svc_rpc_gss_svc_name)
- svc_rpc_gss_svc_names = SLIST_HEAD_INITIALIZER(svc_rpc_gss_svc_names);
+SLIST_HEAD(svc_rpc_gss_svc_name_list, svc_rpc_gss_svc_name);
+KGSS_VNET_DEFINE_STATIC(struct svc_rpc_gss_svc_name_list,
+ svc_rpc_gss_svc_names) = SLIST_HEAD_INITIALIZER(svc_rpc_gss_svc_names);
enum svc_rpc_gss_client_state {
CLIENT_NEW, /* still authenticating */
@@ -197,24 +200,45 @@
&svc_rpc_gss_client_count, 0,
"Number of rpc-gss clients");
-struct svc_rpc_gss_client_list *svc_rpc_gss_client_hash;
-struct svc_rpc_gss_client_list svc_rpc_gss_clients;
-static uint32_t svc_rpc_gss_next_clientid = 1;
+KGSS_VNET_DEFINE(struct svc_rpc_gss_client_list *, svc_rpc_gss_client_hash);
+KGSS_VNET_DEFINE(struct svc_rpc_gss_client_list, svc_rpc_gss_clients);
+KGSS_VNET_DEFINE_STATIC(uint32_t, svc_rpc_gss_next_clientid) = 1;
static void
svc_rpc_gss_init(void *arg)
{
int i;
- svc_rpc_gss_client_hash = mem_alloc(sizeof(struct svc_rpc_gss_client_list) * svc_rpc_gss_client_hash_size);
+ KGSS_VNET(svc_rpc_gss_client_hash) = mem_alloc(
+ sizeof(struct svc_rpc_gss_client_list) *
+ svc_rpc_gss_client_hash_size);
for (i = 0; i < svc_rpc_gss_client_hash_size; i++)
- TAILQ_INIT(&svc_rpc_gss_client_hash[i]);
- TAILQ_INIT(&svc_rpc_gss_clients);
- svc_auth_reg(RPCSEC_GSS, svc_rpc_gss, rpc_gss_svc_getcred);
- sx_init(&svc_rpc_gss_lock, "gsslock");
+ TAILQ_INIT(&KGSS_VNET(svc_rpc_gss_client_hash)[i]);
+ TAILQ_INIT(&KGSS_VNET(svc_rpc_gss_clients));
+ if (IS_DEFAULT_VNET(curvnet)) {
+ svc_auth_reg(RPCSEC_GSS, svc_rpc_gss, rpc_gss_svc_getcred);
+ sx_init(&svc_rpc_gss_lock, "gsslock");
+ }
}
-SYSINIT(svc_rpc_gss_init, SI_SUB_KMEM, SI_ORDER_ANY, svc_rpc_gss_init, NULL);
+VNET_SYSINIT(svc_rpc_gss_init, SI_SUB_VNET_DONE, SI_ORDER_ANY,
+ svc_rpc_gss_init, NULL);
+#ifdef VNET_NFSD
+/* Osd entry for prison cleanup. */
+int
+rpcgss_prison_cleanup(void *obj, void *data __unused)
+{
+ struct prison *pr = obj;
+
+ if ((pr->pr_flags & PR_VNET) == 0)
+ return (0);
+ KGSS_CURVNET_SET(pr->pr_vnet);
+ free(KGSS_VNET(svc_rpc_gss_client_hash), M_RPC);
+ KGSS_CURVNET_RESTORE();
+ return (0);
+}
+#endif
+
bool_t
rpc_gss_set_callback(rpc_gss_callback_t *cb)
{
@@ -227,7 +251,7 @@
}
scb->cb_callback = *cb;
sx_xlock(&svc_rpc_gss_lock);
- SLIST_INSERT_HEAD(&svc_rpc_gss_callbacks, scb, cb_link);
+ SLIST_INSERT_HEAD(&KGSS_VNET(svc_rpc_gss_callbacks), scb, cb_link);
sx_xunlock(&svc_rpc_gss_lock);
return (TRUE);
@@ -239,11 +263,11 @@
struct svc_rpc_gss_callback *scb;
sx_xlock(&svc_rpc_gss_lock);
- SLIST_FOREACH(scb, &svc_rpc_gss_callbacks, cb_link) {
+ SLIST_FOREACH(scb, &KGSS_VNET(svc_rpc_gss_callbacks), cb_link) {
if (scb->cb_callback.program == cb->program
&& scb->cb_callback.version == cb->version
&& scb->cb_callback.callback == cb->callback) {
- SLIST_REMOVE(&svc_rpc_gss_callbacks, scb,
+ SLIST_REMOVE(&KGSS_VNET(svc_rpc_gss_callbacks), scb,
svc_rpc_gss_callback, cb_link);
sx_xunlock(&svc_rpc_gss_lock);
mem_free(scb, sizeof(*scb));
@@ -314,7 +338,7 @@
}
sx_xlock(&svc_rpc_gss_lock);
- SLIST_INSERT_HEAD(&svc_rpc_gss_svc_names, sname, sn_link);
+ SLIST_INSERT_HEAD(&KGSS_VNET(svc_rpc_gss_svc_names), sname, sn_link);
sx_xunlock(&svc_rpc_gss_lock);
return (TRUE);
@@ -327,10 +351,10 @@
struct svc_rpc_gss_svc_name *sname;
sx_xlock(&svc_rpc_gss_lock);
- SLIST_FOREACH(sname, &svc_rpc_gss_svc_names, sn_link) {
+ SLIST_FOREACH(sname, &KGSS_VNET(svc_rpc_gss_svc_names), sn_link) {
if (sname->sn_program == program
&& sname->sn_version == version) {
- SLIST_REMOVE(&svc_rpc_gss_svc_names, sname,
+ SLIST_REMOVE(&KGSS_VNET(svc_rpc_gss_svc_names), sname,
svc_rpc_gss_svc_name, sn_link);
sx_xunlock(&svc_rpc_gss_lock);
gss_release_cred(&min_stat, &sname->sn_cred);
@@ -548,7 +572,8 @@
if (id->ci_hostid != hostid || id->ci_boottime != boottime.tv_sec)
return (NULL);
- list = &svc_rpc_gss_client_hash[id->ci_id % svc_rpc_gss_client_hash_size];
+ list = &KGSS_VNET(svc_rpc_gss_client_hash)
+ [id->ci_id % svc_rpc_gss_client_hash_size];
sx_xlock(&svc_rpc_gss_lock);
TAILQ_FOREACH(client, list, cl_link) {
if (client->cl_id.ci_id == id->ci_id) {
@@ -556,9 +581,10 @@
* Move this client to the front of the LRU
* list.
*/
- TAILQ_REMOVE(&svc_rpc_gss_clients, client, cl_alllink);
- TAILQ_INSERT_HEAD(&svc_rpc_gss_clients, client,
+ TAILQ_REMOVE(&KGSS_VNET(svc_rpc_gss_clients), client,
cl_alllink);
+ TAILQ_INSERT_HEAD(&KGSS_VNET(svc_rpc_gss_clients),
+ client, cl_alllink);
refcount_acquire(&client->cl_refs);
break;
}
@@ -591,7 +617,7 @@
client->cl_id.ci_hostid = hostid;
getboottime(&boottime);
client->cl_id.ci_boottime = boottime.tv_sec;
- client->cl_id.ci_id = svc_rpc_gss_next_clientid++;
+ client->cl_id.ci_id = KGSS_VNET(svc_rpc_gss_next_clientid)++;
/*
* Start the client off with a short expiration time. We will
@@ -601,10 +627,11 @@
client->cl_locked = FALSE;
client->cl_expiration = time_uptime + 5*60;
- list = &svc_rpc_gss_client_hash[client->cl_id.ci_id % svc_rpc_gss_client_hash_size];
+ list = &KGSS_VNET(svc_rpc_gss_client_hash)
+ [client->cl_id.ci_id % svc_rpc_gss_client_hash_size];
sx_xlock(&svc_rpc_gss_lock);
TAILQ_INSERT_HEAD(list, client, cl_link);
- TAILQ_INSERT_HEAD(&svc_rpc_gss_clients, client, cl_alllink);
+ TAILQ_INSERT_HEAD(&KGSS_VNET(svc_rpc_gss_clients), client, cl_alllink);
svc_rpc_gss_client_count++;
sx_xunlock(&svc_rpc_gss_lock);
return (client);
@@ -658,9 +685,10 @@
struct svc_rpc_gss_client_list *list;
sx_assert(&svc_rpc_gss_lock, SX_XLOCKED);
- list = &svc_rpc_gss_client_hash[client->cl_id.ci_id % svc_rpc_gss_client_hash_size];
+ list = &KGSS_VNET(svc_rpc_gss_client_hash)
+ [client->cl_id.ci_id % svc_rpc_gss_client_hash_size];
TAILQ_REMOVE(list, client, cl_link);
- TAILQ_REMOVE(&svc_rpc_gss_clients, client, cl_alllink);
+ TAILQ_REMOVE(&KGSS_VNET(svc_rpc_gss_clients), client, cl_alllink);
svc_rpc_gss_client_count--;
}
@@ -673,7 +701,8 @@
struct svc_rpc_gss_client_list *list;
struct svc_rpc_gss_client *tclient;
- list = &svc_rpc_gss_client_hash[client->cl_id.ci_id % svc_rpc_gss_client_hash_size];
+ list = &KGSS_VNET(svc_rpc_gss_client_hash)
+ [client->cl_id.ci_id % svc_rpc_gss_client_hash_size];
sx_xlock(&svc_rpc_gss_lock);
TAILQ_FOREACH(tclient, list, cl_link) {
/*
@@ -704,17 +733,18 @@
* svc_rpc_gss_clients in LRU order.
*/
sx_xlock(&svc_rpc_gss_lock);
- client = TAILQ_LAST(&svc_rpc_gss_clients, svc_rpc_gss_client_list);
+ client = TAILQ_LAST(&KGSS_VNET(svc_rpc_gss_clients),
+ svc_rpc_gss_client_list);
while (svc_rpc_gss_client_count > svc_rpc_gss_client_max && client != NULL) {
svc_rpc_gss_forget_client_locked(client);
sx_xunlock(&svc_rpc_gss_lock);
svc_rpc_gss_release_client(client);
sx_xlock(&svc_rpc_gss_lock);
- client = TAILQ_LAST(&svc_rpc_gss_clients,
+ client = TAILQ_LAST(&KGSS_VNET(svc_rpc_gss_clients),
svc_rpc_gss_client_list);
}
again:
- TAILQ_FOREACH(client, &svc_rpc_gss_clients, cl_alllink) {
+ TAILQ_FOREACH(client, &KGSS_VNET(svc_rpc_gss_clients), cl_alllink) {
if (client->cl_state == CLIENT_STALE
|| now > client->cl_expiration) {
svc_rpc_gss_forget_client_locked(client);
@@ -883,7 +913,8 @@
*/
sx_xlock(&svc_rpc_gss_lock);
if (!client->cl_sname) {
- SLIST_FOREACH(sname, &svc_rpc_gss_svc_names, sn_link) {
+ SLIST_FOREACH(sname, &KGSS_VNET(svc_rpc_gss_svc_names),
+ sn_link) {
if (sname->sn_program == rqst->rq_prog
&& sname->sn_version == rqst->rq_vers) {
retry:
@@ -1137,7 +1168,7 @@
* See if we have a callback for this guy.
*/
result = TRUE;
- SLIST_FOREACH(scb, &svc_rpc_gss_callbacks, cb_link) {
+ SLIST_FOREACH(scb, &KGSS_VNET(svc_rpc_gss_callbacks), cb_link) {
if (scb->cb_callback.program == rqst->rq_prog
&& scb->cb_callback.version == rqst->rq_vers) {
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 20, 6:25 AM (21 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14732031
Default Alt Text
D37888.diff (14 KB)
Attached To
Mode
D37888: Patch the kgssapi do that it can run in a vnet prison
Attached
Detach File
Event Timeline
Log In to Comment