You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@trafodion.apache.org by "Sandhya Sundaresan (JIRA)" <ji...@apache.org> on 2018/06/20 03:19:00 UTC

[jira] [Resolved] (TRAFODION-3004) SQL dense buffers structure contain a size limit due to an incorrect cast

     [ https://issues.apache.org/jira/browse/TRAFODION-3004?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Sandhya Sundaresan resolved TRAFODION-3004.
-------------------------------------------
       Resolution: Fixed
    Fix Version/s: 2.3

> SQL dense buffers structure contain a size limit due to an incorrect cast
> -------------------------------------------------------------------------
>
>                 Key: TRAFODION-3004
>                 URL: https://issues.apache.org/jira/browse/TRAFODION-3004
>             Project: Apache Trafodion
>          Issue Type: Bug
>          Components: sql-exe
>    Affects Versions: any
>            Reporter: Sandhya Sundaresan
>            Assignee: Sandhya Sundaresan
>            Priority: Major
>             Fix For: 2.3
>
>
> The problem is that we cast the length from UINT32 to unsigned short, in SqlBufferDense::add_tuple_desc(), before actually allocating the buffer for the tupp_descriptor. In my case, since the requested size is over 64KB, allocating a memory not more than 64KB (due to the down cast) allows accessing memory passing beyond the allocation boundary. The suggested modification is to remove the cast (to unsigned short). 
> 1796 tupp_descriptor *SqlBufferDense::add_tuple_desc(Lng32 tup_data_size)
> 1797 {
> 1798 ULng32 rounded_size = ROUND8(tup_data_size);
> 1799 short td_size = ROUND8(sizeof(TupleDescInfo));
> 1800
> 1801 Lng32 freeSpaceNeeded = td_size + rounded_size;
> 1802 if (freeSpace_ < freeSpaceNeeded) // no free space to allocate this tuple
> 1803 return NULL;
> 1804
> 1805 maxTuppDesc_ += 1;
> 1806 freeSpace_ -= freeSpaceNeeded;
> 1807
> 1808 // if buffer is empty, then change status to partially full.
> 1809 if (bufferStatus_ == EMPTY)
> 1810 bufferStatus_ = PARTIAL;
> 1811
> 1812 TupleDescInfo * tdi = NULL;
> 1813 if (lastTupleDesc())
> 1814 tdi =
> 1815 (TupleDescInfo *)(lastTupleDesc()->tupleDesc()->getTupleAddress()
> 1816 + ROUND8(lastTupleDesc()->tupleDesc()->getAllocatedSize()));
> 1817 else
> 1818 tdi = firstTupleDesc();
> 1819
> 1820 tupp_descriptor * td = tdi->tupleDesc();
> 1821 td->init((unsigned short)tup_data_size,
> 1822 0,
> 1823 (char *)td + td_size);
> 1824
> 1825 setPrevTupleDesc(tdi, lastTupleDesc());
> 1826
> 1827 if (lastTupleDesc())
> 1828 setNextTupleDesc(lastTupleDesc(), tdi);
> 1829
> 1830 lastTupleDesc() = tdi;
> 1831
> 1832 setNextTupleDesc(tdi, NULL);
> 1833
> 1834 return td;
> 1835 }
>  
>  
> There are two other places where similar down casting is done.
>  
>  376 // allocate space to hold input params/hostvars
>  377 tupp_descriptor *tp = new(glob->getSpace()) tupp_descriptor;
>  378 char * dataPtr =
>  379 (char *)glob->getSpace()->allocateMemory(root_tdb.inputVarsSize_);
>  380 tp->init(root_tdb.inputVarsSize_,0,dataPtr);
>  381 workAtp_->getTupp(numTuples++) = tp;
>  382 }
>  383
>  384 if (root_tdb.updateCurrentOfQuery())
>  385 {
>  386 // allocate space to hold input pkey row
>  387 tupp_descriptor *tp = new(glob->getSpace()) tupp_descriptor;
>  388 char * dataPtr =
>  389 (char *)glob->getSpace()->allocateMemory(root_tdb.pkeyLen_);
>  390 tp->init((short) root_tdb.pkeyLen_,0,dataPtr);
>  391 workAtp_->getTupp(numTuples++) = tp;
>  392 }
>  393 else if (pkeyExpr())
>  394 {
>  395 pkeyAtp_ = allocateAtp(root_tdb.workCriDesc_, glob->getSpace());
>  396
>  397 // allocate space to hold the row of primary keys
>  398 tupp_descriptor *tp = new(glob->getSpace()) tupp_descriptor;
>  399 char * dataPtr =
>  400 (char *)glob->getSpace()->allocateMemory(root_tdb.pkeyLen_);
>  401 tp->init((short) root_tdb.pkeyLen_,0,dataPtr);
>  402 pkeyAtp_->getTupp(2) = tp;
>  403 }
> 404
>  405 // set the stream timeo
>  
>  
> Also, the offsets stored in tuple_descriptor is unsigned short, which have to be modified to ULng32, to store large tuples (over 64Kb) in dense sql buffer.
>  
> index c3127f5..5fee19a 100644
> --- a/core/sql/exp/ExpSqlTupp.h
> +++ b/core/sql/exp/ExpSqlTupp.h
> @@ -144,8 +144,8 @@ friend class tupp;
>  
>      struct
>      {
> - unsigned short nextTDIOffset_;
> - unsigned short prevTDIOffset_;
> + ULng32 nextTDIOffset_;
> + ULng32 prevTDIOffset_;
>      } tdiOffset_;
>    };
>  @@ -156,8 +156,8 @@ friend class tupp;
>      };
>  
>  protected:
> - unsigned short& nextTDIOffset() \{ return tdiOffset_.nextTDIOffset_; }
> - unsigned short& prevTDIOffset() \{ return tdiOffset_.prevTDIOffset_; }
> + ULng32& nextTDIOffset() \{ return tdiOffset_.nextTDIOffset_; }
> + ULng32& prevTDIOffset() \{ return tdiOffset_.prevTDIOffset_; }



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)