Date: Thu, 18 Jan 2007 14:10:40 +0100 From: Martin Kammerhofer <dada@pluto.tugraz.at> To: freebsd-gnats-submit@FreeBSD.org Subject: ports/108085: port devel/py-freebsd: reference counting bug Message-ID: <200701181310.l0IDAegR028055@pluto.tugraz.at> Resent-Message-ID: <200701181320.l0IDKF2U025589@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 108085 >Category: ports >Synopsis: port devel/py-freebsd: reference counting bug >Confidential: no >Severity: non-critical >Priority: high >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Thu Jan 18 13:20:15 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Martin Kammerhofer >Release: FreeBSD 6.2-PRERELEASE i386 >Organization: >Environment: System: FreeBSD Martin.liebt.Susi 6.2-PRERELEASE FreeBSD 6.2-PRERELEASE #2: Tue Dec 5 13:15:11 CET 2006 toor@Martin.liebt.Susi:/usr/src/sys/i386/compile/P2B-S i386 >Description: Bug #1: The Python wrapper freebsd.setprogname passes a temporary C pointer to setprogname(3). Libc's setprogname stashes this pointer rather than a copy of the referenced string. Therefore when libc uses this pointer later on -- e.g. for error reporting or setproctitle(3) -- it points to arbitrary data inside the Python interpreter. This bug can be trivially fixed by proper reference counting. Bug #2: The Python wrapper freebsd.setproctitle passes its raw string argument to setproctitle(3). This is a security risk whenever the string contains user-supplied data and well documented in the setproctitle(3) man page. >How-To-Repeat: # Bug #1: martin@Martin:~/patches$ python2.4 Python 2.4.4 (#2, Nov 28 2006, 22:41:53) [GCC 3.4.6 [FreeBSD] 20060305] on freebsd6 Type "help", "copyright", "credits" or "license" for more information. >Fix: --- TUTORIAL.orig Sun May 8 08:55:00 2005 +++ TUTORIAL Sat Nov 25 18:06:41 2006 @@ -165,7 +165,7 @@ 'rumble' >>> setproctitle('py-freebsd testing session') >>> os.system('ps auxw|grep freebsd') -perky 71593 0.0 0.8 6288 4176 p8 S+ 2:10AM 0:00.16 global: py-freebsd testing session (python) +perky 71593 0.0 0.8 6288 4176 p8 S+ 2:10AM 0:00.16 rumble: py-freebsd testing session (python) ==== --- src/process.c.orig Sun May 8 08:55:00 2005 +++ src/process.c Sat Nov 25 18:12:52 2006 @@ -51,10 +51,19 @@ static PyObject * PyFB_setprogname(PyObject *self, PyObject *args) { - char *progname; + const char *progname; + static PyObject *namestr = NULL; if (!PyArg_ParseTuple(args, "s:setprogname", &progname)) return NULL; + /* + * Setprogname(3) does not copy the string, it only stores the + * string pointer. Make sure that the string object does not + * get garbage collected and its memory reused! + */ + Py_XDECREF(namestr); /* maybe free old progname */ + PyArg_ParseTuple(args, "O", &namestr); + Py_INCREF(namestr); /* keep new progname object */ setprogname(progname); Py_RETURN_NONE; @@ -64,16 +73,24 @@ static char PyFB_setproctitle__doc__[] = "setproctitle(title):\n" "The setproctitle() library routine sets the process title that\n" -"appears on the ps(1) command."; +"appears on the ps(1) command. The progname and a colon are\n" +"prepended automatically. This behaviour is suppressed when the\n" +"title starts with a dash (-) character. Calling with a None\n" +"argument restores a default process title."; static PyObject * PyFB_setproctitle(PyObject *self, PyObject *args) { - char *newtitle; + const char *newtitle; - if (!PyArg_ParseTuple(args, "s:setproctitle", &newtitle)) + if (!PyArg_ParseTuple(args, "z:setproctitle", &newtitle)) return NULL; - setproctitle(newtitle); + if (newtitle == NULL) + setproctitle(NULL); + else if (*newtitle == '-') + setproctitle("-%s", newtitle+1); + else + setproctitle("%s", newtitle); Py_RETURN_NONE; } >Release-Note: >Audit-Trail: >Unformatted: >>> import freebsd, os, gc >>> progname = "Monty" >>> freebsd.setprogname(progname) >>> freebsd.getprogname() 'Monty' >>> progname = "Nasty" >>> gc.collect() 0 >>> freebsd.getprogname() '<stdin>' >>> # Bug #2: martin@Martin:~$ python2.4 Python 2.4.4 (#2, Nov 28 2006, 22:41:53) [GCC 3.4.6 [FreeBSD] 20060305] on freebsd6 Type "help", "copyright", "credits" or "license" for more information. >>> import freebsd, os >>> freebsd.setproctitle("%d%d%d%d%d%d%d") >>> os.system("ps %d" % os.getpid()) PID TT STAT TIME COMMAND 2171 p3 S+ 0:00,23 python2.4: 838570953-1077971584134712879136162644136155948-10779715281351665100 >>> freebsd.setproctitle("%s" * 99) Segmentation fault: 11 (core dumped)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200701181310.l0IDAegR028055>