-
Notifications
You must be signed in to change notification settings - Fork 30k
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
Initial set of patches for supporting CloudABI #16612
Conversation
CloudABI is a compact POSIX-like runtime that makes use of capability-based security. More details: https://github.com/NuxiNL/cloudlibc
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.
LGTM if CI is happy: https://ci.nodejs.org/job/node-test-pull-request/11092/
Hello @EdSchouten and welcome! Thank you for the contribution. Change LTGM on the face of it, but after reading a little bit about CloudABI, it seems that implementing support raises some interesting questions:
/cc @nodejs/build |
Hi @refack. Thanks for taking a look at these changes! Let me answer your questions, also providing some background/motivation:
CloudABI is an offshoot of a sandboxing framework provided by FreeBSD, called Capsicum. The main difference between the two is that Capsicum goes into the direction of keeping system calls around and letting them return a special errno Though CloudABI's approach causes lots of existing builds to break (including Node.js's), it has a big advantage over Capsicum: the compiler errors give you a guided approach to making an application work well with sandboxing. You immediately get a sense of which parts work and which ones don't. The number of compiler errors acts as a rough estimate for tracking progress. In the process, CloudABI's approach has (unfortunately) allowed us to find many pieces of code that do things like this:
Which is of course quite dangerous, regardless of which sandboxing/security/container/... framework is being used. You try to make your software more secure by using sandboxing, but in the end you've ended up introducing bugs. This is why I've become a huge advocate of removing incompatible features entirely. A very brief answer to your question would be "A lot on ifdefs", but that's absolutely not what I'm aiming for in the long run. Right now I'm disabling features in Node.js to at least get it to work, but my hope is that designs of future APIs also take 'sandboxability' into account and thus don't need to be disabled. A good example of work in this area is Python 3.4's pathlib. Initially intended to make pathname handling less cumbersome, its object oriented API also improves testability/reusability, and in CloudABI's case sandboxability. An improvement, even for people who don't care about CloudABI.
The idea behind CloudABI is that programs have all of their dependencies on external resources (paths disk, bound sockets, connections to backend services, etc.) injected in the form of file descriptors. Instead of using
The argument to this function is a user-provided JSON/YAML-like object that, in addition to strings, integers, etc. can hold file descriptors. One thing I still need to implement is that this tree is exposed within v8. So if you normally spawn a simple web server like this:
You'd have to adjust it like this to work on CloudABI:
Building Node.js for CloudABI should be relatively easy and can be done on most (UNIX-like?) operating systems out there. Even if your OS/distro doesn't have a package for a CloudABI cross compiler yet, just install a vanilla copy of LLVM >= 4 and add symlinks ( Copies of cross compiled libraries that you'll need (CloudABI's C library, but also all of Node.js's dependencies) are automatically built through CloudABI Ports and can be installed through a variety of package managers ( If you don't feel like building Node.js yourself, I've also packaged Node.js through CloudABI Ports. Right now it still has a lot of local patches, of course. My goal is to use that as a patch queue for things that should still be cleaned up, sent out as a pull request, etc. With regards to testing: so far I haven't really taken a stab at getting Node.js's tests to work. This is, of course, something that's important to pursue in the future. |
@@ -111,7 +111,7 @@ typedef int mode_t; | |||
#include <unistd.h> // setuid, getuid | |||
#endif | |||
|
|||
#if defined(__POSIX__) && !defined(__ANDROID__) | |||
#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__) |
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.
IMHO since this is used in three places, it should be aliased to something like UNSANDBOXED_POSIX
or defined(__POSIX__) && !SANDBOXED_POSIX
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.
I've just added a definition, HAVE_POSIX_CREDENTIALS
, that is declared when building for systems that support <pwd.h>
, <grp.h>
, set*uid()
, etc. Does that look all right?
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.
I yield to @cjihrig.
Maybe revisit in the future if there are more usages.
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.
All right. I've just rolled back the HAVE_POSIX_CREDENTIALS
changes.
@EdSchouten thank you for the informative response. If you haven't already PTAL at the platform support strategy (https://github.com/nodejs/node/blob/master/BUILDING.md#strategy). My long term concern is that without CI these changes will rot. So IMHO we next step is to design a CI job that will run some basic tests on this (see nodejs/build#419). |
Having a CI job to do automated builds for CloudABI does indeed make sense. I suspect that's only useful to have after I've managed to upstream all build fixes, right? In the meantime I'm also sending patches over to the V8 developers. Let's see how well that goes... |
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.
I won't block it, but I'm withdrawing my LGTM. I'm not a big fan of going the HAVE_POSIX_CREDENTIALS
route.
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.
LGTM, I'm fine with both HAVE_POSIX_CREDENTIALS
or just spelling it out.
As CloudABI is intended to run applications in cluster contexts (e.g., on Kubernetes), they are oblivious of UNIX credentials. Extend the existing preprocessor checks to disable any use of these interfaces, just like on Windows, Android, etc.
cares_wrap.cc calls into functions like getnameinfo() and getaddrinfo(). These functions tend to be available implicitly through <uv.h>, but we'd better still include this header explicitly. On CloudABI, we make use of a custom implementation of libuv that does not implicitly include header files like <netdb.h>.
Re-LGTM |
CloudABI is a compact POSIX-like runtime that makes use of capability-based security. More details: https://github.com/NuxiNL/cloudlibc * src: Disable use of pwd.h, grp.h and get*uid() on CloudABI. As CloudABI is intended to run applications in cluster contexts (e.g., on Kubernetes), they are oblivious of UNIX credentials. Extend the existing preprocessor checks to disable any use of these interfaces, just like on Windows, Android, etc. * src: Explicitly include <netdb.h>. cares_wrap.cc calls into functions like getnameinfo() and getaddrinfo(). These functions tend to be available implicitly through <uv.h>, but we'd better still include this header explicitly. On CloudABI, we make use of a custom implementation of libuv that does not implicitly include header files like <netdb.h>. PR-URL: nodejs#16612 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Refael Ackermann <refack@gmail.com>
Landed in 78dbcbe |
@EdSchouten thank you, and best of luck with the project. |
Heh, awesome. Thanks! \o/ |
CloudABI is a compact POSIX-like runtime that makes use of capability-based security. More details: https://github.com/NuxiNL/cloudlibc * src: Disable use of pwd.h, grp.h and get*uid() on CloudABI. As CloudABI is intended to run applications in cluster contexts (e.g., on Kubernetes), they are oblivious of UNIX credentials. Extend the existing preprocessor checks to disable any use of these interfaces, just like on Windows, Android, etc. * src: Explicitly include <netdb.h>. cares_wrap.cc calls into functions like getnameinfo() and getaddrinfo(). These functions tend to be available implicitly through <uv.h>, but we'd better still include this header explicitly. On CloudABI, we make use of a custom implementation of libuv that does not implicitly include header files like <netdb.h>. PR-URL: nodejs/node#16612 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Refael Ackermann <refack@gmail.com>
CloudABI is a compact POSIX-like runtime that makes use of capability-based security. More details: https://github.com/NuxiNL/cloudlibc * src: Disable use of pwd.h, grp.h and get*uid() on CloudABI. As CloudABI is intended to run applications in cluster contexts (e.g., on Kubernetes), they are oblivious of UNIX credentials. Extend the existing preprocessor checks to disable any use of these interfaces, just like on Windows, Android, etc. * src: Explicitly include <netdb.h>. cares_wrap.cc calls into functions like getnameinfo() and getaddrinfo(). These functions tend to be available implicitly through <uv.h>, but we'd better still include this header explicitly. On CloudABI, we make use of a custom implementation of libuv that does not implicitly include header files like <netdb.h>. PR-URL: nodejs#16612 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Refael Ackermann <refack@gmail.com>
Does this make sense to backport to v6.x and v8.x now or should we wait for more CloudABI support to be done first? |
Hi Myles, I'd say, don't bother for now. Considering that I also need to send a fair number of patches integrated into V8 as well, let's just focus on supporting future versions of Node. |
CloudABI is a compact POSIX-like runtime that makes use of capability-based security. More details: https://github.com/NuxiNL/cloudlibc * src: Disable use of pwd.h, grp.h and get*uid() on CloudABI. As CloudABI is intended to run applications in cluster contexts (e.g., on Kubernetes), they are oblivious of UNIX credentials. Extend the existing preprocessor checks to disable any use of these interfaces, just like on Windows, Android, etc. * src: Explicitly include <netdb.h>. cares_wrap.cc calls into functions like getnameinfo() and getaddrinfo(). These functions tend to be available implicitly through <uv.h>, but we'd better still include this header explicitly. On CloudABI, we make use of a custom implementation of libuv that does not implicitly include header files like <netdb.h>. PR-URL: nodejs/node#16612 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Refael Ackermann <refack@gmail.com>
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesSome of the tests fail on my FreeBSD system (IPv4 address mismatches), but these errors are unrelated to the change at hand.
Affected core subsystem(s)
build, src