Commit 9d901791 by Martin Radev Committed by Commit Bot

Fix KHR_Debug segfault errors

Calls to functions ObjectLabel, ObjectPtrLabel, GetObjectLabel, GetObjectPtrLabel were resulting into segfaults due to improper validation and parameter handling. It could be that the implementations of those functions were based on an earlier version of the KHR_Debug extension. The patch fixes the segfault error and almost all failing dEQP 3.1 tests related to KHR_Debug. The failing tests were also relevant to older ES versions. There is still one failing test, but that one fails since ES3.1 is not fully supported yet. List of reasons for the segfault error and failing tests: - the segfault error was caused by strlen called on a null pointer - another segfault was caused by writing out the length to a null pointer - even if the buffer size for getObject(Ptr)Label is 0, still the length of the label can be returned. That was not handled. BUG=angleproject:1446 TEST=angle_deqp_gtest_gles31_tests --gtest_filter=*functional_debug_object* Change-Id: I4743be8e862f3620091061cd7abb206a426655ed Reviewed-on: https://chromium-review.googlesource.com/361300Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 29f908bf
...@@ -173,6 +173,36 @@ bool GetNoError(const egl::AttributeMap &attribs) ...@@ -173,6 +173,36 @@ bool GetNoError(const egl::AttributeMap &attribs)
return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE); return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
} }
std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
{
std::string labelName;
if (label != nullptr)
{
size_t labelLength = length < 0 ? strlen(label) : length;
labelName = std::string(label, labelLength);
}
return labelName;
}
void GetObjectLabelBase(const std::string &objectLabel,
GLsizei bufSize,
GLsizei *length,
GLchar *label)
{
size_t writeLength = objectLabel.length();
if (label != nullptr && bufSize > 0)
{
writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
label[writeLength] = '\0';
}
if (length != nullptr)
{
*length = static_cast<GLsizei>(writeLength);
}
}
} // anonymous namespace } // anonymous namespace
namespace gl namespace gl
...@@ -857,6 +887,49 @@ LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const ...@@ -857,6 +887,49 @@ LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))); return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
} }
void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
{
LabeledObject *object = getLabeledObject(identifier, name);
ASSERT(object != nullptr);
std::string labelName = GetObjectLabelFromPointer(length, label);
object->setLabel(labelName);
}
void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
{
LabeledObject *object = getLabeledObjectFromPtr(ptr);
ASSERT(object != nullptr);
std::string labelName = GetObjectLabelFromPointer(length, label);
object->setLabel(labelName);
}
void Context::getObjectLabel(GLenum identifier,
GLuint name,
GLsizei bufSize,
GLsizei *length,
GLchar *label) const
{
LabeledObject *object = getLabeledObject(identifier, name);
ASSERT(object != nullptr);
const std::string &objectLabel = object->getLabel();
GetObjectLabelBase(objectLabel, bufSize, length, label);
}
void Context::getObjectPtrLabel(const void *ptr,
GLsizei bufSize,
GLsizei *length,
GLchar *label) const
{
LabeledObject *object = getLabeledObjectFromPtr(ptr);
ASSERT(object != nullptr);
const std::string &objectLabel = object->getLabel();
GetObjectLabelBase(objectLabel, bufSize, length, label);
}
bool Context::isSampler(GLuint samplerName) const bool Context::isSampler(GLuint samplerName) const
{ {
return mResourceManager->isSampler(samplerName); return mResourceManager->isSampler(samplerName);
......
...@@ -178,8 +178,14 @@ class Context final : public ValidationContext ...@@ -178,8 +178,14 @@ class Context final : public ValidationContext
Query *getQuery(GLuint handle, bool create, GLenum type); Query *getQuery(GLuint handle, bool create, GLenum type);
Query *getQuery(GLuint handle) const; Query *getQuery(GLuint handle) const;
TransformFeedback *getTransformFeedback(GLuint handle) const; TransformFeedback *getTransformFeedback(GLuint handle) const;
LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const; void objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
LabeledObject *getLabeledObjectFromPtr(const void *ptr) const; void objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label);
void getObjectLabel(GLenum identifier,
GLuint name,
GLsizei bufSize,
GLsizei *length,
GLchar *label) const;
void getObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label) const;
Texture *getTargetTexture(GLenum target) const; Texture *getTargetTexture(GLenum target) const;
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const; Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
...@@ -588,6 +594,9 @@ class Context final : public ValidationContext ...@@ -588,6 +594,9 @@ class Context final : public ValidationContext
void initCaps(); void initCaps();
LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const;
LabeledObject *getLabeledObjectFromPtr(const void *ptr) const;
std::unique_ptr<rx::ContextImpl> mImplementation; std::unique_ptr<rx::ContextImpl> mImplementation;
// Caps to use for validation // Caps to use for validation
......
...@@ -1601,6 +1601,32 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, ...@@ -1601,6 +1601,32 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier,
} }
} }
static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
{
size_t labelLength = 0;
if (length < 0)
{
if (label != nullptr)
{
labelLength = strlen(label);
}
}
else
{
labelLength = static_cast<size_t>(length);
}
if (labelLength > context->getExtensions().maxLabelLength)
{
context->handleError(
Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH."));
return false;
}
return true;
}
bool ValidateObjectLabelKHR(Context *context, bool ValidateObjectLabelKHR(Context *context,
GLenum identifier, GLenum identifier,
GLuint name, GLuint name,
...@@ -1618,11 +1644,8 @@ bool ValidateObjectLabelKHR(Context *context, ...@@ -1618,11 +1644,8 @@ bool ValidateObjectLabelKHR(Context *context,
return false; return false;
} }
size_t labelLength = (length < 0) ? strlen(label) : length; if (!ValidateLabelLength(context, length, label))
if (labelLength > context->getExtensions().maxLabelLength)
{ {
context->handleError(
Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH."));
return false; return false;
} }
...@@ -1653,8 +1676,7 @@ bool ValidateGetObjectLabelKHR(Context *context, ...@@ -1653,8 +1676,7 @@ bool ValidateGetObjectLabelKHR(Context *context,
return false; return false;
} }
// Can no-op if bufSize is zero. return true;
return bufSize > 0;
} }
static bool ValidateObjectPtrName(Context *context, const void *ptr) static bool ValidateObjectPtrName(Context *context, const void *ptr)
...@@ -1684,11 +1706,8 @@ bool ValidateObjectPtrLabelKHR(Context *context, ...@@ -1684,11 +1706,8 @@ bool ValidateObjectPtrLabelKHR(Context *context,
return false; return false;
} }
size_t labelLength = (length < 0) ? strlen(label) : length; if (!ValidateLabelLength(context, length, label))
if (labelLength > context->getExtensions().maxLabelLength)
{ {
context->handleError(
Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH."));
return false; return false;
} }
...@@ -1718,8 +1737,7 @@ bool ValidateGetObjectPtrLabelKHR(Context *context, ...@@ -1718,8 +1737,7 @@ bool ValidateGetObjectPtrLabelKHR(Context *context,
return false; return false;
} }
// Can no-op if bufSize is zero. return true;
return bufSize > 0;
} }
bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params) bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
......
...@@ -1266,11 +1266,7 @@ void GL_APIENTRY ObjectLabelKHR(GLenum identifier, GLuint name, GLsizei length, ...@@ -1266,11 +1266,7 @@ void GL_APIENTRY ObjectLabelKHR(GLenum identifier, GLuint name, GLsizei length,
return; return;
} }
LabeledObject *object = context->getLabeledObject(identifier, name); context->objectLabel(identifier, name, length, label);
ASSERT(object != nullptr);
std::string lbl(label, (length > 0) ? static_cast<size_t>(length) : strlen(label));
object->setLabel(lbl);
} }
} }
...@@ -1290,14 +1286,7 @@ GetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *leng ...@@ -1290,14 +1286,7 @@ GetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *leng
return; return;
} }
LabeledObject *object = context->getLabeledObject(identifier, name); context->getObjectLabel(identifier, name, bufSize, length, label);
ASSERT(object != nullptr);
const std::string &objectLabel = object->getLabel();
size_t writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
label[writeLength] = '\0';
*length = static_cast<GLsizei>(writeLength);
} }
} }
...@@ -1314,11 +1303,7 @@ void GL_APIENTRY ObjectPtrLabelKHR(const void *ptr, GLsizei length, const GLchar ...@@ -1314,11 +1303,7 @@ void GL_APIENTRY ObjectPtrLabelKHR(const void *ptr, GLsizei length, const GLchar
return; return;
} }
LabeledObject *object = context->getLabeledObjectFromPtr(ptr); context->objectPtrLabel(ptr, length, label);
ASSERT(object != nullptr);
std::string lbl(label, (length > 0) ? static_cast<size_t>(length) : strlen(label));
object->setLabel(lbl);
} }
} }
...@@ -1340,14 +1325,7 @@ void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr, ...@@ -1340,14 +1325,7 @@ void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr,
return; return;
} }
LabeledObject *object = context->getLabeledObjectFromPtr(ptr); context->getObjectPtrLabel(ptr, bufSize, length, label);
ASSERT(object != nullptr);
const std::string &objectLabel = object->getLabel();
size_t writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
label[writeLength] = '\0';
*length = static_cast<GLsizei>(writeLength);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment