diff options
Diffstat (limited to 'nix/libutil/spawn.cc')
| -rw-r--r-- | nix/libutil/spawn.cc | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/nix/libutil/spawn.cc b/nix/libutil/spawn.cc index 93bab9f59e4..414849b6f04 100644 --- a/nix/libutil/spawn.cc +++ b/nix/libutil/spawn.cc | |||
| @@ -51,6 +51,8 @@ | |||
| 51 | 51 | ||
| 52 | #ifdef __linux__ | 52 | #ifdef __linux__ |
| 53 | #include <sys/personality.h> | 53 | #include <sys/personality.h> |
| 54 | #include <linux/seccomp.h> | ||
| 55 | #include <linux/filter.h> | ||
| 54 | #endif | 56 | #endif |
| 55 | 57 | ||
| 56 | #if defined(SYS_pivot_root) | 58 | #if defined(SYS_pivot_root) |
| @@ -281,6 +283,36 @@ void setIDsAction(SpawnContext & ctx) | |||
| 281 | throw SysError("setuid failed"); | 283 | throw SysError("setuid failed"); |
| 282 | } | 284 | } |
| 283 | 285 | ||
| 286 | void setNoNewPrivsAction(SpawnContext & ctx) | ||
| 287 | { | ||
| 288 | if(ctx.setNoNewPrivs) | ||
| 289 | #if __linux__ && defined(PR_SET_NO_NEW_PRIVS) | ||
| 290 | if(prctl(PR_SET_NO_NEW_PRIVS, 0, 0, 0, 0) == -1) | ||
| 291 | throw SysError("setting PR_SET_NO_NEW_PRIVS"); | ||
| 292 | #else | ||
| 293 | throw Error("setting PR_SET_NO_NEW_PRIVS not supported on this system"); | ||
| 294 | #endif | ||
| 295 | } | ||
| 296 | |||
| 297 | void addSeccompFilterAction(SpawnContext & ctx) | ||
| 298 | { | ||
| 299 | if(ctx.addSeccompFilter) { | ||
| 300 | #if __linux__ && defined(PR_SET_SECCOMP) && defined(SECCOMP_MODE_FILTER) | ||
| 301 | /* We use no extra functionality from the seccomp system call, so | ||
| 302 | * just use prctl. */ | ||
| 303 | if(ctx.seccompFilter.size() > USHRT_MAX) | ||
| 304 | throw Error("seccomp filter too large"); | ||
| 305 | struct sock_fprog prog; | ||
| 306 | prog.len = (unsigned short) ctx.seccompFilter.size(); | ||
| 307 | prog.filter = ctx.seccompFilter.data(); | ||
| 308 | if(prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) == -1) | ||
| 309 | throw SysError("installing seccomp filter"); | ||
| 310 | #else | ||
| 311 | throw Error("setting seccomp filter not supported on this system"); | ||
| 312 | #endif | ||
| 313 | } | ||
| 314 | } | ||
| 315 | |||
| 284 | 316 | ||
| 285 | void restoreSIGPIPEAction(SpawnContext & ctx) | 317 | void restoreSIGPIPEAction(SpawnContext & ctx) |
| 286 | { | 318 | { |
| @@ -336,6 +368,8 @@ Phases getBasicSpawnPhases() | |||
| 336 | { "setPersonality", setPersonalityAction }, | 368 | { "setPersonality", setPersonalityAction }, |
| 337 | { "oomSacrifice", oomSacrificeAction }, | 369 | { "oomSacrifice", oomSacrificeAction }, |
| 338 | { "setIDs", setIDsAction }, | 370 | { "setIDs", setIDsAction }, |
| 371 | { "setNoNewPrivs", setNoNewPrivsAction }, | ||
| 372 | { "addSeccompFilter", addSeccompFilterAction }, | ||
| 339 | { "restoreSIGPIPE", restoreSIGPIPEAction }, | 373 | { "restoreSIGPIPE", restoreSIGPIPEAction }, |
| 340 | { "setupSuccess", setupSuccessAction }, | 374 | { "setupSuccess", setupSuccessAction }, |
| 341 | { "exec", execAction } }; | 375 | { "exec", execAction } }; |
| @@ -773,6 +807,8 @@ Phases getCloneSpawnPhases() | |||
| 773 | CloneSpawnContext.lockMountsMapAll = true. */ | 807 | CloneSpawnContext.lockMountsMapAll = true. */ |
| 774 | { "lockMounts", lockMountsAction }, | 808 | { "lockMounts", lockMountsAction }, |
| 775 | { "setIDs", setIDsAction }, | 809 | { "setIDs", setIDsAction }, |
| 810 | { "setNoNewPrivs", setNoNewPrivsAction }, | ||
| 811 | { "addSeccompFilter", addSeccompFilterAction }, | ||
| 776 | { "restoreSIGPIPE", restoreSIGPIPEAction }, | 812 | { "restoreSIGPIPE", restoreSIGPIPEAction }, |
| 777 | { "setupSuccess", setupSuccessAction }, | 813 | { "setupSuccess", setupSuccessAction }, |
| 778 | { "exec", execAction }}; | 814 | { "exec", execAction }}; |
