All of lore.kernel.org
 help / color / mirror / Atom feed
* [BUG] dm-writeboost: too big nr_rambuf_pool causes massive memory pressure or panic.
@ 2014-07-12  9:06 Satoru Takeuchi
  2014-07-18  1:01 ` Akira Hayakawa
  0 siblings, 1 reply; 7+ messages in thread
From: Satoru Takeuchi @ 2014-07-12  9:06 UTC (permalink / raw)
  To: dm-devel; +Cc: ejt, ruby.wktk

Hi,

Since the upper limit of nr_rambuf_pool argument, user can set too big value
to this argument.

drivers/md/dm-writeboost-target.c:
===============================================================================
static int consume_optional_argv(struct wb_device *wb, struct dm_arg_set *as)
{
        int r = 0;
        struct dm_target *ti = wb->ti;

        static struct dm_arg _args[] = {
                {0, 4, "Invalid optional argc"},
                {4, 10, "Invalid segment_size_order"},
                {1, UINT_MAX, "Invalid nr_rambuf_pool"},
        };
===============================================================================

It can cause the massive memory pressure to kernel by user's mistake
and results in

 - ENOMEM at the (1) or somewhere, and
 - panic at (2).

drivers/md/dm-writeboost-metadata.c:
===============================================================================
...
static int init_rambuf_pool(struct wb_device *wb)
{
        int r = 0;
        size_t i;

        wb->rambuf_pool = kmalloc(sizeof(struct rambuffer) * wb->nr_rambuf_pool,
                                  GFP_KERNEL);
        if (!wb->rambuf_pool)
                return -ENOMEM; # ................. (1)

        wb->rambuf_cachep = kmem_cache_create("dmwb_rambuf",
                        1 << (wb->segment_size_order + SECTOR_SHIFT),
                        1 << (wb->segment_size_order + SECTOR_SHIFT),
                        SLAB_RED_ZONE, NULL);
        if (!wb->rambuf_cachep) {
                r = -ENOMEM;
                goto bad_cachep;
        }

        for (i = 0; i < wb->nr_rambuf_pool; i++) {
                size_t j;
                struct rambuffer *rambuf = wb->rambuf_pool + i;

                rambuf->data = kmem_cache_alloc(wb->rambuf_cachep, GFP_KERNEL);
                if (!rambuf->data) {
                        WBERR("Failed to allocate rambuf->data");
                        for (j = 0; j < i; j++) {
                                rambuf = wb->rambuf_pool + j;
                                kmem_cache_free(wb->rambuf_cachep, rambuf->data);
                        }
                        r = -ENOMEM;
                        goto bad_alloc_data;
                }
                check_buffer_alignment(rambuf->data);
        }

        return r;

bad_alloc_data:
        kmem_cache_destroy(wb->rambuf_cachep);
bad_cachep:
        kfree(wb->rambuf_pool);
        BUG();                         # ........(2)
        return r;
}
...
===============================================================================

Please decide the appropriate upper limit of nr_rambuf_pool (unfortunately
I don't know about it), and remove BUG() at (2) if it's unnecessary.

Thanks,
Satoru

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-07-22  7:14 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-12  9:06 [BUG] dm-writeboost: too big nr_rambuf_pool causes massive memory pressure or panic Satoru Takeuchi
2014-07-18  1:01 ` Akira Hayakawa
2014-07-19  2:13   ` Satoru Takeuchi
2014-07-19 11:40     ` [PATCH] dm-writeboost: Remove unsure BUG() from init_rambuf_pool Satoru Takeuchi
2014-07-19 18:13       ` Alasdair G Kergon
2014-07-21 13:52         ` Satoru Takeuchi
2014-07-22  7:14       ` Akira Hayakawa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.