@@ -59,6 +59,7 @@
static int gss3_create_label(struct rpc_cred *cred, int gss_vers);
static struct gss3_assert *gss3_use_child_handle(struct gss_cl_ctx *ctx);
static struct gss3_assert *gss3_match_label(struct gss3_assert_list *in);
+static void gss3_free_assertions(struct gss3_assert_list *in);
static const struct rpc_authops authgss_ops;
@@ -1275,11 +1276,10 @@ gss_destroying_context(struct rpc_cred *cred)
static void
gss_do_free_ctx(struct gss_cl_ctx *ctx)
{
- dprintk("RPC: %s\n", __func__);
-
gss_delete_sec_context(&ctx->gc_gss_ctx);
kfree(ctx->gc_wire_ctx.data);
kfree(ctx->gc_acceptor.data);
+ gss3_free_assertions(&ctx->gc_alist);
kfree(ctx);
}
@@ -1657,6 +1657,50 @@ gss3_insert_assertion(struct gss3_assert_list *alist, struct gss3_assert *g3a)
spin_unlock(&alist->assert_lock);
}
+static void gss3_free_label(struct gss3_label *gl)
+{
+ kfree(gl->la_label.data);
+}
+
+/**
+ * Note: Currently, only support for one assertion so gss3_num always = 1
+ */
+static void gss3_free_assertions(struct gss3_assert_list *in)
+{
+ struct gss3_assert *found, *tmp;
+ LIST_HEAD(freelist);
+
+ rcu_read_lock();
+ spin_lock(&in->assert_lock);
+ list_for_each_entry_rcu(found, &in->assert_list, gss3_list) {
+ list_del_rcu(&found->gss3_list);
+ list_add(&found->gss3_list, &freelist);
+ }
+ rcu_read_unlock();
+ spin_unlock(&in->assert_lock);
+ synchronize_rcu();
+
+ list_for_each_entry_safe(found, tmp, &freelist, gss3_list) {
+ list_del(&found->gss3_list);
+
+ /* allocated in gss3_dec_label */
+ kfree(found->gss3_handle.data);
+
+ /* gss3_num is always one for now */
+ switch (found->gss3_assertion->au_type) {
+ case GSS3_LABEL:
+ gss3_free_label(&found->gss3_assertion->u.au_label);
+ break;
+ case GSS3_PRIVS:
+ default:
+ pr_warn("RPC %s Can't free unsupported au_type %d\n",
+ __func__, found->gss3_assertion->au_type);
+ return;
+ }
+ kfree(found);
+ }
+}
+
static struct gss3_assert *
gss3_match_label(struct gss3_assert_list *in)
{
@@ -1821,6 +1865,7 @@ gss3_dec_create(struct rpc_rqst *req, struct xdr_stream *xdr,
if (unlikely(!p))
goto out_overflow;
+ /* freed in gss3_free_assertions */
g3cr->cr_handle = kmemdup(p, g3cr->cr_hlen, GFP_KERNEL);
if (!g3cr->cr_handle)
goto out_err;