rpcsvc: Validate RPC procedure number before fetch
authorSantosh Kumar Pradhan <spradhan@redhat.com>
Fri, 9 May 2014 09:31:19 +0000 (15:01 +0530)
committerAnand Avati <avati@redhat.com>
Sat, 17 May 2014 18:56:01 +0000 (11:56 -0700)
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.

Special Thanks to: Murray Ketchion, Grant Byers

Change-Id: I8b5abd406d47fab8fca65b3beb73cdfe8cd85b72
BUG: 1096020
Signed-off-by: Santosh Kumar Pradhan <spradhan@redhat.com>
Reviewed-on: http://review.gluster.org/7726
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
Reviewed-by: Anand Avati <avati@redhat.com>
12 files changed:
api/src/glfs-mgmt.c
glusterfsd/src/glusterfsd-mgmt.c
rpc/rpc-lib/src/rpcsvc.c
xlators/features/quota/src/quotad-aggregator.c
xlators/mgmt/glusterd/src/glusterd-handler.c
xlators/mgmt/glusterd/src/glusterd-handshake.c
xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c
xlators/mgmt/glusterd/src/glusterd-pmap.c
xlators/nfs/server/src/acl3.c
xlators/protocol/client/src/client-callback.c
xlators/protocol/server/src/server-handshake.c
xlators/protocol/server/src/server-rpc-fops.c

index bb82dc9a18897bad3d82e535af52372cf0b8d5df..bac51ceee597ed3135395fa82ed2edcde11b9e39 100644 (file)
@@ -117,7 +117,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},
index bcc965696de8b72ca00b587529729203174ee378..e72483509be3ae7144524ba9ad6a03262cf6e083 100644 (file)
@@ -1331,7 +1331,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},
@@ -1378,7 +1378,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},
index be9f9a861f01a677bdadffe30c5a9d2c61a9dd29..c443a2e6a10c605a3e96022853e7f7d94a42d616 100644 (file)
@@ -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 < 0) || (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
@@ -2608,11 +2619,10 @@ 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_PING]      = {"PING",     GF_DUMP_PING,     rpcsvc_ping, NULL, 0, DRC_NA},
-        [GF_DUMP_MAXVALUE]  = {"MAXVALUE", GF_DUMP_MAXVALUE, NULL,        NULL, 0, DRC_NA},
 };
 
 
@@ -2621,5 +2631,5 @@ struct rpcsvc_program gluster_dump_prog = {
         .prognum   = GLUSTER_DUMP_PROGRAM,
         .progver   = GLUSTER_DUMP_VERSION,
         .actors    = gluster_dump_actors,
-        .numactors = sizeof (gluster_dump_actors) / sizeof (gluster_dump_actors[0]) - 1,
+        .numactors = GF_DUMP_MAXVALUE,
 };
index 5f13fd251c23e7c04a9941ce7667058a85c3e00a..a37a3728b5580dc2271ff2f4d9f3c51cc0130403 100644 (file)
@@ -404,13 +404,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},
 };
 
 
index 722ab983e4028951c890dd9b887deb7f69ee1713..bddc2db584363770a89d998d5f9cc541d86228c2 100644 (file)
@@ -4362,7 +4362,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},
@@ -4379,7 +4379,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},
@@ -4398,7 +4398,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},
@@ -4447,7 +4447,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},
index dbaa972937beff14e9df17bfe1d7d48fb4ec84c2..2901b98d84761d3efe20a65661d83263c6d53866 100644 (file)
@@ -1137,7 +1137,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},
@@ -1154,7 +1154,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},
 };
 
@@ -1170,6 +1170,7 @@ struct rpcsvc_program gluster_cli_getspec_prog = {
 char *glusterd_dump_proc[GF_DUMP_MAXVALUE] = {
         [GF_DUMP_NULL] = "NULL",
         [GF_DUMP_DUMP] = "DUMP",
+        [GF_DUMP_PING] = "PING",
 };
 
 rpc_clnt_prog_t glusterd_dump_prog = {
@@ -1180,16 +1181,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 = {
index 81c5aa57958a060320c9f7b2722f5f88de2d6d69..83325f758450ffeeebb571df90bbb3638976d8aa 100644 (file)
@@ -916,7 +916,7 @@ glusterd_handle_mgmt_v3_unlock (rpcsvc_request_t *req)
                                             glusterd_handle_mgmt_v3_unlock_fn);
 }
 
-rpcsvc_actor_t gd_svc_mgmt_v3_actors[] = {
+rpcsvc_actor_t gd_svc_mgmt_v3_actors[GLUSTERD_MGMT_V3_MAXVALUE] = {
         [GLUSTERD_MGMT_V3_NULL]          = { "NULL",           GLUSTERD_MGMT_V3_NULL,          glusterd_mgmt_v3_null,         NULL, 0, DRC_NA},
         [GLUSTERD_MGMT_V3_LOCK]          = { "MGMT_V3_LOCK",   GLUSTERD_MGMT_V3_LOCK,          glusterd_handle_mgmt_v3_lock,   NULL, 0, DRC_NA},
         [GLUSTERD_MGMT_V3_PRE_VALIDATE]  = { "PRE_VAL",        GLUSTERD_MGMT_V3_PRE_VALIDATE,  glusterd_handle_pre_validate,  NULL, 0, DRC_NA},
index a153ca1a947340d2c28adf34cf39448ee1b06f63..a54a87b1d33e978f89a2d820f3b0bc9eb7e538d2 100644 (file)
@@ -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},
 };
 
 
index 43156eb44b572c636cea2589cb5e77ba78fb62eb..42faffee854938de1b10cd9040e971d2d001d342 100644 (file)
@@ -626,9 +626,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 = {
index d886862f776ea17f85d6797220827cf9edabee98..b2707cb395b2cb32a03d738f093f11564a1fd2f5 100644 (file)
@@ -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 },
index f3ae96ef2ae93565a84a92ee4e2a73d65ef511e3..6b1a39936f493066e8cf65e3f8985e4c4fa04ec7 100644 (file)
@@ -766,7 +766,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},
index ee0d6b438c9b49c71df77c6c157b848b8ae8ec66..c77748d69f1900484f9b58b222dcad7e7a2c2a8f 100644 (file)
@@ -6136,7 +6136,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},