9898 */
9999
100100#ifndef VERSION
101- #define VERSION "1.5 "
101+ #define VERSION "2.0 "
102102#endif
103103
104104#ifndef VPATH
122122#ifndef LANDMARK
123123#define LANDMARK "os.py"
124124#endif
125-
125+
126126static char prefix [MAXPATHLEN + 1 ];
127127static char exec_prefix [MAXPATHLEN + 1 ];
128128static char progpath [MAXPATHLEN + 1 ];
@@ -201,6 +201,11 @@ isdir(char *filename) /* Is directory */
201201}
202202
203203
204+ /* joinpath requires that any buffer argument passed to it has at
205+ least MAXPATHLEN + 1 bytes allocated. If this requirement is met,
206+ it guarantees that it will never overflow the buffer. If stuff
207+ is too long, buffer will contain a truncated copy of stuff.
208+ */
204209static void
205210joinpath (char * buffer , char * stuff )
206211{
@@ -219,6 +224,10 @@ joinpath(char *buffer, char *stuff)
219224 buffer [n + k ] = '\0' ;
220225}
221226
227+ /* init_path_from_argv0 requirs that path be allocated at least
228+ MAXPATHLEN + 1 bytes and that argv0_path be no more than MAXPATHLEN
229+ bytes.
230+ */
222231static void
223232init_path_from_argv0 (char * path , char * argv0_path )
224233{
@@ -237,6 +246,9 @@ init_path_from_argv0(char *path, char *argv0_path)
237246 }
238247}
239248
249+ /* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
250+ bytes long.
251+ */
240252static int
241253search_for_prefix (char * argv0_path , char * home )
242254{
@@ -246,7 +258,7 @@ search_for_prefix(char *argv0_path, char *home)
246258 /* If PYTHONHOME is set, we believe it unconditionally */
247259 if (home ) {
248260 char * delim ;
249- strcpy (prefix , home );
261+ strncpy (prefix , home , MAXPATHLEN );
250262 delim = strchr (prefix , DELIM );
251263 if (delim )
252264 * delim = '\0' ;
@@ -293,7 +305,7 @@ search_for_prefix(char *argv0_path, char *home)
293305 } while (prefix [0 ]);
294306
295307 /* Look at configure's PREFIX */
296- strcpy (prefix , PREFIX );
308+ strncpy (prefix , PREFIX , MAXPATHLEN );
297309 joinpath (prefix , lib_python );
298310 joinpath (prefix , LANDMARK );
299311 if (ismodule (prefix ))
@@ -304,6 +316,9 @@ search_for_prefix(char *argv0_path, char *home)
304316}
305317
306318
319+ /* search_for_exec_prefix requires that argv0_path be no more than
320+ MAXPATHLEN bytes long.
321+ */
307322static int
308323search_for_exec_prefix (char * argv0_path , char * home )
309324{
@@ -314,9 +329,9 @@ search_for_exec_prefix(char *argv0_path, char *home)
314329 char * delim ;
315330 delim = strchr (home , DELIM );
316331 if (delim )
317- strcpy (exec_prefix , delim + 1 );
332+ strncpy (exec_prefix , delim + 1 , MAXPATHLEN );
318333 else
319- strcpy (exec_prefix , home );
334+ strncpy (exec_prefix , home , MAXPATHLEN );
320335 joinpath (exec_prefix , lib_python );
321336 joinpath (exec_prefix , "lib-dynload" );
322337 return 1 ;
@@ -343,7 +358,7 @@ search_for_exec_prefix(char *argv0_path, char *home)
343358 } while (exec_prefix [0 ]);
344359
345360 /* Look at configure's EXEC_PREFIX */
346- strcpy (exec_prefix , EXEC_PREFIX );
361+ strncpy (exec_prefix , EXEC_PREFIX , MAXPATHLEN );
347362 joinpath (exec_prefix , lib_python );
348363 joinpath (exec_prefix , "lib-dynload" );
349364 if (isdir (exec_prefix ))
@@ -377,6 +392,7 @@ calculate_path(void)
377392#endif
378393
379394#ifdef WITH_NEXT_FRAMEWORK
395+ /* XXX Need to check this code for buffer overflows */
380396 pythonModule = NSModuleForSymbol (NSLookupAndBindSymbol ("_Py_Initialize" ));
381397 /* Use dylib functions to find out where the framework was loaded from */
382398 buf = NSLibraryNameForModule (pythonModule );
@@ -393,26 +409,30 @@ calculate_path(void)
393409#endif
394410
395411 /* Initialize this dynamically for K&R C */
396- sprintf (lib_python , "lib/python%s " , VERSION );
412+ sprintf (lib_python , "lib/python%.9s " , VERSION );
397413
398414 /* If there is no slash in the argv0 path, then we have to
399415 * assume python is on the user's $PATH, since there's no
400416 * other way to find a directory to start the search from. If
401417 * $PATH isn't exported, you lose.
402418 */
403419 if (strchr (prog , SEP ))
404- strcpy (progpath , prog );
420+ strncpy (progpath , prog , MAXPATHLEN );
405421 else if (path ) {
422+ int bufspace = MAXPATHLEN ;
406423 while (1 ) {
407424 char * delim = strchr (path , DELIM );
408425
409426 if (delim ) {
410427 size_t len = delim - path ;
428+ if (len > bufspace )
429+ len = bufspace ;
411430 strncpy (progpath , path , len );
412431 * (progpath + len ) = '\0' ;
432+ bufspace -= len ;
413433 }
414434 else
415- strcpy (progpath , path );
435+ strncpy (progpath , path , bufspace );
416436
417437 joinpath (progpath , prog );
418438 if (isxfile (progpath ))
@@ -431,7 +451,7 @@ calculate_path(void)
431451 }
432452#endif
433453
434- strcpy (argv0_path , progpath );
454+ strncpy (argv0_path , progpath , MAXPATHLEN );
435455
436456#if HAVE_READLINK
437457 {
@@ -441,7 +461,9 @@ calculate_path(void)
441461 /* It's not null terminated! */
442462 tmpbuffer [linklen ] = '\0' ;
443463 if (tmpbuffer [0 ] == SEP )
444- strcpy (argv0_path , tmpbuffer );
464+ /* tmpbuffer should never be longer than MAXPATHLEN,
465+ but extra check does not hurt */
466+ strncpy (argv0_path , tmpbuffer , MAXPATHLEN );
445467 else {
446468 /* Interpret relative to progpath */
447469 reduce (argv0_path );
@@ -453,12 +475,15 @@ calculate_path(void)
453475#endif /* HAVE_READLINK */
454476
455477 reduce (argv0_path );
478+ /* At this point, argv0_path is guaranteed to be less than
479+ MAXPATHLEN bytes long.
480+ */
456481
457482 if (!(pfound = search_for_prefix (argv0_path , home ))) {
458483 if (!Py_FrozenFlag )
459484 fprintf (stderr ,
460485 "Could not find platform independent libraries <prefix>\n" );
461- strcpy (prefix , PREFIX );
486+ strncpy (prefix , PREFIX , MAXPATHLEN );
462487 joinpath (prefix , lib_python );
463488 }
464489 else
@@ -468,7 +493,7 @@ calculate_path(void)
468493 if (!Py_FrozenFlag )
469494 fprintf (stderr ,
470495 "Could not find platform dependent libraries <exec_prefix>\n" );
471- strcpy (exec_prefix , EXEC_PREFIX );
496+ strncpy (exec_prefix , EXEC_PREFIX , MAXPATHLEN );
472497 joinpath (exec_prefix , "lib/lib-dynload" );
473498 }
474499 /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
@@ -565,15 +590,15 @@ calculate_path(void)
565590 reduce (prefix );
566591 }
567592 else
568- strcpy (prefix , PREFIX );
593+ strncpy (prefix , PREFIX , MAXPATHLEN );
569594
570595 if (efound > 0 ) {
571596 reduce (exec_prefix );
572597 reduce (exec_prefix );
573598 reduce (exec_prefix );
574599 }
575600 else
576- strcpy (exec_prefix , EXEC_PREFIX );
601+ strncpy (exec_prefix , EXEC_PREFIX , MAXPATHLEN );
577602}
578603
579604
0 commit comments