Print this page
3354 kernel crash in rpcsec_gss after using gsscred
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Carlos Neira <cneirabustos@gmail.com>
Approved by: Robert Mustacchi <rm@joyent.com>
NEX-771 Long RPC messages could confuse kernel and cause panic
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Jan Kryl <jan.kryl@nexenta.com>
re #12783 rb4338 Flow control is needed in rpcmod when the NFS server is unable to keep up with the network
re #13613 rb4516 Tunables needs volatile keyword
*** 22,32 ****
--- 22,34 ----
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright 2012 Milan Jurik. All rights reserved.
+ * Copyright 2012 Marcel Telka <marcel@telka.sk>
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
*/
/* Copyright (c) 1990 Mentat Inc. */
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
*** 568,578 ****
rmm_close(queue_t *q, int flag, cred_t *crp)
{
return ((*((struct temp_slot *)q->q_ptr)->ops->xo_close)(q, flag, crp));
}
- static void rpcmod_release(queue_t *, mblk_t *, bool_t);
/*
* rpcmodopen - open routine gets called when the module gets pushed
* onto the stream.
*/
/*ARGSUSED*/
--- 570,579 ----
*** 579,601 ****
int
rpcmodopen(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp)
{
struct rpcm *rmp;
- extern void (*rpc_rele)(queue_t *, mblk_t *, bool_t);
-
TRACE_0(TR_FAC_KRPC, TR_RPCMODOPEN_START, "rpcmodopen_start:");
/*
- * Initialize entry points to release a rpcmod slot (and an input
- * message if supplied) and to send an output message to the module
- * below rpcmod.
- */
- if (rpc_rele == NULL)
- rpc_rele = rpcmod_release;
-
- /*
* Only sufficiently privileged users can use this module, and it
* is assumed that they will use this module properly, and NOT send
* bulk data from downstream.
*/
if (secpolicy_rpcmod_open(crp) != 0)
--- 580,592 ----
*** 948,961 ****
(void) putbq(q, mp);
return;
}
}
! /* ARGSUSED */
! static void
! rpcmod_release(queue_t *q, mblk_t *bp, bool_t enable)
{
struct rpcm *rmp;
/*
* For now, just free the message.
*/
--- 939,963 ----
(void) putbq(q, mp);
return;
}
}
! void
! rpcmod_hold(queue_t *q)
{
+ struct rpcm *rmp = (struct rpcm *)q->q_ptr;
+
+ mutex_enter(&rmp->rm_lock);
+ rmp->rm_ref++;
+ mutex_exit(&rmp->rm_lock);
+ }
+
+ void
+ rpcmod_release(queue_t *q, mblk_t *bp,
+ /* LINTED E_FUNC_ARG_UNUSED */
+ bool_t enable __unused)
+ {
struct rpcm *rmp;
/*
* For now, just free the message.
*/
*** 1003,1013 ****
(canputnext(write_q) || ((mir_ptr)->mir_svc_no_more_msgs == 1))
static int mir_clnt_dup_request(queue_t *q, mblk_t *mp);
static void mir_rput_proto(queue_t *q, mblk_t *mp);
static int mir_svc_policy_notify(queue_t *q, int event);
- static void mir_svc_release(queue_t *wq, mblk_t *mp, bool_t);
static void mir_svc_start(queue_t *wq);
static void mir_svc_idle_start(queue_t *, mir_t *);
static void mir_svc_idle_stop(queue_t *, mir_t *);
static void mir_svc_start_close(queue_t *, mir_t *);
static void mir_clnt_idle_do_stop(queue_t *);
--- 1005,1014 ----
*** 1018,1033 ****
static void mir_wsrv(queue_t *q);
static void mir_disconnect(queue_t *, mir_t *ir);
static int mir_check_len(queue_t *, mblk_t *);
static void mir_timer(void *);
- extern void (*mir_rele)(queue_t *, mblk_t *, bool_t);
extern void (*mir_start)(queue_t *);
extern void (*clnt_stop_idle)(queue_t *);
! clock_t clnt_idle_timeout = MIR_CLNT_IDLE_TIMEOUT;
! clock_t svc_idle_timeout = MIR_SVC_IDLE_TIMEOUT;
/*
* Timeout for subsequent notifications of idle connection. This is
* typically used to clean up after a wedged orderly release.
*/
--- 1019,1033 ----
static void mir_wsrv(queue_t *q);
static void mir_disconnect(queue_t *, mir_t *ir);
static int mir_check_len(queue_t *, mblk_t *);
static void mir_timer(void *);
extern void (*mir_start)(queue_t *);
extern void (*clnt_stop_idle)(queue_t *);
! volatile clock_t clnt_idle_timeout = MIR_CLNT_IDLE_TIMEOUT;
! volatile clock_t svc_idle_timeout = MIR_SVC_IDLE_TIMEOUT;
/*
* Timeout for subsequent notifications of idle connection. This is
* typically used to clean up after a wedged orderly release.
*/
*** 1257,1268 ****
{
mir_t *mir;
RPCLOG(32, "rpcmod: mir_open of q 0x%p\n", (void *)q);
/* Set variables used directly by kRPC. */
- if (!mir_rele)
- mir_rele = mir_svc_release;
if (!mir_start)
mir_start = mir_svc_start;
if (!clnt_stop_idle)
clnt_stop_idle = mir_clnt_idle_do_stop;
if (!clnt_max_msg_sizep)
--- 1257,1266 ----
*** 2017,2031 ****
* responses downstream, regardless of flow control.
*/
qenable(wq);
}
/*
* This routine is called directly by kRPC after a request is completed,
* whether a reply was sent or the request was dropped.
*/
! static void
mir_svc_release(queue_t *wq, mblk_t *mp, bool_t enable)
{
mir_t *mir = (mir_t *)wq->q_ptr;
mblk_t *cmp = NULL;
--- 2015,2039 ----
* responses downstream, regardless of flow control.
*/
qenable(wq);
}
+ void
+ mir_svc_hold(queue_t *wq)
+ {
+ mir_t *mir = (mir_t *)wq->q_ptr;
+
+ mutex_enter(&mir->mir_mutex);
+ mir->mir_ref_cnt++;
+ mutex_exit(&mir->mir_mutex);
+ }
+
/*
* This routine is called directly by kRPC after a request is completed,
* whether a reply was sent or the request was dropped.
*/
! void
mir_svc_release(queue_t *wq, mblk_t *mp, bool_t enable)
{
mir_t *mir = (mir_t *)wq->q_ptr;
mblk_t *cmp = NULL;