CPython: Patching system calls during porting

Hello all.

I’m working on a port of CPython 3.11 onto an ARM device running a custom Linux distro with a somewhat restricted userspace. One of the limitations I’ve been struggling with is a ban on chmod system call - regardless of what it’s used for, the call will always produce an error. This shouldn’t really be a problem since the only writable partition on the device is formatted in FAT32 and doesn’t support permissions anyway, but in practice, any calls to chmod from anywhere in python will crash a program. Commenting out os.chmod calls in libraries works, but it’s not a real solution.

My goal is to edit chmod implementation to simply do nothing (from my understanding, that’s already its behavior on windows platform). I tried a few naive approaches, like removing chmod from the library functions in configure.ac (which only resulted in a different error since the function is now not implemented at all) and deleting *chmod calls from posixmodule.c (I guess unsuccessfully, since things still crashed on forbidden chmod calls).

What would be the best approach to patch the chmod implementation to do nothing?

Try compiling python with -Dchmod=noop_chmod and privide an implementation of noop_chmod that does nothing and succeeds.

Thanks for the suggestion, I gave it a try (finally) but ran into some issues.

To confirm if I understood what it’s supposed to do correctly: we’re passing a definition to the C preprocessor, same as if we defined it via #define. We’re making a macro called chmod, which will essentially replace all chmod calls with whatever implementation we give it. We then pass it to the configure script via CPPFLAGS.

It seems that I can successfully define macros, but as soon as I try to “redefine” chmod in this way (say via CPPFLAGS="-Dchmod\(x,y\)=0") make will start dropping warnings as follows:

./Include/internal/pycore_fileutils.h:82:27: warning: 'struct stat' declared inside parameter list will not be visible outside of this definition or declaration
 #  define _Py_stat_struct stat
                           ^
./Include/internal/pycore_fileutils.h:87:12: note: in expansion of macro '_Py_stat_struct'
     struct _Py_stat_struct *status);
            ^~~~~~~~~~~~~~~

…then eventually fail on:

Python/marshal.c: In function 'getfilesize':
Python/marshal.c:1560:28: error: storage size of 'st' isn't known
     struct _Py_stat_struct st;
                            ^~

This seems unrelated, but it consistently happens whenever chmod is redefined. My guess is that it messes with configuration in some way, perhaps declaring MS_WINDOWS someplace since _Py_stat_struct seems to be defined for that platform. Thoughts?

This may be a bit on the hacky side, but what about just straight up deleting the os_chmod_impl implementation?

static PyObject *
os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
              int follow_symlinks)
/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
{
    Py_RETURN_NONE;
}

It seems to work without issues on my desktop (linux x86_64) environment (although test_embed fails and I’m not sure if that’s something to worry about).

1 Like

Works indeed, no side effects thus far and I need to apply a few patches already anyway. I believe this will do, thanks for the suggestion!