Id nsolvables = pool->nsolvables;
if (!count)
return nsolvables;
+ if (count < 0 || count >= SOLV_MAX_BLKLEN)
+ solv_ovfl("solvable count overflow");
pool->solvables = solv_extend(pool->solvables, pool->nsolvables, count, sizeof(Solvable), SOLVABLE_BLOCK);
memset(pool->solvables + nsolvables, 0, sizeof(Solvable) * count);
pool->nsolvables += count;
pool->repos = (Repo **)solv_calloc(2, sizeof(Repo *));
}
else
- pool->repos = (Repo **)solv_realloc2(pool->repos, pool->nrepos + 1, sizeof(Repo *));
+ {
+ if (pool->nrepos + 1 >= SOLV_MAX_BLKLEN)
+ solv_ovfl("repository count overflow");
+ pool->repos = (Repo **)solv_realloc2(pool->repos, pool->nrepos + 1, sizeof(Repo *));
+ }
pool->repos[pool->nrepos] = repo;
pool->urepos++;
repo->repoid = pool->nrepos++;
Offset
repo_reserve_ids(Repo *repo, Offset olddeps, int num)
{
+ if (num < 0 || num >= SOLV_MAX_BLKLEN)
+ solv_ovfl("dependency array overflow");
num++; /* room for trailing ID_NULL */
if (!repo->idarraysize) /* ensure buffer space */
}
else
{
+ if (repo->nrepodata + 1 >= SOLV_MAX_BLKLEN)
+ solv_ovfl("repodata count overflow");
repo->nrepodata++;
repo->repodata = solv_realloc2(repo->repodata, repo->nrepodata, sizeof(*data));
}
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#include <limits.h>
#include "repo_solv.h"
#include "util.h"
data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "read_id: id too large (%u/%u)", x, max);
return 0;
}
+ else if (x >= 0x7fffffffU)
+ {
+ data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "read_id: id too large (%u)", x);
+ return 0;
+ }
return x;
}
x = (x << 7) ^ c ^ 128;
data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "read_idarray: id too large (%u/%u)", x, max);
return 0;
}
+ else if (x >= 0x7fffffffU)
+ {
+ data->error = pool_error(data->repo->pool, SOLV_ERROR_ID_RANGE, "read_idarray: id too large (%u)", x);
+ return 0;
+ }
if (map)
x = map[x];
if (store == end)
key = keys + i;
key->name = id;
key->type = type;
- key->size = read_id(&data, type == REPOKEY_TYPE_CONSTANTID ? numid + numrel : 0);
- key->storage = read_id(&data, 0);
+ key->size = read_id(&data, type == REPOKEY_TYPE_CONSTANTID ? numid + numrel : SOLV_MAX_BLKLEN);
+ key->storage = read_id(&data, SOLV_MAX_BLKLEN);
/* old versions used SOLVABLE for main solvable data */
if (key->storage != KEY_STORAGE_INCORE && key->storage != KEY_STORAGE_VERTICAL_OFFSET && key->storage != KEY_STORAGE_SOLVABLE && key->storage != KEY_STORAGE_IDARRAYBLOCK)
data.error = pool_error(pool, SOLV_ERROR_UNSUPPORTED, "unsupported storage type %d", key->storage);
/******* Part 5: Schemata ********************************************/
- id = read_id(&data, 0);
+ id = read_id(&data, SOLV_MAX_BLKLEN);
schemadata = solv_calloc(id + 1, sizeof(Id));
schemadatap = schemadata + 1;
schemadataend = schemadatap + id;
idarraydatap = idarraydataend = 0;
size_idarray = 0;
- maxsize = read_id(&data, 0);
- allsize = read_id(&data, 0);
- if (maxsize < 0 || allsize < 0)
- {
- data.error = pool_error(pool, SOLV_ERROR_CORRUPT, "negative data size in solv header");
- id = 0;
- goto data_error;
- }
- if (maxsize > INT_MAX - 5)
- {
- data.error = pool_error(pool, SOLV_ERROR_OVERFLOW, "data size overflow in solv header");
- id = 0;
- goto data_error;
- }
+ maxsize = read_id(&data, SOLV_MAX_BLKLEN);
+ allsize = read_id(&data, SOLV_MAX_BLKLEN);
+ if (data.error)
+ goto data_error;
maxsize += 5; /* so we can read the next schema of an array */
if (maxsize > allsize)
maxsize = allsize;
id = keys[i].name;
if ((keys[i].type == REPOKEY_TYPE_IDARRAY || keys[i].type == REPOKEY_TYPE_REL_IDARRAY)
&& id >= INTERESTED_START && id <= INTERESTED_END)
- size_idarray += keys[i].size;
+ {
+ size_idarray += keys[i].size;
+ if ((unsigned int)size_idarray >= (unsigned int)SOLV_MAX_BLKLEN)
+ break;
+ }
+ }
+ if (i < numkeys)
+ {
+ data.error = pool_error(pool, SOLV_ERROR_CORRUPT, "idarray size overflow");
+ size_idarray = 0;
+ break; /* overflow */
}
/* allocate needed space in repo */
/* we add maxsize because it is an upper limit for all idarrays, thus we can't overflow */
Id
repodata_schema2id(Repodata *data, Id *schema, int create)
{
- int h, len, i;
+ int h, i;
Id *sp, cid;
Id *schematahash;
+ size_t len;
if (!*schema)
return 0; /* XXX: allow empty schema? */
/* a new one */
if (!create)
return 0;
+ if (len >= SOLV_MAX_BLKLEN)
+ solv_ovfl("schema length overflow");
data->schemadata = solv_extend(data->schemadata, data->schemadatalen, len, sizeof(Id), SCHEMATADATA_BLOCK);
data->schemata = solv_extend(data->schemata, data->nschemata, 1, sizeof(Id), SCHEMATA_BLOCK);
/* add schema */
#define STRING_BLOCK 2047
#define STRINGSPACE_BLOCK 65535
+#define STRING_MAXSIZE 0x40000000
+
void
stringpool_init(Stringpool *ss, const char *strs[])
{
if (!len)
return STRID_EMPTY;
+ if (len >= STRING_MAXSIZE)
+ {
+ solv_ovfl("maximum string size overflow");
+ return 0;
+ }
+
hashmask = ss->stringhashmask;
/* expand hashtable if needed */
Id
stringpool_str2id(Stringpool *ss, const char *str, int create)
{
+ size_t len;
if (!str)
return STRID_NULL;
if (!*str)
return STRID_EMPTY;
- return stringpool_strn2id(ss, str, (unsigned int)strlen(str), create);
+ len = strlen(str);
+ if (len >= STRING_MAXSIZE)
+ {
+ solv_ovfl("maximum string size overflow");
+ return 0;
+ }
+ return stringpool_strn2id(ss, str, (unsigned int)len, create);
}
void
#include "util.h"
+void
+solv_ovfl(const char *str)
+{
+ fprintf(stderr, "%s\n", str);
+ abort();
+ exit(1);
+}
+
void
solv_oom(size_t num, size_t len)
{
len = nlen;
}
}
+ if (len >= SOLV_MAX_BLKLEN)
+ solv_ovfl("solv extend realloc overflow");
return solv_realloc2(old, len, size);
}
extern char *solv_latin1toutf8(const char *buf);
extern char *solv_replacebadutf8(const char *buf, int replchar);
+#ifdef LIBSOLV_INTERNAL
+#define SOLV_MAX_BLKLEN 0x7fff0000
+extern void solv_ovfl(const char *);
+#endif
+
static inline void *solv_extend(void *buf, size_t len, size_t nmemb, size_t size, size_t block)
{