drm/amd/display: Implement bounds check for stream encoder creation in DCN301
[platform/kernel/linux-rpi.git] / kernel / sys.c
index 339fee3..7a4ae6d 100644 (file)
 #ifndef GET_TAGGED_ADDR_CTRL
 # define GET_TAGGED_ADDR_CTRL()                (-EINVAL)
 #endif
+#ifndef RISCV_V_SET_CONTROL
+# define RISCV_V_SET_CONTROL(a)                (-EINVAL)
+#endif
+#ifndef RISCV_V_GET_CONTROL
+# define RISCV_V_GET_CONTROL()         (-EINVAL)
+#endif
 
 /*
  * this is where the system-wide overflow UID and GID are defined, for
@@ -2362,19 +2368,45 @@ static int prctl_set_vma(unsigned long opt, unsigned long start,
 }
 #endif /* CONFIG_ANON_VMA_NAME */
 
+static inline unsigned long get_current_mdwe(void)
+{
+       unsigned long ret = 0;
+
+       if (test_bit(MMF_HAS_MDWE, &current->mm->flags))
+               ret |= PR_MDWE_REFUSE_EXEC_GAIN;
+       if (test_bit(MMF_HAS_MDWE_NO_INHERIT, &current->mm->flags))
+               ret |= PR_MDWE_NO_INHERIT;
+
+       return ret;
+}
+
 static inline int prctl_set_mdwe(unsigned long bits, unsigned long arg3,
                                 unsigned long arg4, unsigned long arg5)
 {
+       unsigned long current_bits;
+
        if (arg3 || arg4 || arg5)
                return -EINVAL;
 
-       if (bits & ~(PR_MDWE_REFUSE_EXEC_GAIN))
+       if (bits & ~(PR_MDWE_REFUSE_EXEC_GAIN | PR_MDWE_NO_INHERIT))
+               return -EINVAL;
+
+       /* NO_INHERIT only makes sense with REFUSE_EXEC_GAIN */
+       if (bits & PR_MDWE_NO_INHERIT && !(bits & PR_MDWE_REFUSE_EXEC_GAIN))
                return -EINVAL;
 
+       /* PARISC cannot allow mdwe as it needs writable stacks */
+       if (IS_ENABLED(CONFIG_PARISC))
+               return -EINVAL;
+
+       current_bits = get_current_mdwe();
+       if (current_bits && current_bits != bits)
+               return -EPERM; /* Cannot unset the flags */
+
+       if (bits & PR_MDWE_NO_INHERIT)
+               set_bit(MMF_HAS_MDWE_NO_INHERIT, &current->mm->flags);
        if (bits & PR_MDWE_REFUSE_EXEC_GAIN)
                set_bit(MMF_HAS_MDWE, &current->mm->flags);
-       else if (test_bit(MMF_HAS_MDWE, &current->mm->flags))
-               return -EPERM; /* Cannot unset the flag */
 
        return 0;
 }
@@ -2384,9 +2416,7 @@ static inline int prctl_get_mdwe(unsigned long arg2, unsigned long arg3,
 {
        if (arg2 || arg3 || arg4 || arg5)
                return -EINVAL;
-
-       return test_bit(MMF_HAS_MDWE, &current->mm->flags) ?
-               PR_MDWE_REFUSE_EXEC_GAIN : 0;
+       return get_current_mdwe();
 }
 
 static int prctl_get_auxv(void __user *addr, unsigned long len)
@@ -2529,11 +2559,6 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
                        else
                                return -EINVAL;
                        break;
-       case PR_GET_AUXV:
-               if (arg4 || arg5)
-                       return -EINVAL;
-               error = prctl_get_auxv((void __user *)arg2, arg3);
-               break;
                default:
                        return -EINVAL;
                }
@@ -2688,6 +2713,11 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
        case PR_SET_VMA:
                error = prctl_set_vma(arg2, arg3, arg4, arg5);
                break;
+       case PR_GET_AUXV:
+               if (arg4 || arg5)
+                       return -EINVAL;
+               error = prctl_get_auxv((void __user *)arg2, arg3);
+               break;
 #ifdef CONFIG_KSM
        case PR_SET_MEMORY_MERGE:
                if (arg3 || arg4 || arg5)
@@ -2708,6 +2738,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
                error = !!test_bit(MMF_VM_MERGE_ANY, &me->mm->flags);
                break;
 #endif
+       case PR_RISCV_V_SET_CONTROL:
+               error = RISCV_V_SET_CONTROL(arg2);
+               break;
+       case PR_RISCV_V_GET_CONTROL:
+               error = RISCV_V_GET_CONTROL();
+               break;
        default:
                error = -EINVAL;
                break;