diff options
author | bch <brad.harder@gmail.com> | 2022-01-28 08:29:14 (GMT) |
---|---|---|
committer | bch <brad.harder@gmail.com> | 2022-01-28 08:29:14 (GMT) |
commit | 60f5d30e4406df3a2d80e61d7d9972dce3293133 (patch) | |
tree | 43d2950292d741dd24544d58ee96b4bb365c9f95 /generic/tclMain.c | |
parent | af3e9b9825f98a98907966cdd71286c1f00c8bcf (diff) | |
download | tcl-60f5d30e4406df3a2d80e61d7d9972dce3293133.zip tcl-60f5d30e4406df3a2d80e61d7d9972dce3293133.tar.gz tcl-60f5d30e4406df3a2d80e61d7d9972dce3293133.tar.bz2 |
rejig argv/argc Tcl_MainEx() handling, prompted by outside discussion re: current [https://arstechnica.com/information-technology/2022/01/a-bug-lurking-for-12-years-gives-attackers-root-on-every-major-linux-distro/|polkit] issues, and comparisons of execve(2) abuse/mitigation (esp wrt OpenBSD); Probably most importantly, the access to argv has been limited to indexing, not swapping back/forth between indexing and advancing argv; pls review
Diffstat (limited to 'generic/tclMain.c')
-rw-r--r-- | generic/tclMain.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/generic/tclMain.c b/generic/tclMain.c index f175319..c2eee13 100644 --- a/generic/tclMain.c +++ b/generic/tclMain.c @@ -288,6 +288,7 @@ Tcl_MainEx( * but before starting to execute commands. */ Tcl_Interp *interp) { + int i=0; /* argv[i] index */ Tcl_Obj *path, *resultPtr, *argvPtr, *appName; const char *encodingName = NULL; int code, exitCode = 0; @@ -296,7 +297,13 @@ Tcl_MainEx( InteractiveState is; TclpSetInitialEncodings(); - TclpFindExecutable((const char *)argv[0]); + if (0 < argc) { + --argc; /* consume argv[0] */ + ++i; + } + TclpFindExecutable((const char *)argv[0]); /* nb: this could be NULL + * w/ (eg) a malformed + * execve() */ Tcl_InitMemory(interp); @@ -318,36 +325,35 @@ Tcl_MainEx( * FILENAME */ - if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1])) + /* mind argc is being adjusted as we proceed */ + if ((argc >= 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1])) && ('-' != argv[3][0])) { Tcl_Obj *value = NewNativeObj(argv[2]); Tcl_SetStartupScript(NewNativeObj(argv[3]), TclGetString(value)); Tcl_DecrRefCount(value); argc -= 3; - argv += 3; - } else if ((argc > 1) && ('-' != argv[1][0])) { + i += 3; + } else if ((argc >= 1) && ('-' != argv[1][0])) { Tcl_SetStartupScript(NewNativeObj(argv[1]), NULL); argc--; - argv++; + i++; } } path = Tcl_GetStartupScript(&encodingName); if (path == NULL) { - appName = NewNativeObj(argv[0]); + appName = NewNativeObj(argv[0]); // nb: argv is _not_ advanced here... } else { appName = path; } Tcl_SetVar2Ex(interp, "argv0", NULL, appName, TCL_GLOBAL_ONLY); - argc--; - argv++; Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewWideIntObj(argc), TCL_GLOBAL_ONLY); argvPtr = Tcl_NewListObj(0, NULL); while (argc--) { - Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(*argv++)); + Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(argv[i++])); } Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY); |