summaryrefslogtreecommitdiffstats
path: root/generic/tclMain.c
diff options
context:
space:
mode:
authorbch <brad.harder@gmail.com>2022-01-28 23:28:24 (GMT)
committerbch <brad.harder@gmail.com>2022-01-28 23:28:24 (GMT)
commitcc66f3601ff68b38489ca84cb582dbbe3ea804ef (patch)
treedd332c3d1379898dc1d9f733887ea3640948943b /generic/tclMain.c
parent5c2bc08ea4edc13e386422d6c6f86bb65014a0a3 (diff)
downloadtcl-cc66f3601ff68b38489ca84cb582dbbe3ea804ef.zip
tcl-cc66f3601ff68b38489ca84cb582dbbe3ea804ef.tar.gz
tcl-cc66f3601ff68b38489ca84cb582dbbe3ea804ef.tar.bz2
rejig argv/argc handling in response to investigation prompted by [https://arstechnica.com/information-technology/2022/01/a-bug-lurking-for-
12-years-gives-attackers-root-on-every-major-linux-distro/|this "polkit issue"] and some experimenting w/ execve() (ab)use. Essentially port of [0e1d2702ab] and its parent; discussed at length on IRC
Diffstat (limited to 'generic/tclMain.c')
-rw-r--r--generic/tclMain.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/generic/tclMain.c b/generic/tclMain.c
index bb48dbb..f1b1ae2 100644
--- a/generic/tclMain.c
+++ b/generic/tclMain.c
@@ -288,6 +288,8 @@ Tcl_MainEx(
* but before starting to execute commands. */
Tcl_Interp *interp)
{
+ char *progname = NULL; /* may/may-not be able to use argv[0] */
+ int i=0; /* argv[i] index */
Tcl_Obj *path, *resultPtr, *argvPtr, *appName;
const char *encodingName = NULL;
int code, exitCode = 0;
@@ -296,7 +298,14 @@ Tcl_MainEx(
InteractiveState is;
TclpSetInitialEncodings();
- TclpFindExecutable((const char *)argv[0]);
+ if (0 < argc) {
+ progname = argv[0];
+ --argc; /* consume argv[0] */
+ ++i;
+ }
+ TclpFindExecutable ((const char *)progname); /* nb: this could be NULL
+ * w/ (eg) a malformed
+ * execve() */
Tcl_InitMemory(interp);
@@ -318,36 +327,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]),
Tcl_GetString(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(progname);
} 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);