Skip to content

Commit 4db9259

Browse files
committed
btrfs-progs: use strncpy_null everywhere
Use the safe version of strncpy that makes sure the string is terminated. To be noted: - the conversion in scrub path handling was skipped - sizes of device paths in some ioctl related structures is BTRFS_DEVICE_PATH_NAME_MAX + 1 Recently gcc 13.3 started to detect problems with our use of strncpy potentially lacking the null terminator, warnings like: cmds/inspect.c: In function ‘cmd_inspect_logical_resolve’: cmds/inspect.c:294:33: warning: ‘__builtin_strncpy’ specified bound 4096 equals destination size [-Wstringop-truncation] 294 | strncpy(mount_path, mounted, PATH_MAX); | ^ Signed-off-by: David Sterba <[email protected]>
1 parent e673aa2 commit 4db9259

13 files changed

+28
-32
lines changed

btrfs-corrupt-block.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1398,7 +1398,7 @@ int main(int argc, char **argv)
13981398
inode = arg_strtou64(optarg);
13991399
break;
14001400
case 'f':
1401-
strncpy(field, optarg, FIELD_BUF_LEN);
1401+
strncpy_null(field, optarg, FIELD_BUF_LEN);
14021402
break;
14031403
case 'x':
14041404
file_extent = arg_strtou64(optarg);

cmds/device.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -799,9 +799,8 @@ static int cmd_device_stats(const struct cmd_struct *cmd, int argc, char **argv)
799799
char path[BTRFS_DEVICE_PATH_NAME_MAX + 1];
800800
int err2;
801801

802-
strncpy(path, (char *)di_args[i].path,
803-
BTRFS_DEVICE_PATH_NAME_MAX);
804-
path[BTRFS_DEVICE_PATH_NAME_MAX] = 0;
802+
strncpy_null(path, (char *)di_args[i].path,
803+
BTRFS_DEVICE_PATH_NAME_MAX + 1);
805804

806805
args.devid = di_args[i].devid;
807806
args.nr_items = BTRFS_DEV_STAT_VALUES_MAX;

cmds/inspect.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ static int cmd_inspect_logical_resolve(const struct cmd_struct *cmd,
258258
if (name[0] == 0) {
259259
path_ptr[-1] = '\0';
260260
path_fd = fd;
261-
strncpy(mount_path, full_path, PATH_MAX);
261+
strncpy_null(mount_path, full_path, PATH_MAX);
262262
} else {
263263
char *mounted = NULL;
264264
char subvol[PATH_MAX];
@@ -291,7 +291,7 @@ static int cmd_inspect_logical_resolve(const struct cmd_struct *cmd,
291291
continue;
292292
}
293293

294-
strncpy(mount_path, mounted, PATH_MAX);
294+
strncpy_null(mount_path, mounted, PATH_MAX);
295295
free(mounted);
296296

297297
path_fd = btrfs_open_dir(mount_path);

cmds/replace.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@ static int cmd_replace_start(const struct cmd_struct *cmd,
266266
goto leave_with_error;
267267
}
268268
} else if (path_is_block_device(srcdev) > 0) {
269-
strncpy((char *)start_args.start.srcdev_name, srcdev,
270-
BTRFS_DEVICE_PATH_NAME_MAX);
269+
strncpy_null((char *)start_args.start.srcdev_name, srcdev,
270+
BTRFS_DEVICE_PATH_NAME_MAX + 1);
271271
start_args.start.srcdevid = 0;
272272
srcdev_size = device_get_partition_size(srcdev);
273273
} else {
@@ -292,8 +292,8 @@ static int cmd_replace_start(const struct cmd_struct *cmd,
292292
goto leave_with_error;
293293
}
294294

295-
strncpy((char *)start_args.start.tgtdev_name, dstdev,
296-
BTRFS_DEVICE_PATH_NAME_MAX);
295+
strncpy_null((char *)start_args.start.tgtdev_name, dstdev,
296+
BTRFS_DEVICE_PATH_NAME_MAX + 1);
297297
ret = btrfs_prepare_device(fddstdev, dstdev, &dstdev_block_count, 0,
298298
PREP_DEVICE_ZERO_END | PREP_DEVICE_VERBOSE |
299299
(discard ? PREP_DEVICE_DISCARD : 0) |

cmds/restore.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -1535,8 +1535,7 @@ static int cmd_restore(const struct cmd_struct *cmd, int argc, char **argv)
15351535
ret = 1;
15361536
goto out;
15371537
}
1538-
strncpy(dir_name, argv[optind + 1], sizeof dir_name);
1539-
dir_name[sizeof dir_name - 1] = 0;
1538+
strncpy_null(dir_name, argv[optind + 1], sizeof(dir_name));
15401539

15411540
/* Strip the trailing / on the dir name */
15421541
len = strlen(dir_name);

cmds/scrub.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,7 @@ static int scrub_start(const struct cmd_struct *cmd, int argc, char **argv,
14371437
sock_path, sizeof(sock_path));
14381438
/* ignore EOVERFLOW, try using a shorter path for the socket */
14391439
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
1440-
strncpy(addr.sun_path, sock_path, sizeof(addr.sun_path) - 1);
1440+
strncpy_null(addr.sun_path, sock_path, sizeof(addr.sun_path));
14411441
ret = bind(prg_fd, (struct sockaddr *)&addr, sizeof(addr));
14421442
if (ret != -1 || errno != EADDRINUSE)
14431443
break;

cmds/subvolume-list.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -547,8 +547,7 @@ static int update_root(struct rb_root *root_lookup,
547547
error_msg(ERROR_MSG_MEMORY, NULL);
548548
exit(1);
549549
}
550-
strncpy(ri->name, name, name_len);
551-
ri->name[name_len] = 0;
550+
strncpy_null(ri->name, name, name_len);
552551
}
553552
if (ref_tree)
554553
ri->ref_tree = ref_tree;
@@ -619,8 +618,7 @@ static int add_root(struct rb_root *root_lookup,
619618
error_msg(ERROR_MSG_MEMORY, NULL);
620619
exit(1);
621620
}
622-
strncpy(ri->name, name, name_len);
623-
ri->name[name_len] = 0;
621+
strncpy_null(ri->name, name, name_len);
624622
}
625623
if (ref_tree)
626624
ri->ref_tree = ref_tree;

