VirtualBox

Changeset 86624 in vbox for trunk/src/libs/xpcom18a4/python


Ignore:
Timestamp:
Oct 19, 2020 10:01:45 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
140998
Message:

xpcom/python: Check the offset used by PyXPCOMGetObTypeName. bugref:9840

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/python/src/TypeObject.cpp

    r86333 r86624  
    5050#include <nsXPCOM.h>
    5151#include <nsISupportsPrimitives.h>
     52
     53#if defined(Py_LIMITED_API) && defined(RT_OS_LINUX)
     54# include <features.h>
     55# ifdef __GLIBC_PREREQ
     56#  if __GLIBC_PREREQ(2,9)
     57#   define PYXPCOM_HAVE_PIPE2
     58#   include <fcntl.h>
     59#  endif
     60# endif
     61#endif
    5262
    5363
     
    90100 * Gets the base XPCOM interface type object, creating it if needed.
    91101 */
    92 static PyTypeObject *PyXPCOM_GetInterfaceType(void)
    93 {
    94         PyTypeObject *pTypeObj = g_pPyInterfaceTypeObj;
    95         if (pTypeObj)
    96                 return pTypeObj;
    97 
     102static PyTypeObject *PyXPCOM_CreateInterfaceType(void)
     103{
    98104        static char g_szTypeDoc[] = "Define the behavior of a PythonCOM Interface type."; /* need non-const */
    99105        PyType_Slot aTypeSlots[] = {
     
    101107                { 0, NULL } /* terminator */
    102108        };
     109        static const char g_szClassNm[] = "interface-type";
    103110        PyType_Spec TypeSpec = {
    104                 /* .name: */            "interface-type",
     111                /* .name: */            g_szClassNm,
    105112                /* .basicsize: */       0,
    106113                /* .itemsize: */        0,
     
    112119        PyErr_Fetch(&exc_typ, &exc_val, &exc_tb); /* goes south in PyType_Ready if we don't clear exceptions first. */
    113120
    114         pTypeObj = (PyTypeObject *)PyType_FromSpec(&TypeSpec);
     121        PyTypeObject *pTypeObj = (PyTypeObject *)PyType_FromSpec(&TypeSpec);
    115122        assert(pTypeObj);
    116123
     
    120127        /*
    121128         * Verify/correct g_offObTypeNameMember.
     129         *
     130         * Using pipe+write to probe the memory content, banking on the kernel
     131         * to return EFAULT when we pass it an invalid address.
    122132         */
    123         /** @todo (could use pipe+read to safely probe memory) */
     133        for (size_t off = sizeof(PyVarObject); off < sizeof(PyVarObject) + 64; off += sizeof(char *)) {
     134                const char * const pszProbe = *(const char **)((uintptr_t)(pTypeObj) + off);
     135                if (RT_VALID_PTR(pszProbe)) {
     136                        int fds[2] = { -1, -1 };
     137# ifdef PYXPCOM_HAVE_PIPE2
     138                        int rc = pipe2(fds, O_CLOEXEC);
     139# else
     140                        int rc = pipe(fds);
     141# endif
     142                        if (rc)
     143                                break;
     144
     145                        ssize_t cbWritten = write(fds[1], pszProbe, sizeof(g_szClassNm));
     146                        if (cbWritten == (ssize_t)sizeof(g_szClassNm)) {
     147                                char szReadBack[sizeof(g_szClassNm)];
     148                                ssize_t offRead = 0;
     149                                while (offRead < cbWritten) {
     150                                        ssize_t cbRead = read(fds[0], &szReadBack[offRead], cbWritten - offRead);
     151                                        if (cbRead >= 0) {
     152                                                offRead += cbRead;
     153                                        } else if (errno != EINTR)
     154                                                break;
     155                                }
     156                                if (   cbWritten == offRead
     157                                    && memcmp(szReadBack, g_szClassNm, sizeof(szReadBack)) == 0) {
     158                                        g_offObTypeNameMember = off;
     159                                        close(fds[0]);
     160                                        close(fds[1]);
     161                                        return pTypeObj;
     162                                }
     163                        }
     164                        close(fds[0]);
     165                        close(fds[1]);
     166                }
     167        }
     168        assert(0);
    124169
    125170        return pTypeObj;
     171}
     172
     173/**
     174 * Gets the base XPCOM interface type object, creating it if needed.
     175 */
     176static PyTypeObject *PyXPCOM_GetInterfaceType(void)
     177{
     178        PyTypeObject *pTypeObj = g_pPyInterfaceTypeObj;
     179        if (pTypeObj)
     180                return pTypeObj;
     181        return PyXPCOM_CreateInterfaceType();
    126182}
    127183
     
    129185 * Get the PyTypeObject::ob_name value.
    130186 *
    131  * @todo This is _horrible_, but there appears to be no simple tp_name getters
    132  *       till https://bugs.python.org/issue31497 (2017).
     187 * @todo This is _horrible_, but there appears to be no simple tp_name getter
     188 *       till https://bugs.python.org/issue31497 (2017 / 3.7.0).  But even then
     189 *       it is not part of the limited API.
    133190 */
    134191const char *PyXPCOMGetObTypeName(PyTypeObject *pTypeObj)
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette