[email protected] wrote:
> Full_Name: Lukas W
> Version: mdb.master c367c1f69685a4d307acb8cea6945c1d67e1cc7e
> OS: Linux
> URL: ftp://ftp.openldap.org/incoming/
> Submission from: (NULL) (114.23.231.86)
>
>
> Replacing values in sub-databases (with MDB_DUPSORT) can lead to the new 
> data's
> length being ignored. This specific example reproduces the problem (creating 
> the
> entries "1"->"ABC", and "1"->2a2abc"):
>
>       […]
>       mdb_dbi_open(txn, NULL, MDB_DUPSORT, &dbi);
>       key.mv_size = 2;
>       key.mv_data = "1";
>       data.mv_size = 4;
>       data.mv_data = "ABC";
>       mdb_put(txn, dbi, &key, &data, 0);
>       data.mv_data = "abc";
>       mdb_put(txn, dbi, &key, &data, 0);
>
> If one later tries to change a value of one of the existing entries, the new
> value is being copied, but the size is not changed. This could lead to 
> database
> corruption if the new value is longer than the old one as the length of the 
> new
> value is used in memcpy.
>
>       key.mv_ze % = 2;
>       key.mv_data = "1";
>       data.mv_size = 4;
>       data.mv_data = "abc";
>       mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH);
>
>       data.mv_size = 2;
>       data.mv_data = "Q";
>       mdb_cursor_put(cursor, &key, &data, MDB_CURRENT);

This is a misuse of MDB_CURRENT: as documented, the new value is supposed to 
be the same size as the existing value.
>
>       mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT);
>       printf("%s (%d)\n", data.mv_size);
>
> This will output "Q (4)", while it should output "Q (2)". Note that the data 
> in
> the DB probably is "Q\0c", printf just stops at the null character.
> The value is written in mdb.c:7516. Context:
>
>       […]
>       /* same size, just replace it. Note that we could
>        * also reuse this node if the new data is smaller,
>        * but instead we opt to shrink the node in that case.
>        */
>       if (F_ISSET(flags, MDB_RESERVE))
>               data->mv_data = olddata.mv_data;
>       else if (!(mc->mc_flags & C_SUB))
>               memcpy(olddata.mv_data, data->mv_data, data->mv_size);
>       else {
> 7516:         memcpy(NODEKEY(leaf), key->mv_data, key->mv_size);
>               goto fix_parent;
>       }
>       […]
>
>
>


-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/



Reply via email to