| From 26cb43d4c78cba0d04d7f94fbc1d23e7c999d340 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 4 Jan 2023 11:14:45 -0500 |
| Subject: btrfs: replace strncpy() with strscpy() |
| |
| [ Upstream commit 63d5429f68a3d4c4aa27e65a05196c17f86c41d6 ] |
| |
| Using strncpy() on NUL-terminated strings are deprecated. To avoid |
| possible forming of non-terminated string strscpy() should be used. |
| |
| Found by Linux Verification Center (linuxtesting.org) with SVACE. |
| |
| CC: stable@vger.kernel.org # 4.9+ |
| Signed-off-by: Artem Chernyshev <artem.chernyshev@red-soft.ru> |
| Reviewed-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/btrfs/ioctl.c | 9 +++------ |
| fs/btrfs/rcu-string.h | 6 +++++- |
| 2 files changed, 8 insertions(+), 7 deletions(-) |
| |
| diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c |
| index 4fff0067bd2a..c498d5e164eb 100644 |
| --- a/fs/btrfs/ioctl.c |
| +++ b/fs/btrfs/ioctl.c |
| @@ -3750,13 +3750,10 @@ static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info, |
| di_args->bytes_used = btrfs_device_get_bytes_used(dev); |
| di_args->total_bytes = btrfs_device_get_total_bytes(dev); |
| memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid)); |
| - if (dev->name) { |
| - strncpy(di_args->path, rcu_str_deref(dev->name), |
| - sizeof(di_args->path) - 1); |
| - di_args->path[sizeof(di_args->path) - 1] = 0; |
| - } else { |
| + if (dev->name) |
| + strscpy(di_args->path, rcu_str_deref(dev->name), sizeof(di_args->path)); |
| + else |
| di_args->path[0] = '\0'; |
| - } |
| |
| out: |
| rcu_read_unlock(); |
| diff --git a/fs/btrfs/rcu-string.h b/fs/btrfs/rcu-string.h |
| index 5c1a617eb25d..5c2b66d155ef 100644 |
| --- a/fs/btrfs/rcu-string.h |
| +++ b/fs/btrfs/rcu-string.h |
| @@ -18,7 +18,11 @@ static inline struct rcu_string *rcu_string_strdup(const char *src, gfp_t mask) |
| (len * sizeof(char)), mask); |
| if (!ret) |
| return ret; |
| - strncpy(ret->str, src, len); |
| + /* Warn if the source got unexpectedly truncated. */ |
| + if (WARN_ON(strscpy(ret->str, src, len) < 0)) { |
| + kfree(ret); |
| + return NULL; |
| + } |
| return ret; |
| } |
| |
| -- |
| 2.35.1 |
| |