There are a few instances of
for (i = 0; i < FOO; ++i) { ret = do_stuff(i) if (ret) goto err; } ... err: while (--i) undo_stuff(i);
At best, this fails to undo_stuff for i==0, but if i==0 was the case that failed, we'll end up with an "infinite" loop in the error path doing nasty stuff.
These were found with a simple coccinelle script
@@ expression i; identifier l; statement S; @@ * l: * while (--i) S
(and there were no false positives).
There's no dependencies between the patches; I just wanted to include a common cover letter with a little background info.
Rasmus Villemoes (5): drm/gma500: fix error path in gma_intel_setup_gmbus() drm/i915: fix error path in intel_setup_gmbus() net/mlx4: fix some error handling in mlx4_multi_func_init() net: sxgbe: fix error paths in sxgbe_platform_probe() mm/backing-dev.c: fix error path in wb_init()
drivers/gpu/drm/gma500/intel_gmbus.c | 2 +- drivers/gpu/drm/i915/intel_i2c.c | 2 +- drivers/net/ethernet/mellanox/mlx4/cmd.c | 4 ++-- drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c | 4 ++-- mm/backing-dev.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-)
The current code fails to call i2c_del_adapter on dev_prev->gmbus[0].adapter, and if the for loop above failed already at i==0, all hell breaks loose when we do the loop body for i = -1,-2,...
Signed-off-by: Rasmus Villemoes linux@rasmusvillemoes.dk --- drivers/gpu/drm/gma500/intel_gmbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c index 566d330aaeea..e7e22187c539 100644 --- a/drivers/gpu/drm/gma500/intel_gmbus.c +++ b/drivers/gpu/drm/gma500/intel_gmbus.c @@ -436,7 +436,7 @@ int gma_intel_setup_gmbus(struct drm_device *dev) return 0;
err: - while (--i) { + while (i--) { struct intel_gmbus *bus = &dev_priv->gmbus[i]; i2c_del_adapter(&bus->adapter); }
On Tue, Feb 9, 2016 at 10:11 PM, Rasmus Villemoes linux@rasmusvillemoes.dk wrote:
The current code fails to call i2c_del_adapter on dev_prev->gmbus[0].adapter, and if the for loop above failed already at i==0, all hell breaks loose when we do the loop body for i = -1,-2,...
Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com
Signed-off-by: Rasmus Villemoes linux@rasmusvillemoes.dk
drivers/gpu/drm/gma500/intel_gmbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c index 566d330aaeea..e7e22187c539 100644 --- a/drivers/gpu/drm/gma500/intel_gmbus.c +++ b/drivers/gpu/drm/gma500/intel_gmbus.c @@ -436,7 +436,7 @@ int gma_intel_setup_gmbus(struct drm_device *dev) return 0;
err:
while (--i) {
while (i--) { struct intel_gmbus *bus = &dev_priv->gmbus[i]; i2c_del_adapter(&bus->adapter); }
-- 2.1.4
On Wed, Feb 10, 2016 at 08:41:17AM +0200, Andy Shevchenko wrote:
On Tue, Feb 9, 2016 at 10:11 PM, Rasmus Villemoes linux@rasmusvillemoes.dk wrote:
The current code fails to call i2c_del_adapter on dev_prev->gmbus[0].adapter, and if the for loop above failed already at i==0, all hell breaks loose when we do the loop body for i = -1,-2,...
Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com
Applied to drm-misc, thanks. -Daniel
Signed-off-by: Rasmus Villemoes linux@rasmusvillemoes.dk
drivers/gpu/drm/gma500/intel_gmbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c index 566d330aaeea..e7e22187c539 100644 --- a/drivers/gpu/drm/gma500/intel_gmbus.c +++ b/drivers/gpu/drm/gma500/intel_gmbus.c @@ -436,7 +436,7 @@ int gma_intel_setup_gmbus(struct drm_device *dev) return 0;
err:
while (--i) {
while (i--) { struct intel_gmbus *bus = &dev_priv->gmbus[i]; i2c_del_adapter(&bus->adapter); }
-- 2.1.4
-- With Best Regards, Andy Shevchenko _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
This fails to undo the setup for pin==0; moreover, something interesting happens if the setup failed already at pin==0.
Signed-off-by: Rasmus Villemoes linux@rasmusvillemoes.dk --- drivers/gpu/drm/i915/intel_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 25254b5c1ac5..deb8282c26d8 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -683,7 +683,7 @@ int intel_setup_gmbus(struct drm_device *dev) return 0;
err: - while (--pin) { + while (pin--) { if (!intel_gmbus_is_valid_pin(dev_priv, pin)) continue;
On Tue, 09 Feb 2016, Rasmus Villemoes linux@rasmusvillemoes.dk wrote:
This fails to undo the setup for pin==0; moreover, something interesting happens if the setup failed already at pin==0.
Signed-off-by: Rasmus Villemoes linux@rasmusvillemoes.dk
drivers/gpu/drm/i915/intel_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 25254b5c1ac5..deb8282c26d8 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -683,7 +683,7 @@ int intel_setup_gmbus(struct drm_device *dev) return 0;
err:
- while (--pin) {
- while (pin--) { if (!intel_gmbus_is_valid_pin(dev_priv, pin)) continue;
Reviewed-by: Jani Nikula jani.nikula@intel.com Fixes: f899fc64cda8 ("drm/i915: use GMBUS to manage i2c links") Cc: stable@vger.kernel.org
On Tue, 09 Feb 2016, Jani Nikula jani.nikula@linux.intel.com wrote:
On Tue, 09 Feb 2016, Rasmus Villemoes linux@rasmusvillemoes.dk wrote:
This fails to undo the setup for pin==0; moreover, something interesting happens if the setup failed already at pin==0.
Signed-off-by: Rasmus Villemoes linux@rasmusvillemoes.dk
drivers/gpu/drm/i915/intel_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 25254b5c1ac5..deb8282c26d8 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -683,7 +683,7 @@ int intel_setup_gmbus(struct drm_device *dev) return 0;
err:
- while (--pin) {
- while (pin--) { if (!intel_gmbus_is_valid_pin(dev_priv, pin)) continue;
Reviewed-by: Jani Nikula jani.nikula@intel.com Fixes: f899fc64cda8 ("drm/i915: use GMBUS to manage i2c links") Cc: stable@vger.kernel.org
And picked up to drm-intel-next-queued, thanks for the patch.
BR, Jani.
dri-devel@lists.freedesktop.org