]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
rpc_servers: Fix crash with many interfaces
authorVolker Lendecke <vl@samba.org>
Thu, 31 Dec 2020 14:10:10 +0000 (15:10 +0100)
committerVolker Lendecke <vl@samba.org>
Mon, 11 Jan 2021 13:19:32 +0000 (13:19 +0000)
Previously, the lowlevel routines wrote into the pf_listen_fd arrays
without checking its size.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Samuel Cabrero <scabrero@samba.org>
source3/printing/spoolssd.c
source3/rpc_server/lsasd.c
source3/rpc_server/mdssd.c

index dc2b85912a9a075511f9359422568bae2b6514e9..8da1a7e392dfeca59e5062957f264b653dc8d9e3 100644 (file)
@@ -580,51 +580,32 @@ static char *get_bq_logfile(void)
 static NTSTATUS spoolssd_create_sockets(struct tevent_context *ev_ctx,
                struct messaging_context *msg_ctx,
                struct dcesrv_context *dce_ctx,
-               struct pf_listen_fd *listen_fd,
-               int *listen_fd_size)
+               TALLOC_CTX *mem_ctx,
+               struct pf_listen_fd **plisten_fds,
+               size_t *pnum_listen_fds)
 {
        NTSTATUS status;
        int fd = -1;
        int rc;
        enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
-       int i;
-       struct dcesrv_endpoint *e = NULL;
+       size_t i, num_fds;
+       struct pf_listen_fd *fds = NULL;
+       struct dcesrv_endpoint *e = dce_ctx->endpoint_list;
 
        DBG_INFO("Initializing DCE/RPC connection endpoints\n");
 
-       for (e = dce_ctx->endpoint_list; e; e = e->next) {
-               int *fds = NULL;
-               size_t j, num_fds;
-
-               status = dcesrv_create_endpoint_sockets(ev_ctx,
-                                                       msg_ctx,
-                                                       dce_ctx,
-                                                       e,
-                                                       dce_ctx,
-                                                       &num_fds,
-                                                       &fds);
-               if (!NT_STATUS_IS_OK(status)) {
-                       char *ep_string = dcerpc_binding_string(
-                                       dce_ctx, e->ep_description);
-                       DBG_ERR("Failed to create endpoint '%s': %s\n",
-                               ep_string, nt_errstr(status));
-                       TALLOC_FREE(ep_string);
-                       goto done;
-               }
-               for (j=0; j<num_fds; j++) {
-                       listen_fd[*listen_fd_size].fd = fds[j];
-                       listen_fd[*listen_fd_size].fd_data = e;
-                       (*listen_fd_size)++;
-               }
-               TALLOC_FREE(fds);
+       status = dcesrv_create_endpoint_list_pf_listen_fds(
+               ev_ctx, msg_ctx, dce_ctx, e, mem_ctx, &num_fds, &fds);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
-       for (i = 0; i < *listen_fd_size; i++) {
-               rc = listen(listen_fd[i].fd, pf_spoolss_cfg.max_allowed_clients);
+       for (i = 0; i < num_fds; i++) {
+               rc = listen(fds[i].fd, pf_spoolss_cfg.max_allowed_clients);
                if (rc == -1) {
                        char *ep_string = NULL;
+                       e = fds[i].fd_data;
 
-                       e = listen_fd[i].fd_data;
                        ep_string = dcerpc_binding_string(dce_ctx,
                                                          e->ep_description);
                        DBG_ERR("Failed to listen on endpoint '%s': %s\n",
@@ -654,6 +635,9 @@ static NTSTATUS spoolssd_create_sockets(struct tevent_context *ev_ctx,
                }
        }
 
+       *plisten_fds = fds;
+       *pnum_listen_fds = num_fds;
+
        status = NT_STATUS_OK;
 done:
        if (fd != -1) {
@@ -669,8 +653,8 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx,
 {
        pid_t pid;
        NTSTATUS status;
-       struct pf_listen_fd listen_fds[1];
-       int listen_fds_size = 0;
+       struct pf_listen_fd *listen_fds = NULL;
+       size_t listen_fds_size = 0;
        int ret;
        bool ok;
        const struct dcesrv_endpoint_server *ep_server = NULL;
@@ -784,7 +768,8 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx,
        status = spoolssd_create_sockets(ev_ctx,
                                         msg_ctx,
                                         dce_ctx,
-                                        listen_fds,
+                                        dce_ctx,
+                                        &listen_fds,
                                         &listen_fds_size);
        if (!NT_STATUS_IS_OK(status)) {
                DBG_ERR("Failed to create sockets: %s\n",
@@ -800,6 +785,7 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx,
                                 pf_spoolss_cfg.max_children,
                                 &spoolss_children_main, dce_ctx,
                                 &spoolss_pool);
+       TALLOC_FREE(listen_fds);
        if (!ok) {
                exit(1);
        }
index 85c4f880c5fbe29166ccc13cc3a3fcdc037ab981..b63de38991a5a3ac32bf0e2429af59ace1c285ae 100644 (file)
@@ -48,7 +48,6 @@
 #define DBGC_CLASS DBGC_RPC_SRV
 
 #define DAEMON_NAME "lsasd"
-#define LSASD_MAX_SOCKETS 64
 
 static struct server_id parent_id;
 static struct prefork_pool *lsasd_pool = NULL;
@@ -546,50 +545,31 @@ static void lsasd_check_children(struct tevent_context *ev_ctx,
 static NTSTATUS lsasd_create_sockets(struct tevent_context *ev_ctx,
                                     struct messaging_context *msg_ctx,
                                     struct dcesrv_context *dce_ctx,
-                                    struct pf_listen_fd *listen_fd,
-                                    int *listen_fd_size)
+                                    TALLOC_CTX *mem_ctx,
+                                    struct pf_listen_fd **plisten_fds,
+                                    size_t *pnum_listen_fds)
 {
        NTSTATUS status;
-       int i;
        int fd = -1;
+       size_t i, num_fds;
+       struct pf_listen_fd *fds = NULL;
        int rc;
-       struct dcesrv_endpoint *e = NULL;
+       struct dcesrv_endpoint *e = dce_ctx->endpoint_list;
 
        DBG_INFO("Initializing DCE/RPC connection endpoints\n");
 
-       for (e = dce_ctx->endpoint_list; e; e = e->next) {
-               int *fds = NULL;
-               size_t j, num_fds;
-
-               status = dcesrv_create_endpoint_sockets(ev_ctx,
-                                                       msg_ctx,
-                                                       dce_ctx,
-                                                       e,
-                                                       dce_ctx,
-                                                       &num_fds,
-                                                       &fds);
-               if (!NT_STATUS_IS_OK(status)) {
-                       char *ep_string = dcerpc_binding_string(
-                                       dce_ctx, e->ep_description);
-                       DBG_ERR("Failed to create endpoint '%s': %s\n",
-                               ep_string, nt_errstr(status));
-                       TALLOC_FREE(ep_string);
-                       goto done;
-               }
-               for (j=0; j<num_fds; j++) {
-                       listen_fd[*listen_fd_size].fd = fds[j];
-                       listen_fd[*listen_fd_size].fd_data = e;
-                       (*listen_fd_size)++;
-               }
-               TALLOC_FREE(fds);
+       status = dcesrv_create_endpoint_list_pf_listen_fds(
+               ev_ctx, msg_ctx, dce_ctx, e, mem_ctx, &num_fds, &fds);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
-       for (i = 0; i < *listen_fd_size; i++) {
-               rc = listen(listen_fd[i].fd, pf_lsasd_cfg.max_allowed_clients);
+       for (i = 0; i < num_fds; i++) {
+               rc = listen(fds[i].fd, pf_lsasd_cfg.max_allowed_clients);
                if (rc == -1) {
                        char *ep_string = NULL;
+                       e = fds[i].fd_data;
 
-                       e = listen_fd[i].fd_data;
                        ep_string = dcerpc_binding_string(dce_ctx,
                                                          e->ep_description);
                        DBG_ERR("Failed to listen on endpoint '%s': %s\n",
@@ -616,6 +596,9 @@ static NTSTATUS lsasd_create_sockets(struct tevent_context *ev_ctx,
                }
        }
 
+       *plisten_fds = fds;
+       *pnum_listen_fds = num_fds;
+
        status = NT_STATUS_OK;
 done:
        if (fd != -1) {
@@ -629,8 +612,8 @@ void start_lsasd(struct tevent_context *ev_ctx,
                 struct dcesrv_context *dce_ctx)
 {
        NTSTATUS status;
-       struct pf_listen_fd listen_fd[LSASD_MAX_SOCKETS];
-       int listen_fd_size = 0;
+       struct pf_listen_fd *listen_fd = NULL;
+       size_t listen_fd_size = 0;
        pid_t pid;
        int rc;
        bool ok;
@@ -748,7 +731,8 @@ void start_lsasd(struct tevent_context *ev_ctx,
        status = lsasd_create_sockets(ev_ctx,
                                      msg_ctx,
                                      dce_ctx,
-                                     listen_fd,
+                                     dce_ctx,
+                                     &listen_fd,
                                      &listen_fd_size);
        if (!NT_STATUS_IS_OK(status)) {
                exit(1);
@@ -765,6 +749,7 @@ void start_lsasd(struct tevent_context *ev_ctx,
                                 &lsasd_children_main,
                                 dce_ctx,
                                 &lsasd_pool);
+       TALLOC_FREE(listen_fd);
        if (!ok) {
                exit(1);
        }
index 7027a983c6a85e99b13257adaa233420e4c42f2f..62448577b9d56df6cacd9d938c06c6f6c9c634c0 100644 (file)
@@ -45,7 +45,6 @@
 #define DBGC_CLASS DBGC_RPC_SRV
 
 #define DAEMON_NAME "mdssd"
-#define MDSSD_MAX_SOCKETS 64
 
 static struct server_id parent_id;
 static struct prefork_pool *mdssd_pool = NULL;
@@ -496,50 +495,31 @@ static void mdssd_check_children(struct tevent_context *ev_ctx,
 static NTSTATUS mdssd_create_sockets(struct tevent_context *ev_ctx,
                                     struct messaging_context *msg_ctx,
                                     struct dcesrv_context *dce_ctx,
-                                    struct pf_listen_fd *listen_fd,
-                                    int *listen_fd_size)
+                                    TALLOC_CTX *mem_ctx,
+                                    struct pf_listen_fd **plisten_fds,
+                                    size_t *pnum_listen_fds)
 {
        NTSTATUS status;
        int fd = -1;
+       size_t i, num_fds;
+       struct pf_listen_fd *fds = NULL;
        int rc;
-       int i;
-       struct dcesrv_endpoint *e = NULL;
+       struct dcesrv_endpoint *e = dce_ctx->endpoint_list;
 
        DBG_INFO("Initializing DCE/RPC connection endpoints\n");
 
-       for (e = dce_ctx->endpoint_list; e; e = e->next) {
-               int *fds = NULL;
-               size_t j, num_fds;
-
-               status = dcesrv_create_endpoint_sockets(ev_ctx,
-                                                       msg_ctx,
-                                                       dce_ctx,
-                                                       e,
-                                                       dce_ctx,
-                                                       &num_fds,
-                                                       &fds);
-               if (!NT_STATUS_IS_OK(status)) {
-                       char *ep_string = dcerpc_binding_string(
-                                       dce_ctx, e->ep_description);
-                       DBG_ERR("Failed to create endpoint '%s': %s\n",
-                               ep_string, nt_errstr(status));
-                       TALLOC_FREE(ep_string);
-                       goto done;
-               }
-               for (j=0; j<num_fds; j++) {
-                       listen_fd[*listen_fd_size].fd = fds[j];
-                       listen_fd[*listen_fd_size].fd_data = e;
-                       (*listen_fd_size)++;
-               }
-               TALLOC_FREE(fds);
+       status = dcesrv_create_endpoint_list_pf_listen_fds(
+               ev_ctx, msg_ctx, dce_ctx, e, mem_ctx, &num_fds, &fds);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
-       for (i = 0; i < *listen_fd_size; i++) {
-               rc = listen(listen_fd[i].fd, pf_mdssd_cfg.max_allowed_clients);
+       for (i = 0; i < num_fds; i++) {
+               rc = listen(fds[i].fd, pf_mdssd_cfg.max_allowed_clients);
                if (rc == -1) {
                        char *ep_string = NULL;
+                       e = fds[i].fd_data;
 
-                       e = listen_fd[i].fd_data;
                        ep_string = dcerpc_binding_string(dce_ctx,
                                                          e->ep_description);
                        DBG_ERR("Failed to listen on endpoint '%s': %s\n",
@@ -566,6 +546,9 @@ static NTSTATUS mdssd_create_sockets(struct tevent_context *ev_ctx,
                }
        }
 
+       *plisten_fds = fds;
+       *pnum_listen_fds = num_fds;
+
        status = NT_STATUS_OK;
 done:
        if (fd != -1) {
@@ -579,8 +562,8 @@ void start_mdssd(struct tevent_context *ev_ctx,
                 struct dcesrv_context *dce_ctx)
 {
        NTSTATUS status;
-       struct pf_listen_fd listen_fd[MDSSD_MAX_SOCKETS];
-       int listen_fd_size = 0;
+       struct pf_listen_fd *listen_fd = NULL;
+       size_t listen_fd_size = 0;
        pid_t pid;
        int rc;
        bool ok;
@@ -665,7 +648,8 @@ void start_mdssd(struct tevent_context *ev_ctx,
        status = mdssd_create_sockets(ev_ctx,
                                      msg_ctx,
                                      dce_ctx,
-                                     listen_fd,
+                                     dce_ctx,
+                                     &listen_fd,
                                      &listen_fd_size);
        if (!NT_STATUS_IS_OK(status)) {
                exit(1);
@@ -682,6 +666,7 @@ void start_mdssd(struct tevent_context *ev_ctx,
                                 &mdssd_children_main,
                                 dce_ctx,
                                 &mdssd_pool);
+       TALLOC_FREE(listen_fd);
        if (!ok) {
                exit(1);
        }