r9086: * fix invalid read in parse_spoolss when writing a devmode to
authorGerald Carter <jerry@samba.org>
Fri, 5 Aug 2005 00:58:31 +0000 (00:58 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:00:25 +0000 (11:00 -0500)
  the wire
* fix dup_a_regval() when size is 0
* ensure we pass a pstring to unlink_internals (fixes delete_driver
  code)
(This used to be commit 353e63ff421c564a1b7c7cfe95982f31c871a227)

source3/printing/nt_printing.c
source3/registry/reg_objects.c
source3/rpc_parse/parse_spoolss.c

index a7ba46cd511dc23aab16e7fbe09198640bbcfa7f..f6e9e2306f512ed8bc044718f22b9e9c7ff48462 100644 (file)
@@ -2102,19 +2102,20 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
                fstring *tddfs;
 
                tddfs = SMB_REALLOC_ARRAY(driver.dependentfiles, fstring, i+2);
-               if (tddfs == NULL) {
+               if ( !tddfs ) {
                        DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
                        break;
                }
-               else driver.dependentfiles = tddfs;
+               else 
+                       driver.dependentfiles = tddfs;
 
                len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
                                  &driver.dependentfiles[i]);
                i++;
        }
        
-       if (driver.dependentfiles != NULL)
-               fstrcpy(driver.dependentfiles[i], "");
+       if ( driver.dependentfiles )
+               fstrcpy( driver.dependentfiles[i], "" );
 
        SAFE_FREE(dbuf.dptr);
 
@@ -4944,6 +4945,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
 {
        int i = 0;
        char *s;
+       pstring file;
        connection_struct *conn;
        DATA_BLOB null_pw;
        NTSTATUS nt_status;
@@ -4985,45 +4987,50 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
        
        if ( *info_3->driverpath ) {
                if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) {
-                       driver_unix_convert(s, conn, NULL, &bad_path, &st);
+                       pstrcpy( file, s );
+                       driver_unix_convert(file, conn, NULL, &bad_path, &st);
                        DEBUG(10,("deleting driverfile [%s]\n", s));
-                       unlink_internals(conn, 0, s);
+                       unlink_internals(conn, 0, file);
                }
        }
                
        if ( *info_3->configfile ) {
                if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
-                       driver_unix_convert(s, conn, NULL, &bad_path, &st);
+                       pstrcpy( file, s );
+                       driver_unix_convert(file, conn, NULL, &bad_path, &st);
                        DEBUG(10,("deleting configfile [%s]\n", s));
-                       unlink_internals(conn, 0, s);
+                       unlink_internals(conn, 0, file);
                }
        }
        
        if ( *info_3->datafile ) {
                if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
-                       driver_unix_convert(s, conn, NULL, &bad_path, &st);
+                       pstrcpy( file, s );
+                       driver_unix_convert(file, conn, NULL, &bad_path, &st);
                        DEBUG(10,("deleting datafile [%s]\n", s));
-                       unlink_internals(conn, 0, s);
+                       unlink_internals(conn, 0, file);
                }
        }
        
        if ( *info_3->helpfile ) {
                if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
-                       driver_unix_convert(s, conn, NULL, &bad_path, &st);
+                       pstrcpy( file, s );
+                       driver_unix_convert(file, conn, NULL, &bad_path, &st);
                        DEBUG(10,("deleting helpfile [%s]\n", s));
-                       unlink_internals(conn, 0, s);
+                       unlink_internals(conn, 0, file);
                }
        }
        
        /* check if we are done removing files */
        
        if ( info_3->dependentfiles ) {
-               while ( *info_3->dependentfiles[i] ) {
-                       char *file;
+               while ( info_3->dependentfiles[i][0] ) {
+                       char *p;
 
                        /* bypass the "\print$" portion of the path */
                        
-                       if ( (file = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
+                       if ( (p = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
+                               pstrcpy( file, p );
                                driver_unix_convert(file, conn, NULL, &bad_path, &st);
                                DEBUG(10,("deleting dependent file [%s]\n", file));
                                unlink_internals(conn, 0, file );
index d6482e698b034f56c8f53a7f0f4e711ce008f911..b5753fc68852e8e722aeff57557320b3d85b6dae 100644 (file)
@@ -194,13 +194,18 @@ REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
        /* copy all the non-pointer initial data */
        
        memcpy( copy, val, sizeof(REGISTRY_VALUE) );
-       if ( val->data_p ) 
+       
+       copy->size = 0;
+       copy->data_p = NULL;
+       
+       if ( val->data_p && val->size ) 
        {
                if ( !(copy->data_p = memdup( val->data_p, val->size )) ) {
                        DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
                                val->size));
                        SAFE_FREE( copy );
                }
+               copy->size = val->size;
        }
        
        return copy;    
index 2663b09381225a46e60375427cfe7c156eb4f6b0..2677a4a2df0a98a707afd6c94746635d2bd96c65 100644 (file)
@@ -631,6 +631,8 @@ BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE
        int available_space;            /* size of the device mode left to parse */
                                        /* only important on unmarshalling       */
        int i = 0;
+       uint16 *unistr_buffer;
+       int j;
                                        
        struct optional_fields {
                fstring         name;
@@ -662,12 +664,20 @@ BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE
        depth++;
 
        if (UNMARSHALLING(ps)) {
-               devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, 32);
+               devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
                if (devmode->devicename.buffer == NULL)
                        return False;
+               unistr_buffer = devmode->devicename.buffer;
        }
-
-       if (!prs_uint16uni(True,"devicename", ps, depth, devmode->devicename.buffer, MAXDEVICENAME))
+       else {
+               /* devicename is a static sized string but the buffer we set is not */
+               unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
+               memset( unistr_buffer, 0x0, MAXDEVICENAME );
+               for ( j=0; devmode->devicename.buffer[j]; j++ )
+                       unistr_buffer[j] = devmode->devicename.buffer[j];
+       }
+               
+       if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME))
                return False;
        
        if (!prs_uint16("specversion",      ps, depth, &devmode->specversion))
@@ -709,12 +719,20 @@ BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE
                return False;
 
        if (UNMARSHALLING(ps)) {
-               devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, 32);
+               devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
                if (devmode->formname.buffer == NULL)
                        return False;
+               unistr_buffer = devmode->formname.buffer;
        }
-
-       if (!prs_uint16uni(True, "formname",  ps, depth, devmode->formname.buffer, 32))
+       else {
+               /* devicename is a static sized string but the buffer we set is not */
+               unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
+               memset( unistr_buffer, 0x0, MAXDEVICENAME );
+               for ( j=0; devmode->formname.buffer[j]; j++ )
+                       unistr_buffer[j] = devmode->formname.buffer[j];
+       }
+       
+       if (!prs_uint16uni(True, "formname",  ps, depth, unistr_buffer, MAXDEVICENAME))
                return False;
        if (!prs_uint16("logpixels",        ps, depth, &devmode->logpixels))
                return False;