[PATCH] arch: ensure we don't "munge" pseudo syscall numbers
authorPaul Moore <paul@paul-moore.com>
Sun, 16 Aug 2020 13:56:36 +0000 (09:56 -0400)
committerFelix Geyer <fgeyer@debian.org>
Sun, 8 Nov 2020 18:59:21 +0000 (18:59 +0000)
A number of arches/ABIs have either syscall offsets (the MIPS
family) or specific bits (x32) which are applied to their normal
syscall numbers.  We generally handle that via "munging" in
libseccomp, and it works reasonably well.  Unfortunately we were
applying this munging process to the negative pseudo syscall
numbers as well and this was causing problems.

This patch fixes the various offset/bit arches/ABIs by not applying
the munging to the negative pseudo syscall numbers.

This resolves GH issue #284:
* https://github.com/seccomp/libseccomp/issues/284

Reported-by: Harald van Dijk <harald@gigawatt.nl>
Acked-by: Tom Hromatka <tom.hromatka@oracle.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
(imported from commit 34cde704979defcbddb8eea64295acf0e477c250)

Gbp-Pq: Name arch_ensure_we_dont_munge_pseudo_syscall_numbers.patch

src/arch-arm.c
src/arch-mips.c
src/arch-mips64.c
src/arch-mips64n32.c
src/arch-x32.c

index 4dd4b6317bdd6789a6a79a4c565eae193fac1df6..9c9153ae69b0e9a895c736daf0aea2605f166c9a 100644 (file)
@@ -50,8 +50,9 @@ int arm_syscall_resolve_name_munge(const char *name)
 {
        int sys;
 
+       /* NOTE: we don't want to modify the pseudo-syscall numbers */
        sys = arm_syscall_resolve_name(name);
-       if (sys == __NR_SCMP_ERROR)
+       if (sys == __NR_SCMP_ERROR || sys < 0)
                return sys;
 
        return (sys | __SCMP_NR_BASE);
@@ -68,7 +69,10 @@ int arm_syscall_resolve_name_munge(const char *name)
  */
 const char *arm_syscall_resolve_num_munge(int num)
 {
-       return arm_syscall_resolve_num(num & (~__SCMP_NR_BASE));
+       /* NOTE: we don't want to modify the pseudo-syscall numbers */
+       if (num >= 0)
+               num &= ~__SCMP_NR_BASE;
+       return arm_syscall_resolve_num(num);
 }
 
 const struct arch_def arch_def_arm = {
index f0e6a143da6c4895b94475c858e62674a455368a..06741c7ff33ec1a7a1daaf0d90e7675408418132 100644 (file)
@@ -43,8 +43,9 @@ int mips_syscall_resolve_name_munge(const char *name)
 {
        int sys;
 
+       /* NOTE: we don't want to modify the pseudo-syscall numbers */
        sys = mips_syscall_resolve_name(name);
-       if (sys == __NR_SCMP_ERROR)
+       if (sys == __NR_SCMP_ERROR || sys < 0)
                return sys;
 
        return sys + __SCMP_NR_BASE;
@@ -61,7 +62,10 @@ int mips_syscall_resolve_name_munge(const char *name)
  */
 const char *mips_syscall_resolve_num_munge(int num)
 {
-       return mips_syscall_resolve_num(num - __SCMP_NR_BASE);
+       /* NOTE: we don't want to modify the pseudo-syscall numbers */
+       if (num >= __SCMP_NR_BASE)
+               num -= __SCMP_NR_BASE;
+       return mips_syscall_resolve_num(num);
 }
 
 const struct arch_def arch_def_mips = {
index 9707d1c5633b00ae60bb3503f0ffda95cec63f38..342d0d88ef85c896a01b6275bcc9fb2ddf296f1d 100644 (file)
@@ -41,8 +41,9 @@ int mips64_syscall_resolve_name_munge(const char *name)
 {
        int sys;
 
+       /* NOTE: we don't want to modify the pseudo-syscall numbers */
        sys = mips64_syscall_resolve_name(name);
-       if (sys == __NR_SCMP_ERROR)
+       if (sys == __NR_SCMP_ERROR || sys < 0)
                return sys;
 
        return sys + __SCMP_NR_BASE;
@@ -59,7 +60,10 @@ int mips64_syscall_resolve_name_munge(const char *name)
  */
 const char *mips64_syscall_resolve_num_munge(int num)
 {
-       return mips64_syscall_resolve_num(num - __SCMP_NR_BASE);
+       /* NOTE: we don't want to modify the pseudo-syscall numbers */
+       if (num >= __SCMP_NR_BASE)
+               num -= __SCMP_NR_BASE;
+       return mips64_syscall_resolve_num(num);
 }
 
 const struct arch_def arch_def_mips64 = {
index f8088aeec3d0a4e1cea88fdd9e69826d29c5414c..098864befc21477e2d6ea980bd03c8abb2e69eff 100644 (file)
@@ -43,8 +43,9 @@ int mips64n32_syscall_resolve_name_munge(const char *name)
 {
        int sys;
 
+       /* NOTE: we don't want to modify the pseudo-syscall numbers */
        sys = mips64n32_syscall_resolve_name(name);
-       if (sys == __NR_SCMP_ERROR)
+       if (sys == __NR_SCMP_ERROR || sys < 0)
                return sys;
 
        return sys + __SCMP_NR_BASE;
@@ -61,7 +62,10 @@ int mips64n32_syscall_resolve_name_munge(const char *name)
  */
 const char *mips64n32_syscall_resolve_num_munge(int num)
 {
-       return mips64n32_syscall_resolve_num(num - __SCMP_NR_BASE);
+       /* NOTE: we don't want to modify the pseudo-syscall numbers */
+       if (num >= __SCMP_NR_BASE)
+               num -= __SCMP_NR_BASE;
+       return mips64n32_syscall_resolve_num(num);
 }
 
 const struct arch_def arch_def_mips64n32 = {
index 389096813dc0b4d25fe7934472e432305dc6faef..50c502eecc2d8a70f2b4351e9a690563910effd0 100644 (file)
@@ -39,8 +39,9 @@ int x32_syscall_resolve_name_munge(const char *name)
 {
        int sys;
 
+       /* NOTE: we don't want to modify the pseudo-syscall numbers */
        sys = x32_syscall_resolve_name(name);
-       if (sys == __NR_SCMP_ERROR)
+       if (sys == __NR_SCMP_ERROR || sys < 0)
                return sys;
 
        return (sys | X32_SYSCALL_BIT);
@@ -57,7 +58,10 @@ int x32_syscall_resolve_name_munge(const char *name)
  */
 const char *x32_syscall_resolve_num_munge(int num)
 {
-       return x32_syscall_resolve_num(num & (~X32_SYSCALL_BIT));
+       /* NOTE: we don't want to modify the pseudo-syscall numbers */
+       if (num >= 0)
+               num &= ~X32_SYSCALL_BIT;
+       return x32_syscall_resolve_num(num);
 }
 
 const struct arch_def arch_def_x32 = {