{"record":{"id":"cfb95c8640f13780","repo":"elastic/elasticsearch","slug":"prctl-pr-set-no-new-privs","errorCode":null,"errorMessage":"prctl(PR_SET_NO_NEW_PRIVS): {}","messagePattern":"prctl\\(PR_SET_NO_NEW_PRIVS\\): (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"warning","filePath":"libs/native/src/main/java/org/elasticsearch/nativeaccess/LinuxNativeAccess.java","lineNumber":281,"sourceCode":"        // check for SECCOMP_MODE_FILTER\n        if (linuxLibc.prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, 0, 0, 0) != 0) {\n            int errno = libc.errno();\n            switch (errno) {\n                case EFAULT:\n                    break; // available\n                case EINVAL:\n                    throw new UnsupportedOperationException(\n                        \"seccomp unavailable: CONFIG_SECCOMP_FILTER not\"\n                            + \" compiled into kernel, CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER are needed\"\n                    );\n                default:\n                    throw new UnsupportedOperationException(\"prctl(PR_SET_SECCOMP): \" + libc.strerror(errno));\n            }\n        }\n\n        // ok, now set PR_SET_NO_NEW_PRIVS, needed to be able to set a seccomp filter as ordinary user\n        if (linuxLibc.prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != 0) {\n            throw new UnsupportedOperationException(\"prctl(PR_SET_NO_NEW_PRIVS): \" + libc.strerror(libc.errno()));\n        }\n\n        // check it worked\n        if (linuxLibc.prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0) != 1) {\n            throw new UnsupportedOperationException(\n                \"seccomp filter did not really succeed: prctl(PR_GET_NO_NEW_PRIVS): \" + libc.strerror(libc.errno())\n            );\n        }\n\n        // BPF installed to check arch, limit, then syscall.\n        // See https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt for details.\n        SockFilter insns[] = {\n            /* 1  */ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, SECCOMP_DATA_ARCH_OFFSET),             //\n            /* 2  */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arch.audit, 0, 7),                 // if (arch != audit) goto fail;\n            /* 3  */ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, SECCOMP_DATA_NR_OFFSET),               //\n            /* 4  */ BPF_JUMP(BPF_JMP + BPF_JGT + BPF_K, arch.limit, 5, 0),                 // if (syscall > LIMIT) goto fail;\n            /* 5  */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arch.fork, 4, 0),                 // if (syscall == FORK) goto fail;\n            /* 6  */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arch.vfork, 3, 0),                 // if (syscall == VFORK) goto fail;","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/native/src/main/java/org/elasticsearch/nativeaccess/LinuxNativeAccess.java#L263-L299","documentation":"Thrown during Linux seccomp sandbox setup in tryInstallExecSandbox(). After all probes pass, the code performs the real operation: prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) to set the NO_NEW_PRIVS flag, which is a prerequisite for installing a seccomp BPF filter as a non-root user. If the set returns non-zero, this error fires with strerror. Unlike the earlier probes (which test capability), this is the actual state-changing call.","triggerScenarios":"Calling tryInstallExecSandbox() where prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) returns non-zero. The probes at lines 229-244 confirmed the kernel supports the primitive, but actually setting it fails.","commonSituations":"Container runtimes (especially Docker with custom --security-opt profiles) that block setting NO_NEW_PRIVS; SELinux/AppArmor policies denying the transition; processes that have already dropped capabilities needed for the prctl; some systemd unit configurations with NoNewPrivileges=false conflicting with the call.","solutions":["Read the strerror to identify the errno (commonly EPERM or EACCES).","If running under systemd, check NoNewPrivileges in the unit file — if already set, the prctl should be a no-op; if conflicting, reconcile the setting.","If in a container, verify the seccomp/AppArmor profile allows PR_SET_NO_NEW_PRIVS or run with --security-opt no-new-privileges:false if appropriate.","Ensure the process has not already dropped CAP_SYS_ADMIN or equivalent capabilities needed for the call.","If the sandbox is not required, accept the failure — ES continues without exec filtering."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    nativeAccess.tryInstallExecSandbox();\n} catch (UnsupportedOperationException e) {\n    // The actual PR_SET_NO_NEW_PRIVS operation was blocked.\n    logger.warn(\"could not set NO_NEW_PRIVS, exec sandbox unavailable: {}\", e.getMessage());\n}","preventionTips":["If running under systemd, set NoNewPrivileges=true in the unit file so the prctl is a no-op rather than a conflict.","For Docker containers, check --security-opt no-new-privileges and the seccomp profile.","Ensure the ES process has not dropped capabilities (CAP_SYS_ADMIN) before bootstrap.","Read the strerror in the exception to distinguish EPERM (policy block) from other errors."],"tags":["linux","seccomp","security","native","kernel","bootstrap","prctl"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}