4453 jonas oreland 2011-08-16
ndb - wl#4163 j01_fix.diff - bug#12873640
Fix invalid write for Tux-nodes wo/ prefix (if max-len does not fit 16-bytes)
Implement randomized start_page_id (which traps this bug directly)
modified:
storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp
storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp
storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp
4452 Ole John Aske 2011-08-16
SPJ: Make 'class NdbResultStream' more self contained by including info
about query/operation type, and its parent stream inside the class
itself.
modified:
storage/ndb/src/ndbapi/NdbQueryOperation.cpp
=== modified file 'storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp 2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp 2011-08-16 08:27:14 +0000
@@ -155,17 +155,24 @@ Dbtux::setNodePref(TuxCtx & ctx, NodeHan
{
const Frag& frag = node.m_frag;
const Index& index = *c_indexPool.getPtr(frag.m_indexId);
- KeyData prefKey(index.m_keySpec, false, 0);
- prefKey.set_buf(node.getPref(), index.m_prefBytes);
+ /*
+ * bug#12873640
+ * Node prefix exists if it has non-zero number of attributes. It is
+ * then a partial instance of KeyData. If the prefix does not exist
+ * then set_buf() could overwrite m_pageId1 in first entry, causing
+ * random crash in TUP via readKeyAttrs().
+ */
if (index.m_prefAttrs > 0) {
+ KeyData prefKey(index.m_keySpec, false, 0);
+ prefKey.set_buf(node.getPref(), index.m_prefBytes);
jam();
readKeyAttrs(ctx, frag, node.getEnt(0), prefKey, index.m_prefAttrs);
- }
#ifdef VM_TRACE
- if (debugFlags & DebugMaint) {
- debugOut << "setNodePref: " << node;
- debugOut << " " << prefKey.print(ctx.c_debugBuffer, DebugBufferBytes);
- debugOut << endl;
+ if (debugFlags & DebugMaint) {
+ debugOut << "setNodePref: " << node;
+ debugOut << " " << prefKey.print(ctx.c_debugBuffer, DebugBufferBytes);
+ debugOut << endl;
+ }
}
#endif
}
=== modified file 'storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp'
--- a/storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp 2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp 2011-08-16 08:27:14 +0000
@@ -39,6 +39,16 @@ static const char * f_method = "MSms";
#endif
#define MAX_CHUNKS 10
+#ifdef VM_TRACE
+#ifndef NDBD_RANDOM_START_PAGE
+#define NDBD_RANDOM_START_PAGE
+#endif
+#endif
+
+#ifdef NDBD_RANDOM_START_PAGE
+static Uint32 g_random_start_page_id = 0;
+#endif
+
/*
* For muti-threaded ndbd, these calls are used for locking around
* memory allocation operations.
@@ -224,6 +234,16 @@ Ndbd_mem_manager::Ndbd_mem_manager()
mt_mem_manager_init();
}
+void*
+Ndbd_mem_manager::get_memroot() const
+{
+#ifdef NDBD_RANDOM_START_PAGE
+ return (void*)(m_base_page - g_random_start_page_id);
+#else
+ return (void*)m_base_page;
+#endif
+}
+
/**
*
* resource 0 has following semantics:
@@ -359,6 +379,29 @@ Ndbd_mem_manager::init(Uint32 *watchCoun
}
#endif
+#ifdef NDBD_RANDOM_START_PAGE
+ /**
+ * In order to find bad-users of page-id's
+ * we add a random offset to the page-id's returned
+ * however, due to ZONE_LO that offset can't be that big
+ * (since we at get_page don't know if it's a HI/LO page)
+ */
+ Uint32 max_rand_start = ZONE_LO_BOUND - 1;
+ if (max_rand_start > pages)
+ {
+ max_rand_start -= pages;
+ if (max_rand_start > 0x10000)
+ g_random_start_page_id = 0x10000 + (rand() % (max_rand_start - 0x10000));
+ else if (max_rand_start)
+ g_random_start_page_id = rand() % max_rand_start;
+
+ assert(Uint64(pages) + Uint64(g_random_start_page_id) <= 0xFFFFFFFF);
+
+ ndbout_c("using g_random_start_page_id: %u (%.8x)",
+ g_random_start_page_id, g_random_start_page_id);
+ }
+#endif
+
/**
* Do malloc
*/
@@ -670,7 +713,7 @@ Ndbd_mem_manager::alloc(AllocZone zone,
return;
* pages = save;
}
-
+
alloc_impl(ZONE_LO, ret, pages, min);
}
@@ -870,7 +913,12 @@ Ndbd_mem_manager::alloc_page(Uint32 type
check_resource_limits(m_resource_limit);
mt_mem_manager_unlock();
+#ifdef NDBD_RANDOM_START_PAGE
+ *i += g_random_start_page_id;
+ return m_base_page + *i - g_random_start_page_id;
+#else
return m_base_page + *i;
+#endif
}
}
mt_mem_manager_unlock();
@@ -885,7 +933,11 @@ Ndbd_mem_manager::release_page(Uint32 ty
mt_mem_manager_lock();
Resource_limit tot = m_resource_limit[0];
Resource_limit rl = m_resource_limit[idx];
-
+
+#ifdef NDBD_RANDOM_START_PAGE
+ i -= g_random_start_page_id;
+#endif
+
Uint32 sub = (rl.m_curr <= rl.m_min) ? 1 : 0; // Over min ?
release(i, 1);
m_resource_limit[0].m_curr = tot.m_curr - 1;
@@ -954,10 +1006,16 @@ Ndbd_mem_manager::alloc_pages(Uint32 typ
m_resource_limit[idx].m_curr = rl.m_curr + req;
check_resource_limits(m_resource_limit);
mt_mem_manager_unlock();
+#ifdef NDBD_RANDOM_START_PAGE
+ *i += g_random_start_page_id;
+#endif
return ;
}
mt_mem_manager_unlock();
* cnt = req;
+#ifdef NDBD_RANDOM_START_PAGE
+ *i += g_random_start_page_id;
+#endif
return;
}
@@ -969,7 +1027,11 @@ Ndbd_mem_manager::release_pages(Uint32 t
mt_mem_manager_lock();
Resource_limit tot = m_resource_limit[0];
Resource_limit rl = m_resource_limit[idx];
-
+
+#ifdef NDBD_RANDOM_START_PAGE
+ i -= g_random_start_page_id;
+#endif
+
release(i, cnt);
Uint32 currnew = rl.m_curr - cnt;
=== modified file 'storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp'
--- a/storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp 2011-06-30 15:59:25 +0000
+++ b/storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp 2011-08-16 08:27:14 +0000
@@ -68,7 +68,7 @@ public:
bool init(Uint32 *watchCounter, bool allow_alloc_less_than_requested = true);
void map(Uint32 * watchCounter, bool memlock = false, Uint32 resources[] = 0);
- void* get_memroot() const { return (void*)m_base_page;}
+ void* get_memroot() const;
void dump() const ;
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.1-telco-7.0 branch (jonas.oreland:4452 to 4453)Bug#12873640 WL#4163 | jonas oreland | 17 Aug |