Created attachment 1108977 [details] reproducer.c Description of problem: seccomp seems to be returning 12bit errno max instead of expected 16bit if SECCOMP_RET_ERRNO used. This minimal reproducer is enough to reprodude the issue. I am attaching it also ---- reproducer start ---- #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <seccomp.h> #include <unistd.h> #define TESTING_SCERRNO 0x1234 /* 4660 */ int main(int argc, char **argv) { scmp_filter_ctx ctx = NULL; int ret; ctx = seccomp_init(SCMP_ACT_ALLOW); if (ctx == NULL) exit(1); if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(TESTING_SCERRNO), SCMP_SYS(dup2), 1, SCMP_CMP(0, SCMP_CMP_EQ, 0)) < 0) exit(1); if (seccomp_load(ctx) < 0) exit(1); seccomp_release(ctx); ret = dup2(0, 42); printf("%d %d %hd\n", ret, errno, TESTING_SCERRNO); return 0; } ---- reproducer start ---- To compile and run use: # gcc -lseccomp -o reproducer reproducer.c # ./reproducer According to docs: SECCOMP_RET_ERRNO: Results in the lower 16-bits of the return value being passed to userland as the errno without executing the system call. It should return according to the documentation [1]: -1 4660 4660 Instead on Fedora returns (it seems to return only 12bit integer max): -1 4095 4660 Version-Release number of selected component (if applicable): kernel-4.2.8-300.fc23.x86_64 kernel-4.4.0-0.rc6.git0.1.fc24.x86_64 How reproducible: 100% Steps to Reproduce: 1. Compile attached reproducer as written in description Actual results: -1 4095 4660 Expected results: -1 4660 4660 [1] https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
For reference, the kernel sets the maximum errno value (MAX_ERRNO) to 4095, see include/linux/err.h. Up until Linux 4.0 there was a bug where seccomp would allow setting a errno value beyond MAX_ERRNO. It was fixed with the following patch: commit 580c57f1076872ebc2427f898b927944ce170f2d Author: Kees Cook <keescook> Date: Tue Feb 17 13:48:00 2015 -0800 seccomp: cap SECCOMP_RET_ERRNO data to MAX_ERRNO The value resulting from the SECCOMP_RET_DATA mask could exceed MAX_ERRNO when setting errno during a SECCOMP_RET_ERRNO filter action. This makes sure we have a reliable value being set, so that an invalid errno will not be ignored by userspace. Signed-off-by: Kees Cook <keescook> Reported-by: Dmitry V. Levin <ldv> Cc: Andy Lutomirski <luto> Cc: Will Drewry <wad> Signed-off-by: Andrew Morton <akpm> Signed-off-by: Linus Torvalds <torvalds> The kernel patch does not appear to be in RHEL7 as I am writing this comment. The libseccomp library has also added an errno check with the following patch: commit 0d287caf43792239b107ee3215b32b8bc901f9c3 Author: Paul Moore <pmoore> Date: Sat Aug 29 20:05:19 2015 -0400 api: limit errno values to MAX_ERRNO It turns out that userspace behaves oddly when given an errno value greater than MAX_ERRNO, so much so that the kernel seccomp mechanism has started blocking filters with bad errno values. Let's try to catch the problem at rule addition time to make things easier to spot and fix. Signed-off-by: Paul Moore <pmoore> The libseccomp patch is not present in any released versions of the library but will be included in the next release.
As this seems like a end-user issue and was fixed in our test suite (using errno of <12bits), is there anything to be done on the kernel or libseccomp side? Or can we close this as NOTABUG?
I do not think so .. thanks .. CLOSING AS NOTABUG (In reply to Jiri Jaburek from comment #5) > As this seems like a end-user issue and was fixed in our test suite (using > errno of <12bits), is there anything to be done on the kernel or libseccomp > side? Or can we close this as NOTABUG?