Compare commits

...

2 Commits

Author SHA1 Message Date
Vitaliy Filippov 22546a29e9 Add an opaque pointer argument to service_proc
Without this argument it's impossible to pass an object instance to procedure
callbacks which basically forces users to either use global variables or to
write additional boilerplate code and find object instances from rpc_context
pointer values.
2022-02-06 02:26:18 +03:00
Vitaliy Filippov 925d2a35ce Don't try to ZDR_DECODE strings into a pre-existing pointer
Otherwise it segfaults inside any string decoding inside rpc_process_call()
as it doesn't zero the allocated memory, so libnfs_zdr_string() may receive
non-zero *strp which is very easy to reproduce by writing a simple NFS server
example using libnfs :-)
2022-02-06 02:23:44 +03:00
6 changed files with 18 additions and 21 deletions

View File

@ -680,7 +680,7 @@ void setclientid_cb(struct rpc_context *rpc, int status, void *data,
/*
* NULL procedure for the callback protocol.
*/
static int cb_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
static int cb_null_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
@ -691,7 +691,7 @@ static int cb_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
* CB_COMPOUND procedure for the callback protocol.
* This is where the server will inform us about lease breaks and similar.
*/
static int cb_compound_proc(struct rpc_context *rpc, struct rpc_msg *call)
static int cb_compound_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
CB_COMPOUND4args *args = call->body.cbody.args;

View File

@ -682,7 +682,7 @@ void setclientid_cb(struct rpc_context *rpc, int status, void *data,
/*
* NULL procedure for the callback protocol.
*/
static int cb_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
static int cb_null_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
@ -693,7 +693,7 @@ static int cb_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
* CB_COMPOUND procedure for the callback protocol.
* This is where the server will inform us about lease breaks and similar.
*/
static int cb_compound_proc(struct rpc_context *rpc, struct rpc_msg *call)
static int cb_compound_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
CB_COMPOUND4args *args = call->body.cbody.args;

View File

@ -248,7 +248,7 @@ void map_remove(int prog, int vers, char *netid)
* It is used by clients, and rpcinfo, to "ping" a service and verify that
* the service is available and that it does support the indicated version.
*/
static int pmap2_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
static int pmap2_null_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
@ -262,7 +262,7 @@ static int pmap2_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
* and portmapper returns which port that service is available on,
* (or 0 if no such program is registered.)
*/
static int pmap2_getport_proc(struct rpc_context *rpc, struct rpc_msg *call)
static int pmap2_getport_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
PMAP2GETPORTargs *args = call->body.cbody.args;
struct mapping *tmp;
@ -290,7 +290,7 @@ static int pmap2_getport_proc(struct rpc_context *rpc, struct rpc_msg *call)
* This RPC returns a list of all endpoints that are registered with
* portmapper.
*/
static int pmap2_dump_proc(struct rpc_context *rpc, struct rpc_msg *call)
static int pmap2_dump_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
PMAP2DUMPres reply;
struct mapping *tmp;
@ -336,7 +336,7 @@ static int pmap2_dump_proc(struct rpc_context *rpc, struct rpc_msg *call)
* v2 SET
* This procedure is used to register and endpoint with portmapper.
*/
static int pmap2_set_proc(struct rpc_context *rpc, struct rpc_msg *call)
static int pmap2_set_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
PMAP2GETPORTargs *args = call->body.cbody.args;
char *prot;
@ -369,7 +369,7 @@ static int pmap2_set_proc(struct rpc_context *rpc, struct rpc_msg *call)
* This procedure is used to remove a registration from portmappers
* list of endpoints.
*/
static int pmap2_unset_proc(struct rpc_context *rpc, struct rpc_msg *call)
static int pmap2_unset_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
PMAP2GETPORTargs *args = call->body.cbody.args;
char *prot;
@ -424,7 +424,7 @@ struct service_proc pmap2_pt[] = {
* It is used by clients, and rpcinfo, to "ping" a service and verify that
* the service is available and that it does support the indicated version.
*/
static int pmap3_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
static int pmap3_null_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
@ -436,7 +436,7 @@ static int pmap3_null_proc(struct rpc_context *rpc, struct rpc_msg *call)
* This RPC returns a list of all endpoints that are registered with
* portmapper.
*/
static int pmap3_dump_proc(struct rpc_context *rpc, struct rpc_msg *call)
static int pmap3_dump_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
PMAP3DUMPres reply;
struct mapping *tmp;

View File

@ -114,13 +114,14 @@ EXTERN struct rpc_context *rpc_init_server_context(int s);
* !0: An abnormal error has occured. It is unrecoverable and the only
* meaningful action is to tear down the connection to the server.
*/
typedef int (*service_fn)(struct rpc_context *rpc, struct rpc_msg *call);
typedef int (*service_fn)(struct rpc_context *rpc, struct rpc_msg *call, void *opaque);
struct service_proc {
int proc;
service_fn func;
zdrproc_t decode_fn;
int decode_buf_size;
void *opaque;
};
/*

View File

@ -289,15 +289,11 @@ bool_t libnfs_zdr_string(ZDR *zdrs, char **strp, uint32_t maxsize)
* in place.
*/
if (zdrs->size > zdrs->pos + (int)size && zdrs->buf[zdrs->pos + size] == 0) {
if (*strp == NULL) {
*strp = &zdrs->buf[zdrs->pos];
(*strp)[size] = 0;
zdrs->pos += size;
zdrs->pos = (zdrs->pos + 3) & ~3;
return TRUE;
}
*strp = &zdrs->buf[zdrs->pos];
(*strp)[size] = 0;
return libnfs_zdr_opaque(zdrs, *strp, size);
zdrs->pos += size;
zdrs->pos = (zdrs->pos + 3) & ~3;
return TRUE;
}
/* Crap. The string is not null terminated in the rx buffer.

View File

@ -458,7 +458,7 @@ static int rpc_process_call(struct rpc_context *rpc, ZDR *zdr)
"call payload");
return rpc_send_error_reply(rpc, &call, GARBAGE_ARGS, 0 ,0);
}
return endpoint->procs[i].func(rpc, &call);
return endpoint->procs[i].func(rpc, &call, endpoint->procs[i].opaque);
}
}