-
Notifications
You must be signed in to change notification settings - Fork 127
Integrate Capabilities in Open-Lambda #301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@@ -388,6 +454,8 @@ static PyMethodDef OlMethods[] = { | |||
{"unshare", (PyCFunction)ol_unshare, METH_NOARGS, "unshare"}, | |||
{"fork", (PyCFunction)ol_fork, METH_NOARGS, "fork"}, | |||
{"enable_seccomp", (PyCFunction)ol_enable_seccomp, METH_NOARGS, "enable_seccomp"}, | |||
{"modify_cap", (PyCFunction)ol_modify_cap, METH_VARARGS, "modify_cap"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tylerharter This is still a work in progress. But the basic idea was that maybe we can expose a function here to modify/ drop capabilities.
Great progress! Let's do one case at a time, each in different PRs: How about this first? "right before forking a Leaf to run the user code". But is it before, or after forking? For you four questions:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great start!
|
||
capList[0] = cap; | ||
if (cap_set_flag(caps, CAP_EFFECTIVE, 1, capList, setting) == -1) { | ||
cap_free(caps); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the nice things about a goto is it gives you a single place to clean things up, like this:
if (caps != NULL)
cap_free(caps);
@@ -8,6 +9,71 @@ | |||
#include <sys/types.h> | |||
#include <sys/wait.h> | |||
#include <seccomp.h> | |||
#include <sys/capability.h> | |||
|
|||
static int modify_cap_impl(int cap, int setting) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To what extent can we just create Python wrappers around the cap API (can_get_proc, cap_set_flag, etc), and then have the logic using it in Python code only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tylerharter I couldn't actually find a native way to do this in Python (atleast at a granular level) and then came across the seccomp code in this file. It feels like we should be able to do a lot with the wrappers - like we have good amount of control over how we want to expose these functions to Python. Is there a concern around doing it in this way?
We may have to do it in a different way (or use an external module?) for dropping privileges in sock.go since these would only work in Python.
@@ -208,6 +208,7 @@ def main(): | |||
file.write(pid) | |||
print(f'server.py: joined cgroup, close FD {fd_id}') | |||
|
|||
# drop privileges here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make capability dropping optional, via config, like it is for seccomp? https://github.com/open-lambda/open-lambda/blob/main/min-image/runtimes/python/server.py#L189
@tylerharter My bad, I meant to say Okay sure, that makes sense. I'll start with |
Upon looking at the code (and the workshop slides), I found 3 possible places where we might drop privileges:
freshProc()
[src/worker/sandbox/sock.go
] right before exec-ing theserver.py
.fork_server()
[min-image/runtimes/server.py
] right before the while loop that forks a new Zygotestart_container()
[min-image/runtimes/server.py
] right before forking a Leaf to run the user code.Some general questions I have:
web_server.py
orfork_server.py
invoked? (EDIT: I meantweb_server()
andfork_server()
functions inserver.py
my bad)su
before I can navigate to the directory and create a lambda function with my code. Is it possible that none of this is run as root right from the beginning itself so this issue doesn't occur either? Or maybe the base directory can be initialized with more relaxed permissions?strace
the system calls (or if we know ones that are needed already) to see which capabilities they need and then iteratively add and test them to see if all things work as expected. Which also brings me to another question