Skip to content

Commit 6446cd1

Browse files
committed
Bug #29820838 NDB : LONG LQHKEYREQS CONTAIN INCORRECTLY SET BITS
In some situations, a number of bits are incorrectly set in the long LQHKEYREQ requestInfo field. This can cause misinterpretation on the LQH receiving the LQHKEYREQ, which interprets them as feature switch booleans. Changes : - The code which is incorrectly setting the bits is fixed so that they are not set. This fixes the bug for all future versions - A new self check is added on the affected bits which are currently unused They must not be set on long LQHKEYREQs arriving from same-version nodes. - They may be set on long LQHKEYREQs from : - Older version nodes, still having this bug - Newer version nodes, using the bits for new purposes - Note that for bits which are at-risk, there remains a risk of misinterpreting a set bit, until all versions are upgraded. - Related fix : The logic related to pass-through of requestInfo bits when forwarding LQHKEYREQs between replicas is also updated to pass through only the bits which are needed at Backup replicas. The addition of the self check provides debug-build test coverage existing testcases. Reviewed by Mauritz Sundell <[email protected]>
1 parent 6ca5ecf commit 6446cd1

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

storage/ndb/include/kernel/signaldata/LqhKey.hpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2003, 2019 Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -183,6 +183,11 @@ class LqhKeyReq {
183183
*/
184184
static UintR getDisableFkConstraints(const UintR & requestInfo);
185185
static void setDisableFkConstraints(UintR & requestInfo, UintR val);
186+
187+
/**
188+
* Get mask of currently undefined bits
189+
*/
190+
static UintR getLongClearBits(const UintR& requestInfo);
186191
};
187192

188193
/**
@@ -257,6 +262,17 @@ class LqhKeyReq {
257262
#define RI_DEFERRED_CONSTAINTS (26)
258263
#define RI_DISABLE_FK (0)
259264

265+
/* Currently unused */
266+
#define RI_CLEAR_SHIFT1 (1)
267+
#define RI_CLEAR_SHIFT2 (2)
268+
#define RI_CLEAR_SHIFT3 (3)
269+
#define RI_CLEAR_SHIFT4 (4)
270+
#define RI_CLEAR_SHIFT5 (5)
271+
#define RI_CLEAR_SHIFT6 (6)
272+
#define RI_CLEAR_SHIFT7 (7)
273+
#define RI_CLEAR_SHIFT8 (8)
274+
#define RI_CLEAR_SHIFT9 (9)
275+
260276
/**
261277
* Scan Info
262278
*
@@ -677,6 +693,24 @@ LqhKeyReq::getDisableFkConstraints(const UintR & requestInfo){
677693
return (requestInfo >> RI_DISABLE_FK) & 1;
678694
}
679695

696+
inline
697+
UintR
698+
LqhKeyReq::getLongClearBits(const UintR& requestInfo)
699+
{
700+
const Uint32 mask =
701+
(1 << RI_CLEAR_SHIFT1) |
702+
(1 << RI_CLEAR_SHIFT2) |
703+
(1 << RI_CLEAR_SHIFT3) |
704+
(1 << RI_CLEAR_SHIFT4) |
705+
(1 << RI_CLEAR_SHIFT5) |
706+
(1 << RI_CLEAR_SHIFT6) |
707+
(1 << RI_CLEAR_SHIFT7) |
708+
(1 << RI_CLEAR_SHIFT8) |
709+
(1 << RI_CLEAR_SHIFT9);
710+
711+
return (requestInfo & mask);
712+
}
713+
680714
inline
681715
Uint32
682716
table_version_major_lqhkeyreq(Uint32 x)

storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
33

44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -806,7 +806,7 @@ void Dblqh::execNDB_STTOR(Signal* signal)
806806
case ZSTART_PHASE1:
807807
jam();
808808
preComputedRequestInfoMask = 0;
809-
LqhKeyReq::setKeyLen(preComputedRequestInfoMask, RI_KEYLEN_MASK);
809+
// Dont setDisableFkconstraints - handled on primary
810810
LqhKeyReq::setLastReplicaNo(preComputedRequestInfoMask, RI_LAST_REPL_MASK);
811811
// Dont LqhKeyReq::setApplicationAddressFlag
812812
LqhKeyReq::setDirtyFlag(preComputedRequestInfoMask, 1);
@@ -4916,6 +4916,24 @@ void Dblqh::execLQHKEYREQ(Signal* signal)
49164916
(Operation_t) op == ZUNLOCK ? ZREAD : // lockType not relevant for unlock req
49174917
(Operation_t) op;
49184918
}
4919+
#ifdef VM_TRACE
4920+
if (unlikely(isLongReq &&
4921+
LqhKeyReq::getLongClearBits(Treqinfo) != 0))
4922+
{
4923+
jam();
4924+
/* Bits set which should not be - definite error on same version */
4925+
const Uint32 ownVersion = getNodeInfo(getOwnNodeId()).m_version;
4926+
if (senderVersion == ownVersion)
4927+
{
4928+
jam();
4929+
ndbout_c("Received bad long request info %x from same version node %x %x",
4930+
Treqinfo,
4931+
senderVersion,
4932+
ownVersion);
4933+
ndbrequire(false);
4934+
}
4935+
}
4936+
#endif
49194937

49204938
if (regTcPtr->dirtyOp)
49214939
{
@@ -13349,8 +13367,6 @@ void Dblqh::copyTupkeyConfLab(Signal* signal)
1334913367
return;
1335013368
}
1335113369

13352-
LqhKeyReq::setKeyLen(tcConP->reqinfo, len);
13353-
1335413370
/*---------------------------------------------------------------------------*/
1335513371
// To avoid using up to many operation records in ACC we will increase the
1335613372
// constant to ensure that we never send more than 40 records at a time.
@@ -21843,7 +21859,6 @@ void Dblqh::initReqinfoExecSr(Signal* signal)
2184321859
{
2184421860
UintR Treqinfo = 0;
2184521861
TcConnectionrec * const regTcPtr = tcConnectptr.p;
21846-
LqhKeyReq::setKeyLen(Treqinfo, regTcPtr->primKeyLen);
2184721862
/* ------------------------------------------------------------------------- */
2184821863
/* NUMBER OF BACKUPS AND STANDBYS ARE ZERO AND NEED NOT BE SET. */
2184921864
/* REPLICA TYPE IS CLEARED BY SEND_LQHKEYREQ. */

0 commit comments

Comments
 (0)