common/help.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ void fixup_argv0(char **argv, const char *token)
4747

4848
void set_argv0(char **argv)
4949
{
50-
strncpy(argv0_buf, argv[0], sizeof(argv0_buf));
51-
argv0_buf[sizeof(argv0_buf) - 1] = 0;
50+
strncpy_null(argv0_buf, argv[0], sizeof(argv0_buf));
5251
}
5352

5453
int check_argc_exact(int nargs, int expected)

common/open-utils.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "common/messages.h"
3333
#include "common/path-utils.h"
3434
#include "common/device-scan.h"
35+
#include "common/string-utils.h"
3536
#include "common/open-utils.h"
3637

3738
/*
@@ -103,10 +104,9 @@ int check_mounted_where(int fd, const char *file, char *where, int size,
103104
}
104105

105106
/* Did we find an entry in mnt table? */
106-
if (mnt && size && where) {
107-
strncpy(where, mnt->mnt_dir, size);
108-
where[size-1] = 0;
109-
}
107+
if (mnt && size && where)
108+
strncpy_null(where, mnt->mnt_dir, size);
109+
110110
if (fs_dev_ret)
111111
*fs_dev_ret = fs_devices_mnt;
112112
else if (noscan)

convert/main.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1996,7 +1996,7 @@ int BOX_MAIN(convert)(int argc, char *argv[])
19961996
error("invalid UUID: %s\n", optarg);
19971997
return 1;
19981998
}
1999-
strncpy(fsid, optarg, sizeof(fsid));
1999+
strncpy_null(fsid, optarg, sizeof(fsid));
20002000
}
20012001
break;
20022002
case GETOPT_VAL_HELP:

