In the functions compat_get_bitmap() and compat_put_bitmap() the variable nr_compat_longs stores how many compat_ulong_t words should be copied in a loop. The copy loop itself is this: if (nr_compat_longs-- > 0) { if (__get_user(um, umask)) return -EFAULT; } else { um = 0; } Since nr_compat_longs gets unconditionally decremented in each loop and since it's type is unsigned this could theoretically lead to out of bounds accesses to userspace if nr_compat_longs wraps around to (unsigned)(-1). Although the callers currently do not trigger out-of-bounds accesses, we should better implement the loop in a safe way to completely avoid such warp-arounds.
Unified · Split
| @@ -912,7 +912,8 @@ long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask, · 911 unmodified lines | |||
| 912 | * bitmap. We must however ensure the end of the | 912 | * bitmap. We must however ensure the end of the |
| 913 | * kernel bitmap is zeroed. | 913 | * kernel bitmap is zeroed. |
| 914 | */ | 914 | */ |
| 915 | if (nr_compat_longs-- > 0) { | 915 | if (nr_compat_longs) { |
| 916 | nr_compat_longs--; | ||
| 916 | if (__get_user(um, umask)) | 917 | if (__get_user(um, umask)) |
| 917 | return -EFAULT; | 918 | return -EFAULT; |
| 918 | } else { | 919 | } else { |
| @@ -954,7 +955,8 @@ long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, · 35 unmodified lines | |||
| 954 | * We dont want to write past the end of the userspace | 955 | * We dont want to write past the end of the userspace |
| 955 | * bitmap. | 956 | * bitmap. |
| 956 | */ | 957 | */ |
| 957 | if (nr_compat_longs-- > 0) { | 958 | if (nr_compat_longs) { |
| 959 | nr_compat_longs--; | ||
| 958 | if (__put_user(um, umask)) | 960 | if (__put_user(um, umask)) |
| 959 | return -EFAULT; | 961 | return -EFAULT; |
| 960 | } | 962 | } |