diff options
author | Zach Brown <zab@redhat.com> | 2013-01-23 11:31:24 -0800 |
---|---|---|
committer | Zach Brown <zab@redhat.com> | 2013-02-05 16:09:39 -0800 |
commit | de763395fb05bcd5c1ae32f9cd88d55cb396231c (patch) | |
tree | a544b469ccc48e623abbe6580017ff090c457fb8 | |
parent | 506fb87fe48f38e2999b6265fcc54456ea81c7b1 (diff) | |
download | btrfs-progs-de763395fb05bcd5c1ae32f9cd88d55cb396231c.tar.gz |
btrfs-progs: fix overflow in btrfs_scan_one_dir()
btrfs_scan_one_dir() can overflow an arbitrarily small 256 byte buffer
with an arbitrarily slightly larger 1024 byte buffer as it remembers the
path of a dir to later descend.
Make these buffers the same size to stop the overflow and chose PATH_MAX
for that size so that it won't fail on legitimately bonkers paths.
Signed-off-by: Zach Brown <zab@redhat.com>
-rw-r--r-- | utils.c | 10 |
1 files changed, 4 insertions, 6 deletions
@@ -922,7 +922,7 @@ int get_mountpt(char *dev, char *mntpt, size_t size) struct pending_dir { struct list_head list; - char name[256]; + char name[PATH_MAX]; }; void btrfs_register_one_device(char *fname) @@ -958,7 +958,6 @@ int btrfs_scan_one_dir(char *dirname, int run_ioctl) int ret; int fd; int dirname_len; - int pathlen; char *fullpath; struct list_head pending_list; struct btrfs_fs_devices *tmp_devices; @@ -973,8 +972,7 @@ int btrfs_scan_one_dir(char *dirname, int run_ioctl) again: dirname_len = strlen(pending->name); - pathlen = 1024; - fullpath = malloc(pathlen); + fullpath = malloc(PATH_MAX); dirname = pending->name; if (!fullpath) { @@ -993,11 +991,11 @@ again: break; if (dirent->d_name[0] == '.') continue; - if (dirname_len + strlen(dirent->d_name) + 2 > pathlen) { + if (dirname_len + strlen(dirent->d_name) + 2 > PATH_MAX) { ret = -EFAULT; goto fail; } - snprintf(fullpath, pathlen, "%s/%s", dirname, dirent->d_name); + snprintf(fullpath, PATH_MAX, "%s/%s", dirname, dirent->d_name); ret = lstat(fullpath, &st); if (ret < 0) { fprintf(stderr, "failed to stat %s\n", fullpath); |