diff options
author | Wolfram Sang <wsa@kernel.org> | 2020-12-07 07:57:42 +0100 |
---|---|---|
committer | Wolfram Sang <wsa@kernel.org> | 2020-12-07 07:57:42 +0100 |
commit | 1e04538c751bfc572bfa9995996c7f4af098a625 (patch) | |
tree | 40aa603803f857af4a5a5f25f81b6fb31b8e0152 /lib/strncpy_from_user.c | |
parent | 5e9a97b1f4491b8b65874901ad084348fcaba327 (diff) | |
parent | 0477e92881850d44910a7e94fc2c46f96faa131f (diff) |
Merge branch 'i2c/for-current' into i2c/for-5.11
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); } |