diff options
author | Theodore Ts'o <tytso@mit.edu> | 2008-02-26 22:24:42 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-02-26 22:24:42 -0500 |
commit | 1f1ee1948525632736e8135d797db116d2a34c8d (patch) | |
tree | 67e8733f8b02a01e74b478f74f9179167b6c1d01 /lib/blkid/devname.c | |
parent | dcc91e1053c357efca35e0d5674aa78989ee44bf (diff) | |
download | e2fsprogs-1f1ee1948525632736e8135d797db116d2a34c8d.tar.gz |
libblkid: Add error checking to devicemapper code to avoid segfaults
If a device mapper volume disappears while libblkid code is running,
it is possible for the devicemapper code to return errors, and since
libblkid wasn't checking for error returns, it would dereference a
null pointer and crash. Add error checking to prevent this.
Addresses-RedHat-Bugzilla: #433857
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'lib/blkid/devname.c')
-rw-r--r-- | lib/blkid/devname.c | 105 |
1 files changed, 61 insertions, 44 deletions
diff --git a/lib/blkid/devname.c b/lib/blkid/devname.c index fd646960..29cde8e7 100644 --- a/lib/blkid/devname.c +++ b/lib/blkid/devname.c @@ -154,8 +154,10 @@ set_pri: } #ifdef HAVE_DEVMAPPER -static void dm_quiet_log(int level, const char *file, int line, - const char *f, ...) +static void dm_quiet_log(int level __BLKID_ATTR((unused)), + const char *file __BLKID_ATTR((unused)), + int line __BLKID_ATTR((unused)), + const char *f __BLKID_ATTR((unused)), ...) { return; } @@ -168,38 +170,43 @@ static int dm_device_has_dep(const dev_t dev, const char *name) struct dm_task *task; struct dm_deps *deps; struct dm_info info; - int i; + unsigned int i; + int ret = 0; task = dm_task_create(DM_DEVICE_DEPS); if (!task) - return 0; + goto out; - dm_task_set_name(task, name); - dm_task_run(task); - dm_task_get_info(task, &info); + if (!dm_task_set_name(task, name)) + goto out; - if (!info.exists) { - dm_task_destroy(task); - return 0; - } + if (!dm_task_run(task)) + goto out; + if (!dm_task_get_info(task, &info)) + goto out; + + if (!info.exists) + goto out; + deps = dm_task_get_deps(task); - if (!deps || deps->count == 0) { - dm_task_destroy(task); - return 0; - } + if (!deps || deps->count == 0) + goto out; for (i = 0; i < deps->count; i++) { dev_t dep_dev = deps->device[i]; if (dev == dep_dev) { - dm_task_destroy(task); - return 1; + ret = 1; + goto out; } } - dm_task_destroy(task); - return 0; +out: + if (task) + dm_task_destroy(task); + + return ret; } static int dm_device_is_leaf(const dev_t dev) @@ -212,19 +219,20 @@ static int dm_device_is_leaf(const dev_t dev) dm_log_init(dm_quiet_log); task = dm_task_create(DM_DEVICE_LIST); if (!task) - return 1; + goto out; + dm_log_init(0); - dm_task_run(task); + if (!dm_task_run(task)) + goto out; + names = dm_task_get_names(task); - if (!names || !names->dev) { - dm_task_destroy(task); - return 1; - } + if (!names || !names->dev) + goto out; n = 0; do { - names = (void *)names + next; + names = (struct dm_names *) ((char *)names + next); if (dm_device_has_dep(dev, names->name)) ret = 0; @@ -232,7 +240,9 @@ static int dm_device_is_leaf(const dev_t dev) next = names->next; } while (next); - dm_task_destroy(task); +out: + if (task) + dm_task_destroy(task); return ret; } @@ -245,20 +255,25 @@ static dev_t dm_get_devno(const char *name) task = dm_task_create(DM_DEVICE_INFO); if (!task) - return ret; + goto out; - dm_task_set_name(task, name); - dm_task_run(task); - dm_task_get_info(task, &info); + if (!dm_task_set_name(task, name)) + goto out; - if (!info.exists) { - dm_task_destroy(task); - return ret; - } + if (!dm_task_run(task)) + goto out; + + if (!dm_task_get_info(task, &info)) + goto out; + + if (!info.exists) + goto out; ret = makedev(info.major, info.minor); - dm_task_destroy(task); +out: + if (task) + dm_task_destroy(task); return ret; } @@ -273,15 +288,15 @@ static void dm_probe_all(blkid_cache cache, int only_if_new) dm_log_init(dm_quiet_log); task = dm_task_create(DM_DEVICE_LIST); if (!task) - return; + goto out; dm_log_init(0); - dm_task_run(task); + if (!dm_task_run(task)) + goto out; + names = dm_task_get_names(task); - if (!names || !names->dev) { - dm_task_destroy(task); - return; - } + if (!names || !names->dev) + goto out; n = 0; do { @@ -289,7 +304,7 @@ static void dm_probe_all(blkid_cache cache, int only_if_new) char *device = NULL; dev_t dev = 0; - names = (void *)names + next; + names = (struct dm_names *) ((char *)names + next); rc = asprintf(&device, "mapper/%s", names->name); if (rc < 0) @@ -309,7 +324,9 @@ try_next: next = names->next; } while (next); - dm_task_destroy(task); +out: + if (task) + dm_task_destroy(task); } #endif /* HAVE_DEVMAPPER */ |