From 3d7b19cd1ecd53f0808b07df7c4ac801fd48f3c3 Mon Sep 17 00:00:00 2001 From: Santosh Kumar Pradhan Date: Thu, 3 Jul 2014 17:11:44 +0530 Subject: rpcsvc: Validate RPC procedure number before fetch While accessing the procedures of given RPC program in, rpcsvc_get_program_vector_sizer(), It was not checking boundary conditions which would cause buffer overflow and subsequently SEGV. Make sure rpcsvc_actor_t arrays have numactors number of actors. FIX: Validate the RPC procedure number before fetching the actor. Upstream main review: http://review.gluster.org/7726 BUG: 1096020 Change-Id: Iaf207ee976cb56fa9a554ec82c9eab36d3b289ed Signed-off-by: Santosh Kumar Pradhan Reviewed-on: http://review.gluster.org/8228 Tested-by: Gluster Build System Reviewed-by: Niels de Vos --- api/src/glfs-mgmt.c | 2 +- glusterfsd/src/glusterfsd-mgmt.c | 4 ++-- rpc/rpc-lib/src/rpcsvc.c | 22 ++++++++++++++++------ xlators/features/quota/src/quotad-aggregator.c | 4 ++-- xlators/mgmt/glusterd/src/glusterd-handler.c | 8 ++++---- xlators/mgmt/glusterd/src/glusterd-handshake.c | 12 ++++++------ xlators/mgmt/glusterd/src/glusterd-pmap.c | 4 ++-- xlators/nfs/server/src/acl3.c | 6 +++--- xlators/protocol/client/src/client-callback.c | 2 +- xlators/protocol/server/src/server-handshake.c | 2 +- xlators/protocol/server/src/server-rpc-fops.c | 2 +- 11 files changed, 39 insertions(+), 29 deletions(-) diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c index 2557186ebd8..10d9583738e 100644 --- a/api/src/glfs-mgmt.c +++ b/api/src/glfs-mgmt.c @@ -116,7 +116,7 @@ mgmt_cbk_event (struct rpc_clnt *rpc, void *mydata, void *data) } -rpcclnt_cb_actor_t mgmt_cbk_actors[] = { +rpcclnt_cb_actor_t mgmt_cbk_actors[GF_CBK_MAXVALUE] = { [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, mgmt_cbk_spec }, [GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_CBK_EVENT_NOTIFY, mgmt_cbk_event}, diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c index 0484779ce55..b75a8027e07 100644 --- a/glusterfsd/src/glusterfsd-mgmt.c +++ b/glusterfsd/src/glusterfsd-mgmt.c @@ -1136,7 +1136,7 @@ glusterfs_handle_rpc_msg (rpcsvc_request_t *req) return ret; } -rpcclnt_cb_actor_t mgmt_cbk_actors[] = { +rpcclnt_cb_actor_t mgmt_cbk_actors[GF_CBK_MAXVALUE] = { [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, mgmt_cbk_spec }, [GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_CBK_EVENT_NOTIFY, mgmt_cbk_event}, @@ -1183,7 +1183,7 @@ rpc_clnt_prog_t clnt_handshake_prog = { .procnames = clnt_handshake_procs, }; -rpcsvc_actor_t glusterfs_actors[] = { +rpcsvc_actor_t glusterfs_actors[GLUSTERD_BRICK_MAXVALUE] = { [GLUSTERD_BRICK_NULL] = {"NULL", GLUSTERD_BRICK_NULL, glusterfs_handle_rpc_msg, NULL, 0, DRC_NA}, [GLUSTERD_BRICK_TERMINATE] = {"TERMINATE", GLUSTERD_BRICK_TERMINATE, glusterfs_handle_terminate, NULL, 0, DRC_NA}, [GLUSTERD_BRICK_XLATOR_INFO] = {"TRANSLATOR INFO", GLUSTERD_BRICK_XLATOR_INFO, glusterfs_handle_translator_info_get, NULL, 0, DRC_NA}, diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c index d6e9ee951c8..11869233c8e 100644 --- a/rpc/rpc-lib/src/rpcsvc.c +++ b/rpc/rpc-lib/src/rpcsvc.c @@ -117,6 +117,7 @@ rpcsvc_get_program_vector_sizer (rpcsvc_t *svc, uint32_t prognum, pthread_mutex_lock (&svc->rpclock); { + /* Find the matching RPC program from registered list */ list_for_each_entry (program, &svc->programs, program) { if ((program->prognum == prognum) && (program->progver == progver)) { @@ -127,10 +128,20 @@ rpcsvc_get_program_vector_sizer (rpcsvc_t *svc, uint32_t prognum, } pthread_mutex_unlock (&svc->rpclock); - if (found) + if (found) { + /* Make sure the requested procnum is supported by RPC prog */ + if (procnum >= program->numactors) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, + "RPC procedure %d not available for Program %s", + procnum, program->progname); + return NULL; + } + + /* SUCCESS: Supported procedure */ return program->actors[procnum].vector_sizer; - else - return NULL; + } + + return NULL; /* FAIL */ } gf_boolean_t @@ -2596,10 +2607,9 @@ out: } -rpcsvc_actor_t gluster_dump_actors[] = { +rpcsvc_actor_t gluster_dump_actors[GF_DUMP_MAXVALUE] = { [GF_DUMP_NULL] = {"NULL", GF_DUMP_NULL, NULL, NULL, 0, DRC_NA}, [GF_DUMP_DUMP] = {"DUMP", GF_DUMP_DUMP, rpcsvc_dump, NULL, 0, DRC_NA}, - [GF_DUMP_MAXVALUE] = {"MAXVALUE", GF_DUMP_MAXVALUE, NULL, NULL, 0, DRC_NA}, }; @@ -2608,5 +2618,5 @@ struct rpcsvc_program gluster_dump_prog = { .prognum = GLUSTER_DUMP_PROGRAM, .progver = GLUSTER_DUMP_VERSION, .actors = gluster_dump_actors, - .numactors = 2, + .numactors = GF_DUMP_MAXVALUE, }; diff --git a/xlators/features/quota/src/quotad-aggregator.c b/xlators/features/quota/src/quotad-aggregator.c index bf7a845fd22..32c3f745a5d 100644 --- a/xlators/features/quota/src/quotad-aggregator.c +++ b/xlators/features/quota/src/quotad-aggregator.c @@ -400,13 +400,13 @@ out: return ret; } -rpcsvc_actor_t quotad_aggregator_actors[] = { +rpcsvc_actor_t quotad_aggregator_actors[GF_AGGREGATOR_MAXVALUE] = { [GF_AGGREGATOR_NULL] = {"NULL", GF_AGGREGATOR_NULL, NULL, NULL, 0, DRC_NA}, [GF_AGGREGATOR_LOOKUP] = {"LOOKUP", GF_AGGREGATOR_NULL, quotad_aggregator_lookup, NULL, 0, DRC_NA}, [GF_AGGREGATOR_GETLIMIT] = {"GETLIMIT", GF_AGGREGATOR_GETLIMIT, - quotad_aggregator_getlimit, NULL, 0}, + quotad_aggregator_getlimit, NULL, 0, DRC_NA}, }; diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 0407741bb7b..a594a770034 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -3921,7 +3921,7 @@ glusterd_null (rpcsvc_request_t *req) return 0; } -rpcsvc_actor_t gd_svc_mgmt_actors[] = { +rpcsvc_actor_t gd_svc_mgmt_actors[GLUSTERD_MGMT_MAXVALUE] = { [GLUSTERD_MGMT_NULL] = { "NULL", GLUSTERD_MGMT_NULL, glusterd_null, NULL, 0, DRC_NA}, [GLUSTERD_MGMT_CLUSTER_LOCK] = { "CLUSTER_LOCK", GLUSTERD_MGMT_CLUSTER_LOCK, glusterd_handle_cluster_lock, NULL, 0, DRC_NA}, [GLUSTERD_MGMT_CLUSTER_UNLOCK] = { "CLUSTER_UNLOCK", GLUSTERD_MGMT_CLUSTER_UNLOCK, glusterd_handle_cluster_unlock, NULL, 0, DRC_NA}, @@ -3938,7 +3938,7 @@ struct rpcsvc_program gd_svc_mgmt_prog = { .synctask = _gf_true, }; -rpcsvc_actor_t gd_svc_peer_actors[] = { +rpcsvc_actor_t gd_svc_peer_actors[GLUSTERD_FRIEND_MAXVALUE] = { [GLUSTERD_FRIEND_NULL] = { "NULL", GLUSTERD_MGMT_NULL, glusterd_null, NULL, 0, DRC_NA}, [GLUSTERD_PROBE_QUERY] = { "PROBE_QUERY", GLUSTERD_PROBE_QUERY, glusterd_handle_probe_query, NULL, 0, DRC_NA}, [GLUSTERD_FRIEND_ADD] = { "FRIEND_ADD", GLUSTERD_FRIEND_ADD, glusterd_handle_incoming_friend_req, NULL, 0, DRC_NA}, @@ -3957,7 +3957,7 @@ struct rpcsvc_program gd_svc_peer_prog = { -rpcsvc_actor_t gd_svc_cli_actors[] = { +rpcsvc_actor_t gd_svc_cli_actors[GLUSTER_CLI_MAXVALUE] = { [GLUSTER_CLI_PROBE] = { "CLI_PROBE", GLUSTER_CLI_PROBE, glusterd_handle_cli_probe, NULL, 0, DRC_NA}, [GLUSTER_CLI_CREATE_VOLUME] = { "CLI_CREATE_VOLUME", GLUSTER_CLI_CREATE_VOLUME, glusterd_handle_create_volume, NULL, 0, DRC_NA}, [GLUSTER_CLI_DEFRAG_VOLUME] = { "CLI_DEFRAG_VOLUME", GLUSTER_CLI_DEFRAG_VOLUME, glusterd_handle_defrag_volume, NULL, 0, DRC_NA}, @@ -4004,7 +4004,7 @@ struct rpcsvc_program gd_svc_cli_prog = { /* This is a minimal RPC prog, which contains only the readonly RPC procs from * the cli rpcsvc */ -rpcsvc_actor_t gd_svc_cli_actors_ro[] = { +rpcsvc_actor_t gd_svc_cli_actors_ro[GLUSTER_CLI_MAXVALUE] = { [GLUSTER_CLI_LIST_FRIENDS] = { "LIST_FRIENDS", GLUSTER_CLI_LIST_FRIENDS, glusterd_handle_cli_list_friends, NULL, 0, DRC_NA}, [GLUSTER_CLI_UUID_GET] = { "UUID_GET", GLUSTER_CLI_UUID_GET, glusterd_handle_cli_uuid_get, NULL, 0, DRC_NA}, [GLUSTER_CLI_GET_VOLUME] = { "GET_VOLUME", GLUSTER_CLI_GET_VOLUME, glusterd_handle_cli_get_volume, NULL, 0, DRC_NA}, diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c index 87958d0701b..71100c0d409 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handshake.c +++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c @@ -727,7 +727,7 @@ server_get_volume_info (rpcsvc_request_t *req) __server_get_volume_info); } -rpcsvc_actor_t gluster_handshake_actors[] = { +rpcsvc_actor_t gluster_handshake_actors[GF_HNDSK_MAXVALUE] = { [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, NULL, NULL, 0, DRC_NA}, [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, 0, DRC_NA}, [GF_HNDSK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_HNDSK_EVENT_NOTIFY, server_event_notify, NULL, 0, DRC_NA}, @@ -744,7 +744,7 @@ struct rpcsvc_program gluster_handshake_prog = { }; /* A minimal RPC program just for the cli getspec command */ -rpcsvc_actor_t gluster_cli_getspec_actors[] = { +rpcsvc_actor_t gluster_cli_getspec_actors[GF_HNDSK_MAXVALUE] = { [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, 0, DRC_NA}, }; @@ -770,16 +770,16 @@ rpc_clnt_prog_t glusterd_dump_prog = { }; -rpcsvc_actor_t glusterd_mgmt_hndsk_actors[] = { +rpcsvc_actor_t glusterd_mgmt_hndsk_actors[GD_MGMT_HNDSK_MAXVALUE] = { [GD_MGMT_HNDSK_NULL] = {"NULL", GD_MGMT_HNDSK_NULL, NULL, - NULL, 0}, + NULL, 0, DRC_NA}, [GD_MGMT_HNDSK_VERSIONS] = {"MGMT-VERS", GD_MGMT_HNDSK_VERSIONS, glusterd_mgmt_hndsk_versions, NULL, - 0}, + 0, DRC_NA}, [GD_MGMT_HNDSK_VERSIONS_ACK] = {"MGMT-VERS-ACK", GD_MGMT_HNDSK_VERSIONS_ACK, glusterd_mgmt_hndsk_versions_ack, - NULL, 0}, + NULL, 0, DRC_NA}, }; struct rpcsvc_program glusterd_mgmt_hndsk_prog = { diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.c b/xlators/mgmt/glusterd/src/glusterd-pmap.c index a153ca1a947..a54a87b1d33 100644 --- a/xlators/mgmt/glusterd/src/glusterd-pmap.c +++ b/xlators/mgmt/glusterd/src/glusterd-pmap.c @@ -473,13 +473,13 @@ gluster_pmap_signout (rpcsvc_request_t *req) return glusterd_big_locked_handler (req, __gluster_pmap_signout); } -rpcsvc_actor_t gluster_pmap_actors[] = { +rpcsvc_actor_t gluster_pmap_actors[GF_PMAP_MAXVALUE] = { [GF_PMAP_NULL] = {"NULL", GF_PMAP_NULL, NULL, NULL, 0, DRC_NA}, [GF_PMAP_PORTBYBRICK] = {"PORTBYBRICK", GF_PMAP_PORTBYBRICK, gluster_pmap_portbybrick, NULL, 0, DRC_NA}, [GF_PMAP_BRICKBYPORT] = {"BRICKBYPORT", GF_PMAP_BRICKBYPORT, gluster_pmap_brickbyport, NULL, 0, DRC_NA}, + [GF_PMAP_SIGNUP] = {"SIGNUP", GF_PMAP_SIGNUP, gluster_pmap_signup, NULL, 0, DRC_NA}, [GF_PMAP_SIGNIN] = {"SIGNIN", GF_PMAP_SIGNIN, gluster_pmap_signin, NULL, 0, DRC_NA}, [GF_PMAP_SIGNOUT] = {"SIGNOUT", GF_PMAP_SIGNOUT, gluster_pmap_signout, NULL, 0, DRC_NA}, - [GF_PMAP_SIGNUP] = {"SIGNUP", GF_PMAP_SIGNUP, gluster_pmap_signup, NULL, 0, DRC_NA}, }; diff --git a/xlators/nfs/server/src/acl3.c b/xlators/nfs/server/src/acl3.c index 5286077a891..566e43a75bf 100644 --- a/xlators/nfs/server/src/acl3.c +++ b/xlators/nfs/server/src/acl3.c @@ -614,9 +614,9 @@ rpcerr: rpcsvc_actor_t acl3svc_actors[ACL3_PROC_COUNT] = { - {"NULL", ACL3_NULL, acl3svc_null, NULL, 0}, - {"GETACL", ACL3_GETACL, acl3svc_getacl, NULL, 0}, - {"SETACL", ACL3_SETACL, acl3svc_setacl, NULL, 0}, + {"NULL", ACL3_NULL, acl3svc_null, NULL, 0, DRC_NA}, + {"GETACL", ACL3_GETACL, acl3svc_getacl, NULL, 0, DRC_NA}, + {"SETACL", ACL3_SETACL, acl3svc_setacl, NULL, 0, DRC_NA}, }; rpcsvc_program_t acl3prog = { diff --git a/xlators/protocol/client/src/client-callback.c b/xlators/protocol/client/src/client-callback.c index d886862f776..b2707cb395b 100644 --- a/xlators/protocol/client/src/client-callback.c +++ b/xlators/protocol/client/src/client-callback.c @@ -40,7 +40,7 @@ client_cbk_ino_flush (struct rpc_clnt *rpc, void *mydata, void *data) return 0; } -rpcclnt_cb_actor_t gluster_cbk_actors[] = { +rpcclnt_cb_actor_t gluster_cbk_actors[GF_CBK_MAXVALUE] = { [GF_CBK_NULL] = {"NULL", GF_CBK_NULL, client_cbk_null }, [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, client_cbk_fetchspec }, [GF_CBK_INO_FLUSH] = {"INO_FLUSH", GF_CBK_INO_FLUSH, client_cbk_ino_flush }, diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c index d4941011da9..38c06b5b113 100644 --- a/xlators/protocol/server/src/server-handshake.c +++ b/xlators/protocol/server/src/server-handshake.c @@ -763,7 +763,7 @@ fail: return 0; } -rpcsvc_actor_t gluster_handshake_actors[] = { +rpcsvc_actor_t gluster_handshake_actors[GF_HNDSK_MAXVALUE] = { [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, server_null, NULL, 0, DRC_NA}, [GF_HNDSK_SETVOLUME] = {"SETVOLUME", GF_HNDSK_SETVOLUME, server_setvolume, NULL, 0, DRC_NA}, [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, 0, DRC_NA}, diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c index b6b74dd2b2f..e67d168d84d 100644 --- a/xlators/protocol/server/src/server-rpc-fops.c +++ b/xlators/protocol/server/src/server-rpc-fops.c @@ -6135,7 +6135,7 @@ out: } -rpcsvc_actor_t glusterfs3_3_fop_actors[] = { +rpcsvc_actor_t glusterfs3_3_fop_actors[GLUSTER_FOP_PROCCNT] = { [GFS3_OP_NULL] = {"NULL", GFS3_OP_NULL, server_null, NULL, 0, DRC_NA}, [GFS3_OP_STAT] = {"STAT", GFS3_OP_STAT, server3_3_stat, NULL, 0, DRC_NA}, [GFS3_OP_READLINK] = {"READLINK", GFS3_OP_READLINK, server3_3_readlink, NULL, 0, DRC_NA}, -- cgit