1

We have an existing project using Eventlet module.

There is a server handling client request using green threads. All the requests are handled by a single user 'User A'

I now need to change this to do a setfsuid/setfsgid on the threads so that the underlying files are all created with the ownership of the requesting user only.

I understand that I need setid Linux capability to make the setfsid calls.

But will setfsid calls work with green threads like they do with the native threads ?

By reading through various texts over the net regarding 'green threads', I couldn't gather much :(

mittal
  • 915
  • 10
  • 29

2 Answers2

0

All green threads are executed from one OS thread. To kernel it looks like your whole Python program only has one thread.

If you need separate filesystem ids for each request, start a separate OS thread, call setfsuid() in it and execute required filesystem calls in it.

threading = eventlet.patcher.original('threading')
temoto
  • 5,394
  • 3
  • 34
  • 50
  • 1
    Which also would mean only one user can be served at any given time. – BlackJack Jan 19 '16 at 15:32
  • @BlackJack I changed answer to allow separate filesystem ids for each request. – temoto Jan 20 '16 at 05:05
  • @temoto Thanks for looking into this and replying But I didn't understand what would this patching achieve. The current project starts a main process and couple of worker processes which use the green threads to handle upto 1K requests each. When you said 'start a separate OS thread', where should that change be made ? – mittal Jan 20 '16 at 14:12
  • @BlackJack I couldn't understand why you mentioned only one user can be served at – mittal Jan 20 '16 at 14:14
  • 1
    @mittal because you have only one OS thread but with several users at a time there are several green threads using the same UID set for that single OS thread. – BlackJack Jan 20 '16 at 14:21
  • @BlackJack That also means that existing 'green threads' way of handling in the project would be a hindrance in achieving the purpose ? – mittal Jan 20 '16 at 14:23
  • 1
    @mittal If you end up starting an OS thread for each green thread then green threads don't work for your purpose. – BlackJack Jan 20 '16 at 14:26
  • @BlackJack I am bit confused. I meant that is there a way to achieve what I want with green threads, or I need to completely revamp it, ditch green threads and instead move to native threads ? – mittal Jan 20 '16 at 14:29
  • 1
    @mittal the `patcher.original()` is used to reliably get original threading module even if you used eventlet monkey patching to replace standard library modules with greened versions. You can still handle network in green threads, but access filesystem from OS threads. Indeed this means that green threads don't work for your purpose. – temoto Jan 20 '16 at 14:58
  • @temoto You mean using a mix of green threads and native threads ? How to do that, any links/pointers which I can read through ? By patcher.original(), I would be able to make use of native threads from within green threads ? Sorry, if I am not making much sense. I am unfamiliar with green threads, how they work etc. I read lot of stuff, but still couldn't gather much. – mittal Jan 21 '16 at 16:11
  • Yes, I mean mix and you don't do anything special to mix them. Just read Eventlet docs about using green threads. Just read standard Python docs about OS threads. – temoto Jan 21 '16 at 18:12
  • I meant, more from a design point of view. Say a green thread is handling client connection, if it needs to carry out a filesystem operation, can a green thread invoke an OS thread which will do setfsid() ? – mittal Jan 25 '16 at 05:57
  • 2
    It's possible, but then you have OS threads as bottleneck, so the only reason to have green threads in first place is if you have other requests that don't require `setfsuid`. If all requests require `setfsuid`, then having green threads and OS threads only adds cognitive load at no profit. – temoto Jan 25 '16 at 12:37
  • >> the only reason to have green threads in first place is if you have other requests that don't require `setfsuid`. Yes, that was the original project design where everything was to be done using a `single user` :'( – mittal Jan 28 '16 at 06:24
  • @temoto I was wondering if I could do the other way, would it help. I mean, for each incoming request spawn a new native thread, with setfsuid, and that thread can invoke green threads to carry out the tasks specific to that thread ? – mittal Feb 08 '16 at 05:59
  • I recommend against that. 1) Eventlet doesn't have a stable API for pinpointing green threads to specific OS thread. 2) It's complicated. I recommend either completely switch to native threads only, or continue with green threads and use `eventlet.tpool` to spawn native threads, but be aware that `tpool` reuses old threads (hence pool in name), so you have to ensure proper `setfsuid` in the beginning of each call through tpool. – temoto Feb 08 '16 at 07:55
  • @temoto Thanks for that suggestion. Can you point to me some links where I can find examples of using tpool ? – mittal Mar 08 '16 at 16:48
0

The kernel is ignorant to green threads. If a process has a uid and gid, it is used by all green threads running as part of this process.

At a first glance, what you are seeking to do is equivalent to having a privileged process do a setuid prior to opening/creating a file, than doing a second setuid to open/create a second file etc. all to ensure that each file has the right ownership. I never tried such a scheme, but it sounds very very wrong. It is also extremely bad security wise. You are running at high privileges and may find yourself processing user X's data while having user Y's uid.

At a second glance, green threads are cooperative, meaning that under the hoods, some of the operations you do will yield. Following such yield, you may change to a different green thread that will change the uid again...

Bottom line, forget about changing the uid and gid of the green thread - there is no such thing. Create the file with whatever ID you have and chown to the right id after. Find a way to do that without running as root for security reasons.

davidhadas
  • 2,333
  • 21
  • 17