commit eb78be9beeee01dcf137e60559f5ac26c3fe2c13 Author: Damian Johnson atagar@torproject.org Date: Mon May 2 21:04:17 2011 -0700
fix: Making the process name setter safer/better
fixes include: - just using memset rather than maually filling with null chars - using \0 arg dividers - erroring out rather than clobber env (ie, refuse to use a process name longer than the original argv) --- src/starter.py | 2 +- src/util/procname.py | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/src/starter.py b/src/starter.py index 365676c..5b73a73 100644 --- a/src/starter.py +++ b/src/starter.py @@ -392,7 +392,7 @@ if __name__ == '__main__':
try: from util import procname - procname.renameProcess("arm %s" % " ".join(sys.argv[1:])) + procname.renameProcess("arm\0%s" % "\0".join(sys.argv[1:])) except: pass
cli.controller.startTorMonitor(time.time() - initTime, expandedEvents, param["startup.blindModeEnabled"]) diff --git a/src/util/procname.py b/src/util/procname.py index 7641c5a..14a82b8 100644 --- a/src/util/procname.py +++ b/src/util/procname.py @@ -19,10 +19,6 @@ from util import sysTools # flag for setting the process name, found in '/usr/include/linux/prctl.h' PR_SET_NAME = 15
-# Maximum number of characters we'll set the process name to. Evidently this -# cap was simply chosen since it didn't cause a segfault for its author. -MAX_CHAR = 1608 - argc_t = ctypes.POINTER(ctypes.c_char_p)
Py_GetArgcArgv = ctypes.pythonapi.Py_GetArgcArgv @@ -32,6 +28,7 @@ Py_GetArgcArgv.argtypes = [ctypes.POINTER(ctypes.c_int),
# tracks the last name we've changed the process to currentProcessName = None +maxNameLength = -1
def renameProcess(processName): """ @@ -53,7 +50,7 @@ def _setArgv(processName): strcpy(argv[0], "new_name"); """
- global currentProcessName + global currentProcessName, maxNameLength
argv = ctypes.c_int(0) argc = argc_t() @@ -66,7 +63,7 @@ def _setArgv(processName): # for Jake's implementation on this.
if currentProcessName == None: - # Using argv via... + # Getting argv via... # currentProcessName = " ".join(["python"] + sys.argv) # # doesn't do the trick since this will miss interpretor arguments like... @@ -82,18 +79,20 @@ def _setArgv(processName): # python ./src/starter.py
currentProcessName = psResults[1] + maxNameLength = len(currentProcessName)
if not currentProcessName: raise IOError("unable to determine our process name")
- # we need to fill extra space with null characters, otherwise the process - # will end with a '?' when you run ps against it - if len(currentProcessName) > len(processName): - processName += "\0" * (len(currentProcessName) - len(processName)) + if len(processName) > maxNameLength: + msg = "can't rename process to something longer than our initial name since this would overwrite memory used for the env" + raise IOError(msg) + + # space we need to clear + zeroSize = max(len(currentProcessName), len(processName))
- size = min(len(processName), MAX_CHAR) - ctypes.memset(argc.contents, 0, size + 1) # null terminate the string's end - ctypes.memmove(argc.contents, processName, size) + ctypes.memset(argc.contents, 0, zeroSize + 1) # null terminate the string's end + ctypes.memmove(argc.contents, processName, len(processName)) currentProcessName = processName[:MAX_CHAR]
def _setPrctlName(processName):