Re: Trying to support Python 3 but fails on libsemanage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, May 16, 2012 at 11:17:36AM +0200, Sven Vermeulen wrote:
> I'm trying to get Python 3 support up and going with the SELinux userspace
> utilities. I'm hitting a compatibility issue that I'm not able to work out
> further.
> 
> This is the following "test case":
> 	semanage fcontext -a -t swapfile_t /swapfile
> 	semanage fcontext -d -t swapfile_t /swapfile
> 
> With Python 2.7, this works as it should be. With Python 3.2 however, I get
> the following error while trying to delete the entry:
> 
> /usr/sbin/semanage: File context for /swapfile is not defined

I've not been able to debug this much further, but this is as far as I got
today...

(1.) semanage (the python script) calls the python seobject class, more
     specifically the seobject.fcontextRecords class
(2.) in seobject.fcontextRecords, deleting a file context goes to the
     __delete function
(3.) in __delete, semanage_fcontext_key_create(self.sh, target,
     file_type[fstype]) is called, which returns rc (return code) and k (the
     key used to interact with libsemanage)

     self.sh is a handle used to keep track of the "transaction", target is
     the string of the file context to delete (like "/swapfile"),
     file_type[fstype] here is for specific types of contexts

(4.) semanage_fcontext_key_create() goes to the _semanage.so shared library
     (through semanage.py which imports _semanage), which is created from the
     libsemanage code through swig

(5.) The semanage_fcontext_key_create() function is defined in
     src/fcontext_record.c. It allocates memory, puts in the information
     (like expression = "/swapfile") and returns the address of this memory
     location as key

So far I can follow how things go. Since the Python script uses the
_semanage.so as library, it can (or should) use the memory address without
problems (no forks or so involved, so the memory address should remain
correct, right?)

However, what happens next is a bit too unclear to me. 

(6.) In seobject.py, the function "semanage_fcontext_exists_local" is
     called. The name obviously tells me we're going to see if the file
     definition is mentioned in the file_contexts.local so that it can be
     removed. It uses the key as a reference to seek this information.
(7.) semanage_fcontext_exists_local is defined in src/fcontexts_local.c, but
     this contains the following:

        dbase_config_t *dconfig = semanage_fcontext_dbase_local(handle);
        return dbase_exists(handle, dconfig, key, response);

     What is semanage_fcontext_dbase_local(handle)'s job? Is this to define
     the target database to work with (in our case, for file contexts)?
(8.) dbase_exists() is defined in src/databqse.c. It calls the following:

        dconfig->dtable->exists(handle, dconfig->dbase, key, response)

     I assume the function "exists" depends on the dtable, which comes from
     dconfig, and which - in our case - will refer to
     semanage_fcontext_compare (in src/fcontext_record.c)

Now here's where the fun part comes in.

In both semanage_fcontext_key_create() and semanage_fcontext_compare() I
have added some debugging statements, namely:

fprintf(stderr, "DEBUG - create: key is %u, expr is \"%s\"\n", key, key->expr);
and
fprintf(stderr, "DEBUG - compare: key is %u, expr is \"%s\"\n", key, key->expr);


When I run the mentioned use case with Python 2.7, I get the following
(expected) output:

DEBUG - create: key is 3216874400, expr is "/swapfile"
DEBUG - compare: key is 3216874400, expr is "/swapfile"
DEBUG - compare: key is 3216874400, expr is "/swapfile"

after which it gets deleted (the two compare-debug lines are because the
file_contexts.local has two entries, and the second one matches).

With Python 3.2, it becomes the following:

DEBUG - create: key is 973543696, expr is "/swapfile"
DEBUG - compare: key is 973543696, expr is ""�0^\"
DEBUG - compare: key is 973543696, expr is ""�0^\"
...


Somewhere between creating the key and checking its content, the content of
the memory is changed (or the target of the pointer pointing to the
expression). Since the key itself (address) is unchanged, this is done
somewhere in the libsemanage code, right?

But if it is, and the code doesn't seem to have any #if PY_MAJOR_VERSION ...  #endif
constructs in it, what can then cause Python 2.7 to behave differently here?
Is it the swig'ed result that differs from Python 2.7 and Python 3.2? If so,
is there any way this can be debugged easily?

Wkr,
	Sven Vermeulen

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.


[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux