Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit cf47cfd

Browse files
sugoi1c0d1f1ed
authored andcommitted
Guard against out of bounds accesses caused by a large base level
A texture's base level can be any positive integer, but SwiftShader stores texture levels in a array that has an implementation dependent size (IMPLEMENTATION_MAX_TEXTURE_LEVELS). To avoid accessing this array out of bounds, a class was added to make sure all accesses to the array are done within its bounds. Change-Id: I9b439018f209a47371bd2959ba847345326964dd Reviewed-on: https://swiftshader-review.googlesource.com/20488 Tested-by: Alexis Hétu <[email protected]> Tested-by: Nicolas Capens <[email protected]> Reviewed-by: Nicolas Capens <[email protected]>
1 parent 3655209 commit cf47cfd

File tree

2 files changed

+56
-65
lines changed

2 files changed

+56
-65
lines changed

src/OpenGL/libGLESv2/Texture.cpp

Lines changed: 5 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -420,11 +420,6 @@ bool Texture::isMipmapFiltered(Sampler *sampler) const
420420

421421
Texture2D::Texture2D(GLuint name) : Texture(name)
422422
{
423-
for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
424-
{
425-
image[i] = nullptr;
426-
}
427-
428423
mSurface = nullptr;
429424

430425
mColorbufferProxy = nullptr;
@@ -433,14 +428,7 @@ Texture2D::Texture2D(GLuint name) : Texture(name)
433428

434429
Texture2D::~Texture2D()
435430
{
436-
for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
437-
{
438-
if(image[i])
439-
{
440-
image[i]->unbind(this);
441-
image[i] = nullptr;
442-
}
443-
}
431+
image.unbind(this);
444432

445433
if(mSurface)
446434
{
@@ -562,14 +550,7 @@ void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLint inter
562550

563551
void Texture2D::bindTexImage(gl::Surface *surface)
564552
{
565-
for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
566-
{
567-
if(image[level])
568-
{
569-
image[level]->release();
570-
image[level] = nullptr;
571-
}
572-
}
553+
image.release();
573554

574555
image[0] = surface->getRenderTarget();
575556

@@ -579,14 +560,7 @@ void Texture2D::bindTexImage(gl::Surface *surface)
579560

580561
void Texture2D::releaseTexImage()
581562
{
582-
for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
583-
{
584-
if(image[level])
585-
{
586-
image[level]->release();
587-
image[level] = nullptr;
588-
}
589-
}
563+
image.release();
590564

591565
if(mSurface)
592566
{
@@ -902,14 +876,6 @@ Renderbuffer *Texture2DRect::getRenderbuffer(GLenum target, GLint level)
902876

903877
TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name)
904878
{
905-
for(int f = 0; f < 6; f++)
906-
{
907-
for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
908-
{
909-
image[f][i] = nullptr;
910-
}
911-
}
912-
913879
for(int f = 0; f < 6; f++)
914880
{
915881
mFaceProxies[f] = nullptr;
@@ -919,20 +885,9 @@ TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name)
919885

920886
TextureCubeMap::~TextureCubeMap()
921887
{
922-
for(int f = 0; f < 6; f++)
923-
{
924-
for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
925-
{
926-
if(image[f][i])
927-
{
928-
image[f][i]->unbind(this);
929-
image[f][i] = nullptr;
930-
}
931-
}
932-
}
933-
934888
for(int i = 0; i < 6; i++)
935889
{
890+
image[i].unbind(this);
936891
mFaceProxies[i] = nullptr;
937892
}
938893
}
@@ -1440,11 +1395,6 @@ bool TextureCubeMap::isShared(GLenum target, unsigned int level) const
14401395

14411396
Texture3D::Texture3D(GLuint name) : Texture(name)
14421397
{
1443-
for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1444-
{
1445-
image[i] = nullptr;
1446-
}
1447-
14481398
mSurface = nullptr;
14491399

14501400
mColorbufferProxy = nullptr;
@@ -1453,14 +1403,7 @@ Texture3D::Texture3D(GLuint name) : Texture(name)
14531403

14541404
Texture3D::~Texture3D()
14551405
{
1456-
for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1457-
{
1458-
if(image[i])
1459-
{
1460-
image[i]->unbind(this);
1461-
image[i] = nullptr;
1462-
}
1463-
}
1406+
image.unbind(this);
14641407

14651408
if(mSurface)
14661409
{

src/OpenGL/libGLESv2/Texture.h

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,54 @@ enum
4545
IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION,
4646
};
4747

48+
class ImageLevels
49+
{
50+
public:
51+
inline const egl::Image* operator[](size_t index) const
52+
{
53+
return (index < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? image[index] : nullptr;
54+
}
55+
56+
inline egl::Image*& operator[](size_t index)
57+
{
58+
if(index < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
59+
{
60+
return image[index];
61+
}
62+
63+
static egl::Image* nullImage;
64+
nullImage = nullptr;
65+
return nullImage;
66+
}
67+
68+
inline void release()
69+
{
70+
for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
71+
{
72+
if(image[i])
73+
{
74+
image[i]->release();
75+
image[i] = nullptr;
76+
}
77+
}
78+
}
79+
80+
inline void unbind(const egl::Texture* texture)
81+
{
82+
for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
83+
{
84+
if(image[i])
85+
{
86+
image[i]->unbind(texture);
87+
image[i] = nullptr;
88+
}
89+
}
90+
}
91+
92+
private:
93+
egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS] = {};
94+
};
95+
4896
class Texture : public egl::Texture
4997
{
5098
public:
@@ -192,7 +240,7 @@ class Texture2D : public Texture
192240

193241
bool isMipmapComplete() const;
194242

195-
egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
243+
ImageLevels image;
196244

197245
gl::Surface *mSurface;
198246

@@ -265,7 +313,7 @@ class TextureCubeMap : public Texture
265313
// face is one of the GL_TEXTURE_CUBE_MAP_* enumerants. Returns nullptr on failure.
266314
egl::Image *getImage(GLenum face, unsigned int level);
267315

268-
egl::Image *image[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
316+
ImageLevels image[6];
269317

270318
// A specific internal reference count is kept for colorbuffer proxy references,
271319
// because, as the renderbuffer acting as proxy will maintain a binding pointer
@@ -321,7 +369,7 @@ class Texture3D : public Texture
321369

322370
bool isMipmapComplete() const;
323371

324-
egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
372+
ImageLevels image;
325373

326374
gl::Surface *mSurface;
327375

0 commit comments

Comments
 (0)