convert/source-ext2.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "kernel-shared/file-item.h"
3131
#include "common/extent-cache.h"
3232
#include "common/messages.h"
33+
#include "common/string-utils.h"
3334
#include "convert/common.h"
3435
#include "convert/source-fs.h"
3536
#include "convert/source-ext2.h"
@@ -638,7 +639,7 @@ static int ext2_copy_single_xattr(struct btrfs_trans_handle *trans,
638639
data = databuf;
639640
datalen = bufsize;
640641
}
641-
strncpy(namebuf, xattr_prefix_table[name_index], XATTR_NAME_MAX);
642+
strncpy_null(namebuf, xattr_prefix_table[name_index], XATTR_NAME_MAX);
642643
strncat(namebuf, EXT2_EXT_ATTR_NAME(entry), entry->e_name_len);
643644
if (name_len + datalen > BTRFS_LEAF_DATA_SIZE(root->fs_info) -
644645
sizeof(struct btrfs_item) - sizeof(struct btrfs_dir_item)) {

kernel-shared/print-tree.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "common/defs.h"
3737
#include "common/internal.h"
3838
#include "common/messages.h"
39+
#include "common/string-utils.h"
3940
#include "uapi/btrfs.h"
4041

4142
static void print_dir_item_type(struct extent_buffer *eb,
@@ -186,7 +187,7 @@ static void bg_flags_to_str(u64 flags, char *ret)
186187
ret[0] = '\0';
187188
if (flags & BTRFS_BLOCK_GROUP_DATA) {
188189
empty = 0;
189-
strncpy(ret, "DATA", BG_FLAG_STRING_LEN);
190+
strncpy_null(ret, "DATA", BG_FLAG_STRING_LEN);
190191
}
191192
if (flags & BTRFS_BLOCK_GROUP_METADATA) {
192193
if (!empty)
@@ -209,7 +210,7 @@ static void bg_flags_to_str(u64 flags, char *ret)
209210
* Thus here we only fill @profile if it's not single.
210211
*/
211212
if (strncmp(name, "SINGLE", strlen("SINGLE")) != 0)
212-
strncpy(profile, name, BG_FLAG_STRING_LEN);
213+
strncpy_null(profile, name, BG_FLAG_STRING_LEN);
213214
}
214215
if (profile[0]) {
215216
strncat(ret, "|", BG_FLAG_STRING_LEN);
@@ -1398,7 +1399,7 @@ static void print_header_info(struct extent_buffer *eb, unsigned int mode)
13981399
#define DEV_REPLACE_STRING_LEN 64
13991400
#define CASE_DEV_REPLACE_MODE_ENTRY(dest, name) \
14001401
case BTRFS_DEV_REPLACE_ITEM_CONT_READING_FROM_SRCDEV_MODE_##name: \
1401-
strncpy((dest), #name, DEV_REPLACE_STRING_LEN); \
1402+
strncpy_null((dest), #name, DEV_REPLACE_STRING_LEN); \
14021403
break;
14031404

14041405
static void replace_mode_to_str(u64 flags, char *ret)
@@ -1415,7 +1416,7 @@ static void replace_mode_to_str(u64 flags, char *ret)
14151416

14161417
#define CASE_DEV_REPLACE_STATE_ENTRY(dest, name) \
14171418
case BTRFS_IOCTL_DEV_REPLACE_STATE_##name: \
1418-
strncpy((dest), #name, DEV_REPLACE_STRING_LEN); \
1419+
strncpy_null((dest), #name, DEV_REPLACE_STRING_LEN); \
14191420
break;
14201421

14211422
static void replace_state_to_str(u64 flags, char *ret)

mkfs/main.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -1361,8 +1361,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
13611361
source_dir = strdup(optarg);
13621362
break;
13631363
case 'U':
1364-
strncpy(fs_uuid, optarg,
1365-
BTRFS_UUID_UNPARSED_SIZE - 1);
1364+
strncpy_null(fs_uuid, optarg, BTRFS_UUID_UNPARSED_SIZE);
13661365
break;
13671366
case 'K':
13681367
opt_discard = false;
@@ -1371,7 +1370,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
13711370
bconf_be_quiet();
13721371
break;
13731372
case GETOPT_VAL_DEVICE_UUID:
1374-
strncpy(dev_uuid, optarg, BTRFS_UUID_UNPARSED_SIZE - 1);
1373+
strncpy_null(dev_uuid, optarg, BTRFS_UUID_UNPARSED_SIZE);
13751374
break;
13761375
case GETOPT_VAL_SHRINK:
13771376
shrink_rootdir = true;

0 commit comments

Comments
 (0)