mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-07-28 10:52:02 +00:00
[client] spice: validate bitmap fills and prevent potental VLA crash
This commit is contained in:
@@ -638,25 +638,73 @@ void egl_desktopSpiceConfigure(EGL_Desktop * desktop, int width, int height)
|
|||||||
void egl_desktopSpiceDrawFill(EGL_Desktop * desktop, int x, int y, int width,
|
void egl_desktopSpiceDrawFill(EGL_Desktop * desktop, int x, int y, int width,
|
||||||
int height, uint32_t color)
|
int height, uint32_t color)
|
||||||
{
|
{
|
||||||
|
if (!desktop->spiceTexture || width <= 0 || height <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int64_t right = (int64_t)x + width;
|
||||||
|
const int64_t bottom = (int64_t)y + height;
|
||||||
|
if (x >= desktop->spiceWidth || y >= desktop->spiceHeight ||
|
||||||
|
right <= 0 || bottom <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
x = x < 0 ? 0 : x;
|
||||||
|
y = y < 0 ? 0 : y;
|
||||||
|
width = (right > desktop->spiceWidth ?
|
||||||
|
desktop->spiceWidth : (int)right ) - x;
|
||||||
|
height = (bottom > desktop->spiceHeight ?
|
||||||
|
desktop->spiceHeight : (int)bottom) - y;
|
||||||
|
|
||||||
/* this is a fairly hacky way to do this, but since it's only for the fallback
|
/* this is a fairly hacky way to do this, but since it's only for the fallback
|
||||||
* spice display it's not really an issue */
|
* spice display it's not really an issue */
|
||||||
|
|
||||||
uint32_t line[width];
|
uint32_t * line = malloc((size_t)width * sizeof(*line));
|
||||||
for(int x = 0; x < width; ++x)
|
if (!line)
|
||||||
line[x] = color;
|
{
|
||||||
|
DEBUG_ERROR("Failed to allocate SPICE fill row");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < width; ++i)
|
||||||
|
line[i] = color;
|
||||||
|
|
||||||
for(int dy = 0; dy < height; ++dy)
|
for(int dy = 0; dy < height; ++dy)
|
||||||
egl_textureUpdateRect(desktop->spiceTexture,
|
egl_textureUpdateRect(desktop->spiceTexture,
|
||||||
x, y + dy, width, 1, width, sizeof(line), (uint8_t *)line, false);
|
x, y + dy, width, 1, width, width * sizeof(*line),
|
||||||
|
(uint8_t *)line, false);
|
||||||
|
|
||||||
|
free(line);
|
||||||
atomic_store(&desktop->processFrame, true);
|
atomic_store(&desktop->processFrame, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void egl_desktopSpiceDrawBitmap(EGL_Desktop * desktop, int x, int y, int width,
|
void egl_desktopSpiceDrawBitmap(EGL_Desktop * desktop, int x, int y, int width,
|
||||||
int height, int stride, uint8_t * data, bool topDown)
|
int height, int stride, uint8_t * data, bool topDown)
|
||||||
{
|
{
|
||||||
|
if (!desktop->spiceTexture || !data ||
|
||||||
|
width <= 0 || height <= 0 || stride <= 0 || width > stride / 4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int originalHeight = height;
|
||||||
|
const int64_t right = (int64_t)x + width;
|
||||||
|
const int64_t bottom = (int64_t)y + height;
|
||||||
|
if (x >= desktop->spiceWidth || y >= desktop->spiceHeight ||
|
||||||
|
right <= 0 || bottom <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int sourceX = x < 0 ? -x : 0;
|
||||||
|
const int sourceY = y < 0 ? -y : 0;
|
||||||
|
x = x < 0 ? 0 : x;
|
||||||
|
y = y < 0 ? 0 : y;
|
||||||
|
width = (right > desktop->spiceWidth ?
|
||||||
|
desktop->spiceWidth : (int)right ) - x;
|
||||||
|
height = (bottom > desktop->spiceHeight ?
|
||||||
|
desktop->spiceHeight : (int)bottom) - y;
|
||||||
|
|
||||||
|
const int sourceRow = topDown ?
|
||||||
|
sourceY : originalHeight - sourceY - height;
|
||||||
|
data += (size_t)sourceRow * stride + (size_t)sourceX * 4;
|
||||||
|
|
||||||
egl_textureUpdateRect(desktop->spiceTexture,
|
egl_textureUpdateRect(desktop->spiceTexture,
|
||||||
x, y, width, height, width, stride, data, topDown);
|
x, y, width, height, stride / 4, stride, data, topDown);
|
||||||
atomic_store(&desktop->processFrame, true);
|
atomic_store(&desktop->processFrame, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -615,12 +615,34 @@ static void opengl_spiceDrawFill(LG_Renderer * renderer, int x, int y, int width
|
|||||||
{
|
{
|
||||||
struct Inst * this = UPCAST(struct Inst, renderer);
|
struct Inst * this = UPCAST(struct Inst, renderer);
|
||||||
|
|
||||||
|
if (width <= 0 || height <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int64_t right = (int64_t)x + width;
|
||||||
|
const int64_t bottom = (int64_t)y + height;
|
||||||
|
if (x >= this->spiceSize.x || y >= this->spiceSize.y ||
|
||||||
|
right <= 0 || bottom <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
x = x < 0 ? 0 : x;
|
||||||
|
y = y < 0 ? 0 : y;
|
||||||
|
width = (right > this->spiceSize.x ?
|
||||||
|
this->spiceSize.x : (int)right ) - x;
|
||||||
|
height = (bottom > this->spiceSize.y ?
|
||||||
|
this->spiceSize.y : (int)bottom) - y;
|
||||||
|
|
||||||
/* this is a fairly hacky way to do this, but since it's only for the fallback
|
/* this is a fairly hacky way to do this, but since it's only for the fallback
|
||||||
* spice display it's not really an issue */
|
* spice display it's not really an issue */
|
||||||
|
|
||||||
uint32_t line[width];
|
uint32_t * line = malloc((size_t)width * sizeof(*line));
|
||||||
for(int x = 0; x < width; ++x)
|
if (!line)
|
||||||
line[x] = color;
|
{
|
||||||
|
DEBUG_ERROR("Failed to allocate SPICE fill row");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < width; ++i)
|
||||||
|
line[i] = color;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, this->textures[SPICE_TEXTURE]);
|
glBindTexture(GL_TEXTURE_2D, this->textures[SPICE_TEXTURE]);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT , 4 );
|
glPixelStorei(GL_UNPACK_ALIGNMENT , 4 );
|
||||||
@@ -639,6 +661,7 @@ static void opengl_spiceDrawFill(LG_Renderer * renderer, int x, int y, int width
|
|||||||
line
|
line
|
||||||
);
|
);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
free(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void opengl_spiceDrawBitmap(LG_Renderer * renderer, int x, int y, int width,
|
static void opengl_spiceDrawBitmap(LG_Renderer * renderer, int x, int y, int width,
|
||||||
@@ -646,10 +669,20 @@ static void opengl_spiceDrawBitmap(LG_Renderer * renderer, int x, int y, int wid
|
|||||||
{
|
{
|
||||||
struct Inst * this = UPCAST(struct Inst, renderer);
|
struct Inst * this = UPCAST(struct Inst, renderer);
|
||||||
|
|
||||||
|
if (!data || width <= 0 || height <= 0 ||
|
||||||
|
stride <= 0 || width > stride / 4)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!topDown)
|
if (!topDown)
|
||||||
{
|
{
|
||||||
// this is non-optimal but as spice is a fallback it's not too critical
|
// this is non-optimal but as spice is a fallback it's not too critical
|
||||||
uint8_t line[stride];
|
uint8_t * line = malloc((size_t)stride);
|
||||||
|
if (!line)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to allocate SPICE bitmap row");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for(int y = 0; y < height / 2; ++y)
|
for(int y = 0; y < height / 2; ++y)
|
||||||
{
|
{
|
||||||
uint8_t * top = data + y * stride;
|
uint8_t * top = data + y * stride;
|
||||||
@@ -658,8 +691,25 @@ static void opengl_spiceDrawBitmap(LG_Renderer * renderer, int x, int y, int wid
|
|||||||
memcpy(top , btm , stride);
|
memcpy(top , btm , stride);
|
||||||
memcpy(btm , line, stride);
|
memcpy(btm , line, stride);
|
||||||
}
|
}
|
||||||
|
free(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int64_t right = (int64_t)x + width;
|
||||||
|
const int64_t bottom = (int64_t)y + height;
|
||||||
|
if (x >= this->spiceSize.x || y >= this->spiceSize.y ||
|
||||||
|
right <= 0 || bottom <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int sourceX = x < 0 ? -x : 0;
|
||||||
|
const int sourceY = y < 0 ? -y : 0;
|
||||||
|
x = x < 0 ? 0 : x;
|
||||||
|
y = y < 0 ? 0 : y;
|
||||||
|
width = (right > this->spiceSize.x ?
|
||||||
|
this->spiceSize.x : (int)right ) - x;
|
||||||
|
height = (bottom > this->spiceSize.y ?
|
||||||
|
this->spiceSize.y : (int)bottom) - y;
|
||||||
|
data += (size_t)sourceY * stride + (size_t)sourceX * 4;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, this->textures[SPICE_TEXTURE]);
|
glBindTexture(GL_TEXTURE_2D, this->textures[SPICE_TEXTURE]);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT , 4 );
|
glPixelStorei(GL_UNPACK_ALIGNMENT , 4 );
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / 4);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / 4);
|
||||||
|
|||||||
Reference in New Issue
Block a user