From e07d6ea33bca4e354e32d4aa02b87e28f1d7c0f6 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Thu, 4 Dec 2014 20:03:39 +0100 Subject: [PATCH 1/6] spoolss: clear JobInfo on GetJob error In handling a spoolss GetJob request, the _spoolss_GetJob() handler may return an immediate error if one of the input parameters is invalid. If this is done without zeroing the pre-allocated @info pointer, then api_spoolss_GetJob() will attempt to marshall @info, which in the case of an @offered value of zero results in a marshalling error: ndr_push_error(7): Bad subcontext (PUSH) content_size 64 is larger than size_is(0) Bug: https://bugzilla.samba.org/show_bug.cgi?id=10984 Signed-off-by: David Disseldorp Reviewed-by: Andreas Schneider (cherry picked from commit 89869e090c56a3f83b451b437f9c3f40a231dd24) --- source3/rpc_server/spoolss/srv_spoolss_nt.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index c451212..6e3012c 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -9479,7 +9479,8 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, /* that's an [in out] buffer */ if (!r->in.buffer && (r->in.offered != 0)) { - return WERR_INVALID_PARAM; + result = WERR_INVALID_PARAM; + goto err_jinfo_free; } DEBUG(5,("_spoolss_GetJob\n")); @@ -9487,12 +9488,14 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, *r->out.needed = 0; if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { - return WERR_BADFID; + result = WERR_BADFID; + goto err_jinfo_free; } svc_name = lp_const_servicename(snum); if (svc_name == NULL) { - return WERR_INVALID_PARAM; + result = WERR_INVALID_PARAM; + goto err_jinfo_free; } result = winreg_get_printer_internal(p->mem_ctx, @@ -9501,22 +9504,22 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, svc_name, &pinfo2); if (!W_ERROR_IS_OK(result)) { - return result; + goto err_jinfo_free; } pdb = get_print_db_byname(svc_name); if (pdb == NULL) { DEBUG(3, ("failed to get print db for svc %s\n", svc_name)); - TALLOC_FREE(pinfo2); - return WERR_INVALID_PARAM; + result = WERR_INVALID_PARAM; + goto err_pinfo_free; } sysjob = jobid_to_sysjob_pdb(pdb, r->in.job_id); release_print_db(pdb); if (sysjob == -1) { DEBUG(3, ("no sysjob for spoolss jobid %u\n", r->in.job_id)); - TALLOC_FREE(pinfo2); - return WERR_INVALID_PARAM; + result = WERR_INVALID_PARAM; + goto err_pinfo_free; } count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status); @@ -9546,8 +9549,7 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, TALLOC_FREE(pinfo2); if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(r->out.info); - return result; + goto err_jinfo_free; } *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info, @@ -9555,6 +9557,12 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); + +err_pinfo_free: + TALLOC_FREE(pinfo2); +err_jinfo_free: + TALLOC_FREE(r->out.info); + return result; } /**************************************************************** -- 2.1.2 From b4aa8bf1a63c866dec9208f5ef852ff232369c5c Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 17 Dec 2014 15:21:33 +0100 Subject: [PATCH 2/6] spoolss: clear DriverInfo on GetPrinterDriver2 error In handling a spoolss GetPrinterDriver2 request, the handler may return an immediate error if one of the input parameters is invalid. If this is done without zeroing the pre-allocated @info pointer, then marshalling of the response will fail. Bug: https://bugzilla.samba.org/show_bug.cgi?id=10984 Signed-off-by: David Disseldorp Reviewed-by: Andreas Schneider (cherry picked from commit fb9ecb044ee986ab3496da6cbad162a224378475) --- source3/rpc_server/spoolss/srv_spoolss_nt.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index 6e3012c..d29d854 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -5681,14 +5681,16 @@ WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p, /* that's an [in out] buffer */ if (!r->in.buffer && (r->in.offered != 0)) { - return WERR_INVALID_PARAM; + result = WERR_INVALID_PARAM; + goto err_info_free; } DEBUG(4,("_spoolss_GetPrinterDriver2\n")); if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) { DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n")); - return WERR_INVALID_PRINTER_NAME; + result = WERR_INVALID_PRINTER_NAME; + goto err_info_free; } *r->out.needed = 0; @@ -5696,7 +5698,8 @@ WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p, *r->out.server_minor_version = 0; if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { - return WERR_BADFID; + result = WERR_BADFID; + goto err_info_free; } if (r->in.client_major_version == SPOOLSS_DRIVER_VERSION_2012) { @@ -5713,8 +5716,7 @@ WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p, r->in.architecture, version); if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(r->out.info); - return result; + goto err_info_free; } *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo, @@ -5722,6 +5724,10 @@ WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p, r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); + +err_info_free: + TALLOC_FREE(r->out.info); + return result; } -- 2.1.2 From b2207bf389ef81c8d2c95036cf82f674f7363635 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 17 Dec 2014 15:29:52 +0100 Subject: [PATCH 3/6] spoolss: clear FormInfo on GetForm error In handling a spoolss GetForm request, the handler may return an immediate error if one of the input parameters is invalid. If this is done without zeroing the pre-allocated @info pointer, then marshalling of the response will fail. Bug: https://bugzilla.samba.org/show_bug.cgi?id=10984 Signed-off-by: David Disseldorp Reviewed-by: Andreas Schneider (cherry picked from commit b113ed6043622cdec68f3a70631b363594f3a8d0) --- source3/rpc_server/spoolss/srv_spoolss_nt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index d29d854..cc5e652 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -7848,6 +7848,7 @@ WERROR _spoolss_GetForm(struct pipes_struct *p, /* that's an [in out] buffer */ if (!r->in.buffer && (r->in.offered != 0)) { + TALLOC_FREE(r->out.info); return WERR_INVALID_PARAM; } -- 2.1.2 From 6939504ac922a2f630ad9402cdd5fdf00403ac43 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 17 Dec 2014 15:54:22 +0100 Subject: [PATCH 4/6] spoolss: clear info on GetPrintProcessorDirectory error If an error is returned without zeroing a pre-allocated @info pointer, then marshalling of the response will fail. Bug: https://bugzilla.samba.org/show_bug.cgi?id=10984 Signed-off-by: David Disseldorp Reviewed-by: Andreas Schneider (cherry picked from commit 679c781112ce6b7cffca11c28e58ae5f9a0d717d) --- source3/rpc_server/spoolss/srv_spoolss_nt.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index cc5e652..5dfbc1a 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -10141,7 +10141,8 @@ WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p, /* that's an [in out] buffer */ if (!r->in.buffer && (r->in.offered != 0)) { - return WERR_INVALID_PARAM; + result = WERR_INVALID_PARAM; + goto err_info_free; } DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n", @@ -10157,7 +10158,8 @@ WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p, snum = find_service(talloc_tos(), "prnproc$", &prnproc_share); if (!prnproc_share) { - return WERR_NOMEM; + result = WERR_NOMEM; + goto err_info_free; } if (snum != -1) { prnproc_share_exists = true; @@ -10168,8 +10170,7 @@ WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p, r->in.environment, &r->out.info->info1); if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(r->out.info); - return result; + goto err_info_free; } *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, @@ -10177,6 +10178,10 @@ WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p, r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); + +err_info_free: + TALLOC_FREE(r->out.info); + return result; } /******************************************************************* -- 2.1.2 From bdde243d7b032f2df5997b0e3996be0e0ce4ec16 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 17 Dec 2014 16:47:50 +0100 Subject: [PATCH 5/6] spoolss: clear info on GetPrinterDriverDirectory error If an error is returned without zeroing a pre-allocated @info pointer, then marshalling of the response will fail. Bug: https://bugzilla.samba.org/show_bug.cgi?id=10984 Signed-off-by: David Disseldorp Reviewed-by: Andreas Schneider (cherry picked from commit c9fccb5018f9a19bb654b9ad79aa716e37a274d6) --- source3/rpc_server/spoolss/srv_spoolss_nt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index 5dfbc1a..cf2526d 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -8539,6 +8539,7 @@ WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p, /* that's an [in out] buffer */ if (!r->in.buffer && (r->in.offered != 0)) { + TALLOC_FREE(r->out.info); return WERR_INVALID_PARAM; } -- 2.1.2 From 97655d3245ce18fc8c7171dd7384bef42a11ae96 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 17 Dec 2014 16:54:42 +0100 Subject: [PATCH 6/6] spoolss: clear PrinterInfo on GetPrinter error If an error is returned without zeroing a pre-allocated @info pointer, then marshalling of the response will fail. Bug: https://bugzilla.samba.org/show_bug.cgi?id=10984 Signed-off-by: David Disseldorp Reviewed-by: Andreas Schneider (cherry picked from commit a11e97b79645ff0d9e7d20f5318a979194a858fe) --- source3/rpc_server/spoolss/srv_spoolss_nt.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index cf2526d..17eee50 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -4773,17 +4773,20 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p, /* that's an [in out] buffer */ if (!r->in.buffer && (r->in.offered != 0)) { - return WERR_INVALID_PARAM; + result = WERR_INVALID_PARAM; + goto err_info_free; } *r->out.needed = 0; if (Printer == NULL) { - return WERR_BADFID; + result = WERR_BADFID; + goto err_info_free; } if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { - return WERR_BADFID; + result = WERR_BADFID; + goto err_info_free; } result = winreg_get_printer_internal(p->mem_ctx, @@ -4792,7 +4795,7 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p, lp_const_servicename(snum), &info2); if (!W_ERROR_IS_OK(result)) { - goto out; + goto err_info_free; } switch (r->in.level) { @@ -4852,12 +4855,10 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p, } TALLOC_FREE(info2); - out: if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n", r->in.level, win_errstr(result))); - TALLOC_FREE(r->out.info); - return result; + goto err_info_free; } *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo, @@ -4865,6 +4866,10 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p, r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); + +err_info_free: + TALLOC_FREE(r->out.info); + return result; } /******************************************************************** -- 2.1.2