diff options
author | Tony Lindgren <tony@atomide.com> | 2020-12-18 10:15:12 +0300 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2020-12-18 10:15:12 +0300 |
commit | 500050f0d28868af302a3c24d7d1d0191521286e (patch) | |
tree | 7c4366836fcf5c7d7be4292f60d76876b3c463a0 /lib/strncpy_from_user.c | |
parent | c0bc969c176b10598b31d5d1a5edf9a5261f0a9f (diff) | |
parent | 6efac0173cd15460b48c91e1b0a000379f341f00 (diff) | |
download | linux-500050f0d28868af302a3c24d7d1d0191521286e.tar.xz |
Merge branch 'fixes-omap3' into fixes
Diffstat (limited to 'lib/strncpy_from_user.c')
-rw-r--r-- | lib/strncpy_from_user.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c index e6d5fcc2cdf3..122d8d0e253c 100644 --- a/lib/strncpy_from_user.c +++ b/lib/strncpy_from_user.c @@ -35,17 +35,32 @@ static inline long do_strncpy_from_user(char *dst, const char __user *src, goto byte_at_a_time; while (max >= sizeof(unsigned long)) { - unsigned long c, data; + unsigned long c, data, mask; /* Fall back to byte-at-a-time if we get a page fault */ unsafe_get_user(c, (unsigned long __user *)(src+res), byte_at_a_time); - *(unsigned long *)(dst+res) = c; + /* + * Note that we mask out the bytes following the NUL. This is + * important to do because string oblivious code may read past + * the NUL. For those routines, we don't want to give them + * potentially random bytes after the NUL in `src`. + * + * One example of such code is BPF map keys. BPF treats map keys + * as an opaque set of bytes. Without the post-NUL mask, any BPF + * maps keyed by strings returned from strncpy_from_user() may + * have multiple entries for semantically identical strings. + */ if (has_zero(c, &data, &constants)) { data = prep_zero_mask(c, data, &constants); data = create_zero_mask(data); + mask = zero_bytemask(data); + *(unsigned long *)(dst+res) = c & mask; return res + find_zero(data); } + + *(unsigned long *)(dst+res) = c; + res += sizeof(unsigned long); max -= sizeof(unsigned long); } |