• NeilBrown's avatar
    sysfs: be careful of error returns from ops->show() · c8a139d0
    NeilBrown authored
    ops->show() can return a negative error code.
    Commit 65da3484 ("sysfs: correctly handle short reads on PREALLOC attrs.")
    (in v4.4) caused this to be stored in an unsigned 'size_t' variable, so errors
    would look like large numbers.
    As a result, if an error is returned, sysfs_kf_read() will return the
    value of 'count', typically 4096.
    Commit 17d0774f ("sysfs: correctly handle read offset on PREALLOC attrs")
    (in v4.8) extended this error to use the unsigned large 'len' as a size for
    Consequently, if ->show returns an error, then the first read() on the
    sysfs file will return 4096 and could return uninitialized memory to
    If the application performs a subsequent read, this will trigger a memmove()
    with extremely large count, and is likely to crash the machine is bizarre ways.
    This bug can currently only be triggered by reading from an md
    sysfs attribute declared with __ATTR_PREALLOC() during the
    brief period between when mddev_put() deletes an mddev from
    the ->all_mddevs list, and when mddev_delayed_delete() - which is
    scheduled on a workqueue - completes.
    Before this, an error won't be returned by the ->show()
    After this, the ->show() won't be called.
    I can reproduce it reliably only by putting delay like
    early in mddev_delayed_delete(). Then after creating an
    md device md0 run
      echo clear > /sys/block/md0/md/array_state; cat /sys/block/md0/md/array_state
    The bug can be triggered without the usleep.
    Fixes: 65da3484 ("sysfs: correctly handle short reads on PREALLOC attrs.")
    Fixes: 17d0774f ("sysfs: correctly handle read offset on PREALLOC attrs")
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarNeilBrown <neilb@suse.com>
    Acked-by: default avatarTejun Heo <tj@kernel.org>
    Reported-and-tested-by: default avatarMiroslav Benes <mbenes@suse.cz>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Last commit
Last update
Kconfig Loading commit data...
Makefile Loading commit data...
dir.c Loading commit data...
file.c Loading commit data...
group.c Loading commit data...
mount.c Loading commit data...
symlink.c Loading commit data...
sysfs.h Loading commit data...