← Back to team overview

maria-developers team mailing list archive

Re: MDEV-18734 ASAN heap-use-after-free in my_strnxfrm_simple_internal upon update on versioned partitioned table

 

Hi Sergei,

On Thu, Mar 21, 2019 at 10:24 PM Sergei Golubchik <serg@xxxxxxxxxxx> wrote:

> Hi, Aleksey!
>
> On Mar 20, Aleksey Midenkov wrote:
> > Hi Sergei!
> >
> > It turned out that only vcol blobs are affected. They are allocated
> > by update_virtual_fields(), so it was enough to just refresh their value
> by
> > doing update_virtual_fields() again after record is restored from the
> > queue. Please review the fix:
> >
> > https://github.com/MariaDB/server/pull/1234
> >
> > diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
> > index 8700610415cb..aa5a04af1dbc 100644
> > --- a/sql/ha_partition.cc
> > +++ b/sql/ha_partition.cc
> > @@ -6251,6 +6251,8 @@ void ha_partition::return_top_record(uchar *buf)
> >
> >    part_id= uint2korr(key_buffer);
> >    memcpy(buf, rec_buffer, m_rec_length);
> > +  if (table->vfield && buf == table->record[0])
> > +    table->update_virtual_fields(this, VCOL_UPDATE_FOR_READ);
> >    m_last_part= part_id;
> >    m_top_entry= part_id;
> >  }
>
> I suspect there's a problem with that still.
>
> With this fix you basically free and reallocate the blob for every
> record. So for all blobs in the queue blob pointers might be invalid.
>
> But the queue might need them if it's sorted by the blob value.
> Try this test case:
>
>   create or replace table t1 (x int primary key,
>     b tinytext, v text as (concat(b)) virtual,
>     index (v(10))
>   ) partition by range columns (x) (
>       partition p1 values less than (4),
>       partition p2 values less than (6),
>       partition pn values less than (maxvalue));
>   insert into t1 (x, b) values (1, 'q'), (2, 'z'), (4, 'a'), (5, 'b'), (6,
> 'x'), (7,'y');
>   select * from t1 where v > 'a';
>   drop table t1;
>
>
The above example did not reproduce anything for me. init_queue() is not
called. If I add UPDATE from the task case, then init_queue() is called but
it is sorted by 'x'. If I modify UPDATE to:

update t1 set b= 'bar' where v > 'a' order by v limit 2;

Then Bounded_queue is used instead of QUICK_RANGE_SELECT.


> here there's an index on the virtual column (to tempt partitioning to
> sort the queue by it) and an expression for a virtual column (to make
> blob to allocate memory for it, and not just reuse the field's pointer).
>
> Here partitioning tries to sort the queue by the index, and fails.
> If you remove concat from the virtual column definition, everything
> works.
>
> Regards,
> Sergei
> Chief Architect MariaDB
> and security@xxxxxxxxxxx
>


-- 
All the best,

Aleksey Midenkov
@midenok

References