btrfs-progs: fix overflow in btrfs_scan_one_dir()
authorZach Brown <zab@redhat.com>
Wed, 23 Jan 2013 19:31:24 +0000 (11:31 -0800)
committerZach Brown <zab@redhat.com>
Wed, 6 Feb 2013 00:09:39 +0000 (16:09 -0800)
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>
utils.c

diff --git a/utils.c b/utils.c
index 4b05961..7a1e39d 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -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);