forked from Mirrors/btrfs-progs
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>master
parent
506fb87fe4
commit
de763395fb
10
utils.c
10
utils.c
|
@ -922,7 +922,7 @@ int get_mountpt(char *dev, char *mntpt, size_t size)
|
||||||
|
|
||||||
struct pending_dir {
|
struct pending_dir {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
char name[256];
|
char name[PATH_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
void btrfs_register_one_device(char *fname)
|
void btrfs_register_one_device(char *fname)
|
||||||
|
@ -958,7 +958,6 @@ int btrfs_scan_one_dir(char *dirname, int run_ioctl)
|
||||||
int ret;
|
int ret;
|
||||||
int fd;
|
int fd;
|
||||||
int dirname_len;
|
int dirname_len;
|
||||||
int pathlen;
|
|
||||||
char *fullpath;
|
char *fullpath;
|
||||||
struct list_head pending_list;
|
struct list_head pending_list;
|
||||||
struct btrfs_fs_devices *tmp_devices;
|
struct btrfs_fs_devices *tmp_devices;
|
||||||
|
@ -973,8 +972,7 @@ int btrfs_scan_one_dir(char *dirname, int run_ioctl)
|
||||||
|
|
||||||
again:
|
again:
|
||||||
dirname_len = strlen(pending->name);
|
dirname_len = strlen(pending->name);
|
||||||
pathlen = 1024;
|
fullpath = malloc(PATH_MAX);
|
||||||
fullpath = malloc(pathlen);
|
|
||||||
dirname = pending->name;
|
dirname = pending->name;
|
||||||
|
|
||||||
if (!fullpath) {
|
if (!fullpath) {
|
||||||
|
@ -993,11 +991,11 @@ again:
|
||||||
break;
|
break;
|
||||||
if (dirent->d_name[0] == '.')
|
if (dirent->d_name[0] == '.')
|
||||||
continue;
|
continue;
|
||||||
if (dirname_len + strlen(dirent->d_name) + 2 > pathlen) {
|
if (dirname_len + strlen(dirent->d_name) + 2 > PATH_MAX) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto fail;
|
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);
|
ret = lstat(fullpath, &st);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "failed to stat %s\n", fullpath);
|
fprintf(stderr, "failed to stat %s\n", fullpath);
|
||||||
|
|
Loading…
Reference in New Issue