Who should be contacted about issues in the CONNECT storage engine? The attached patch is from Debian Bug#838914
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=838914 Apparently the code does direct unaligned accesses of word data. This works fine on the x86 architecture, but on some other architectures (like MIPS), it causes a bus error. In other places in the server code, the similar issue is handled correctly with uint4korr() and similar macros (though these also deal with byte order). I think the patch (or something similar) is good and should be upstreamed. But I am not sure how the CONNECT storage engine is maintained - should this go directly into MariaDB? If there is an upstream maintained CONNECT storage engine, probably it should preferably go there first? - Kristian.g
Description: Handle unaligned buffers in connect's TYPBLK class On MIPS platforms (and probably others) unaligned memory access results in a bus error. In the connect storage engine, block data for some data formats is stored packed in memory and the TYPBLK class is used to read values from it. Since TYPBLK does not have special handling for this packed memory, it can quite easily result in unaligned memory accesses. . The simple way to fix this is to perform all accesses to the main buffer through memcpy. With GCC and optimizations turned on, this call to memcpy is completely optimized away on architectures where unaligned accesses are ok (like x86). Author: James Cowgill <jcowg...@debian.org> --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ Index: mariadb-10.0-10.0.27/storage/connect/valblk.h =================================================================== --- mariadb-10.0-10.0.27.orig/storage/connect/valblk.h +++ mariadb-10.0-10.0.27/storage/connect/valblk.h @@ -139,6 +139,7 @@ class VALBLK : public BLOCK { int Prec; // Precision of float values }; // end of class VALBLK + /***********************************************************************/ /* Class TYPBLK: represents a block of typed values. */ /***********************************************************************/ @@ -151,40 +152,40 @@ class TYPBLK : public VALBLK { // Implementation virtual bool Init(PGLOBAL g, bool check); virtual int GetVlen(void) {return sizeof(TYPE);} - virtual char GetTinyValue(int n) {return (char)Typp[n];} - virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];} - virtual short GetShortValue(int n) {return (short)Typp[n];} - virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];} - virtual int GetIntValue(int n) {return (int)Typp[n];} - virtual uint GetUIntValue(int n) {return (uint)Typp[n];} - virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];} - virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];} - virtual double GetFloatValue(int n) {return (double)Typp[n];} + virtual char GetTinyValue(int n) {return (char)UnalignedRead(n);} + virtual uchar GetUTinyValue(int n) {return (uchar)UnalignedRead(n);} + virtual short GetShortValue(int n) {return (short)UnalignedRead(n);} + virtual ushort GetUShortValue(int n) {return (ushort)UnalignedRead(n);} + virtual int GetIntValue(int n) {return (int)UnalignedRead(n);} + virtual uint GetUIntValue(int n) {return (uint)UnalignedRead(n);} + virtual longlong GetBigintValue(int n) {return (longlong)UnalignedRead(n);} + virtual ulonglong GetUBigintValue(int n) {return (ulonglong)UnalignedRead(n);} + virtual double GetFloatValue(int n) {return (double)UnalignedRead(n);} virtual char *GetCharString(char *p, int n); - virtual void Reset(int n) {Typp[n] = 0;} + virtual void Reset(int n) {UnalignedWrite(n, 0);} // Methods using VALBLK::SetValue; virtual void SetValue(PSZ sp, int n); virtual void SetValue(char *sp, uint len, int n); virtual void SetValue(short sval, int n) - {Typp[n] = (TYPE)sval; SetNull(n, false);} + {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);} virtual void SetValue(ushort sval, int n) - {Typp[n] = (TYPE)sval; SetNull(n, false);} + {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);} virtual void SetValue(int lval, int n) - {Typp[n] = (TYPE)lval; SetNull(n, false);} + {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);} virtual void SetValue(uint lval, int n) - {Typp[n] = (TYPE)lval; SetNull(n, false);} + {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);} virtual void SetValue(longlong lval, int n) - {Typp[n] = (TYPE)lval; SetNull(n, false);} + {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);} virtual void SetValue(ulonglong lval, int n) - {Typp[n] = (TYPE)lval; SetNull(n, false);} + {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);} virtual void SetValue(double fval, int n) - {Typp[n] = (TYPE)fval; SetNull(n, false);} + {UnalignedWrite(n, (TYPE)fval); SetNull(n, false);} virtual void SetValue(char cval, int n) - {Typp[n] = (TYPE)cval; SetNull(n, false);} + {UnalignedWrite(n, (TYPE)cval); SetNull(n, false);} virtual void SetValue(uchar cval, int n) - {Typp[n] = (TYPE)cval; SetNull(n, false);} + {UnalignedWrite(n, (TYPE)cval); SetNull(n, false);} virtual void SetValue(PVAL valp, int n); virtual void SetValue(PVBLK pv, int n1, int n2); virtual void SetMin(PVAL valp, int n); @@ -206,6 +207,17 @@ class TYPBLK : public VALBLK { // Members TYPE* const &Typp; const char *Fmt; + + // Unaligned access + TYPE UnalignedRead(int n) const { + TYPE result; + memcpy(&result, Typp + n, sizeof(TYPE)); + return result; + } + + void UnalignedWrite(int n, TYPE value) { + memcpy(Typp + n, &value, sizeof(TYPE)); + } }; // end of class TYPBLK /***********************************************************************/ Index: mariadb-10.0-10.0.27/storage/connect/valblk.cpp =================================================================== --- mariadb-10.0-10.0.27.orig/storage/connect/valblk.cpp +++ mariadb-10.0-10.0.27/storage/connect/valblk.cpp @@ -265,14 +265,14 @@ bool TYPBLK<TYPE>::Init(PGLOBAL g, bool template <class TYPE> char *TYPBLK<TYPE>::GetCharString(char *p, int n) { - sprintf(p, Fmt, Typp[n]); + sprintf(p, Fmt, UnalignedRead(n)); return p; } // end of GetCharString template <> char *TYPBLK<double>::GetCharString(char *p, int n) { - sprintf(p, Fmt, Prec, Typp[n]); + sprintf(p, Fmt, Prec, UnalignedRead(n)); return p; } // end of GetCharString @@ -288,7 +288,7 @@ void TYPBLK<TYPE>::SetValue(PVAL valp, i ChkTyp(valp); if (!(b = valp->IsNull())) - Typp[n] = GetTypedValue(valp); + UnalignedWrite(n, GetTypedValue(valp)); else Reset(n); @@ -350,9 +350,9 @@ void TYPBLK<TYPE>::SetValue(PSZ p, int n ulonglong val = CharToNumber(p, strlen(p), maxval, Unsigned, &minus); if (minus && val < maxval) - Typp[n] = (TYPE)(-(signed)val); + UnalignedWrite(n, (TYPE)(-(signed)val)); else - Typp[n] = (TYPE)val; + UnalignedWrite(n, (TYPE)val); SetNull(n, false); } // end of SetValue @@ -395,7 +395,7 @@ void TYPBLK<double>::SetValue(PSZ p, int longjmp(g->jumper[g->jump_level], Type); } // endif Check - Typp[n] = atof(p); + UnalignedWrite(n, atof(p)); SetNull(n, false); } // end of SetValue @@ -427,7 +427,7 @@ void TYPBLK<TYPE>::SetValue(PVBLK pv, in ChkTyp(pv); if (!(b = pv->IsNull(n2) && Nullable)) - Typp[n1] = GetTypedValue(pv, n2); + UnalignedWrite(n1, GetTypedValue(pv, n2)); else Reset(n1); @@ -478,10 +478,10 @@ void TYPBLK<TYPE>::SetMin(PVAL valp, int { CheckParms(valp, n) TYPE tval = GetTypedValue(valp); - TYPE& tmin = Typp[n]; + TYPE tmin = UnalignedRead(n); if (tval < tmin) - tmin = tval; + UnalignedWrite(n, tval); } // end of SetMin @@ -493,10 +493,10 @@ void TYPBLK<TYPE>::SetMax(PVAL valp, int { CheckParms(valp, n) TYPE tval = GetTypedValue(valp); - TYPE& tmin = Typp[n]; + TYPE tmin = UnalignedRead(n); if (tval > tmin) - tmin = tval; + UnalignedWrite(n, tval); } // end of SetMax @@ -522,7 +522,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, i template <class TYPE> void TYPBLK<TYPE>::Move(int i, int j) { - Typp[j] = Typp[i]; + UnalignedWrite(j, UnalignedRead(i)); MoveNull(i, j); } // end of Move @@ -536,7 +536,7 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n ChkIndx(n); ChkTyp(vp); #endif // _DEBUG - TYPE mlv = Typp[n]; + TYPE mlv = UnalignedRead(n); TYPE vlv = GetTypedValue(vp); return (vlv > mlv) ? 1 : (vlv < mlv) ? (-1) : 0; @@ -548,8 +548,8 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n template <class TYPE> int TYPBLK<TYPE>::CompVal(int i1, int i2) { - TYPE lv1 = Typp[i1]; - TYPE lv2 = Typp[i2]; + TYPE lv1 = UnalignedRead(i1); + TYPE lv2 = UnalignedRead(i2); return (lv1 > lv2) ? 1 : (lv1 < lv2) ? (-1) : 0; } // end of CompVal @@ -586,7 +586,7 @@ int TYPBLK<TYPE>::Find(PVAL vp) TYPE n = GetTypedValue(vp); for (i = 0; i < Nval; i++) - if (n == Typp[i]) + if (n == UnalignedRead(i)) break; return (i < Nval) ? i : (-1); @@ -602,7 +602,7 @@ int TYPBLK<TYPE>::GetMaxLength(void) int i, n, m; for (i = n = 0; i < Nval; i++) { - m = sprintf(buf, Fmt, Typp[i]); + m = sprintf(buf, Fmt, UnalignedRead(i)); n = MY_MAX(n, m); } // endfor i @@ -1332,7 +1332,7 @@ char *DATBLK::GetCharString(char *p, int char *vp; if (Dvalp) { - Dvalp->SetValue(Typp[n]); + Dvalp->SetValue(UnalignedRead(n)); vp = Dvalp->GetCharString(p); } else vp = TYPBLK<int>::GetCharString(p, n); @@ -1348,7 +1348,7 @@ void DATBLK::SetValue(PSZ p, int n) if (Dvalp) { // Decode the string according to format Dvalp->SetValue_psz(p); - Typp[n] = Dvalp->GetIntValue(); + UnalignedWrite(n, Dvalp->GetIntValue()); } else TYPBLK<int>::SetValue(p, n);
_______________________________________________ Mailing list: https://launchpad.net/~maria-developers Post to : maria-developers@lists.launchpad.net Unsubscribe : https://launchpad.net/~maria-developers More help : https://help.launchpad.net/ListHelp