->max_alloc to krb5_storage and use it

This commit is contained in:
Love Hornquist Astrand
2011-05-08 00:16:02 -07:00
parent 35652e4a03
commit bd2d4c2f79
7 changed files with 87 additions and 10 deletions

View File

@@ -43,6 +43,7 @@ struct krb5_storage_data {
void (*free)(struct krb5_storage_data*);
krb5_flags flags;
int eof_code;
size_t max_alloc;
};
#endif /* __store_int_h__ */

View File

@@ -119,6 +119,41 @@ krb5_storage_get_byteorder(krb5_storage *sp)
return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
}
/**
* Set the max alloc value
*
* @param sp the storage buffer set the max allow for
* @param size maximum size to allocate, use 0 to remove limit
*
* @ingroup krb5_storage
*/
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_storage_set_max_alloc(krb5_storage *sp, size_t size)
{
sp->max_alloc = size;
}
/* don't allocate unresonable amount of memory */
static krb5_error_code
size_too_large(krb5_storage *sp, size_t size)
{
if (sp->max_alloc && sp->max_alloc < size)
return HEIM_ERR_TOO_BIG;
return 0;
}
static krb5_error_code
size_too_large_num(krb5_storage *sp, size_t count, size_t size)
{
if (sp->max_alloc == 0 || size == 0)
return 0;
size = sp->max_alloc / size;
if (size < count)
return HEIM_ERR_TOO_BIG;
return 0;
}
/**
* Seek to a new offset.
*
@@ -263,9 +298,9 @@ krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
if (pos < 0)
return HEIM_ERR_NOT_SEEKABLE;
size = sp->seek(sp, 0, SEEK_END);
/* don't allocate unresonable amount of memory */
if (size > UINT_MAX/8)
return HEIM_ERR_TOO_BIG;
ret = size_too_large(sp, size);
if (ret)
return ret;
ret = krb5_data_alloc(data, size);
if (ret) {
sp->seek(sp, pos, SEEK_SET);
@@ -645,6 +680,9 @@ krb5_ret_data(krb5_storage *sp,
ret = krb5_ret_int32(sp, &size);
if(ret)
return ret;
ret = size_too_large(sp, size);
if (ret)
return ret;
ret = krb5_data_alloc (data, size);
if (ret)
return ret;
@@ -757,6 +795,9 @@ krb5_ret_stringz(krb5_storage *sp,
char *tmp;
len++;
ret = size_too_large(sp, len);
if (ret)
break;
tmp = realloc (s, len);
if (tmp == NULL) {
free (s);
@@ -823,6 +864,9 @@ krb5_ret_stringnl(krb5_storage *sp,
}
len++;
ret = size_too_large(sp, len);
if (ret)
break;
tmp = realloc (s, len);
if (tmp == NULL) {
free (s);
@@ -923,6 +967,11 @@ krb5_ret_principal(krb5_storage *sp,
free(p);
return EINVAL;
}
ret = size_too_large_num(sp, ncomp, sizeof(p->name.name_string.val[0]));
if (ret) {
free(p);
return ret;
}
p->name.name_type = type;
p->name.name_string.len = ncomp;
ret = krb5_ret_string(sp, &p->realm);
@@ -930,7 +979,7 @@ krb5_ret_principal(krb5_storage *sp,
free(p);
return ret;
}
p->name.name_string.val = calloc(ncomp, sizeof(*p->name.name_string.val));
p->name.name_string.val = calloc(ncomp, sizeof(p->name.name_string.val[0]));
if(p->name.name_string.val == NULL && ncomp != 0){
free(p->realm);
free(p);
@@ -1153,6 +1202,8 @@ krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
ret = krb5_ret_int32(sp, &tmp);
if(ret) return ret;
ret = size_too_large_num(sp, tmp, sizeof(adr->val[0]));
if (ret) return ret;
adr->len = tmp;
ALLOC(adr->val, adr->len);
if (adr->val == NULL && adr->len != 0)
@@ -1211,6 +1262,8 @@ krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
int i;
ret = krb5_ret_int32(sp, &tmp);
if(ret) return ret;
ret = size_too_large_num(sp, tmp, sizeof(auth->val[0]));
if (ret) return ret;
ALLOC_SEQ(auth, tmp);
if (auth->val == NULL && tmp != 0)
return ENOMEM;

View File

@@ -190,5 +190,6 @@ krb5_storage_emem(void)
sp->seek = emem_seek;
sp->trunc = emem_trunc;
sp->free = emem_free;
sp->max_alloc = UINT_MAX/8;
return sp;
}

View File

@@ -128,5 +128,6 @@ krb5_storage_from_fd(krb5_socket_t fd_in)
sp->seek = fd_seek;
sp->trunc = fd_trunc;
sp->free = fd_free;
sp->max_alloc = UINT_MAX/8;
return sp;
}

View File

@@ -145,6 +145,7 @@ krb5_storage_from_mem(void *buf, size_t len)
sp->seek = mem_seek;
sp->trunc = mem_trunc;
sp->free = NULL;
sp->max_alloc = UINT_MAX/8;
return sp;
}
@@ -203,5 +204,6 @@ krb5_storage_from_readonly_mem(const void *buf, size_t len)
sp->seek = mem_seek;
sp->trunc = mem_no_trunc;
sp->free = NULL;
sp->max_alloc = UINT_MAX/8;
return sp;
}

View File

@@ -193,8 +193,6 @@ test_storage(krb5_context context, krb5_storage *sp)
test_uint8(context, sp);
test_uint16(context, sp);
test_uint32(context, sp);
krb5_storage_free(sp);
}
@@ -217,10 +215,25 @@ test_truncate(krb5_context context, krb5_storage *sp, int fd)
krb5_err(context, 1, errno, "fstat");
if (sb.st_size != 1024)
krb5_errx(context, 1, "length not 2");
krb5_storage_free(sp);
}
static void
check_too_large(krb5_context context, krb5_storage *sp)
{
uint32_t too_big_sizes[] = { INT_MAX, INT_MAX / 2, INT_MAX / 4, INT_MAX / 8 + 1};
krb5_error_code ret;
krb5_data data;
size_t n;
for (n = 0; n < sizeof(too_big_sizes) / sizeof(too_big_sizes); n++) {
krb5_storage_truncate(sp, 0);
krb5_store_uint32(sp, too_big_sizes[n]);
krb5_storage_seek(sp, 0, SEEK_SET);
ret = krb5_ret_data(sp, &data);
if (ret != HEIM_ERR_TOO_BIG)
errx(1, "not too big: %lu", (unsigned long)n);
}
}
/*
*
@@ -284,10 +297,13 @@ main(int argc, char **argv)
krb5_errx(context, 1, "krb5_storage_emem: no mem");
test_storage(context, sp);
check_too_large(context, sp);
krb5_storage_free(sp);
fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0600);
if (fd < 0)
krb5_err(context, 1, errno, "open(%s", fn);
krb5_err(context, 1, errno, "open(%s)", fn);
sp = krb5_storage_from_fd(fd);
close(fd);
@@ -295,6 +311,7 @@ main(int argc, char **argv)
krb5_errx(context, 1, "krb5_storage_from_fd: %s no mem", fn);
test_storage(context, sp);
krb5_storage_free(sp);
unlink(fn);
/*
@@ -303,13 +320,14 @@ main(int argc, char **argv)
fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0600);
if (fd < 0)
krb5_err(context, 1, errno, "open(%s", fn);
krb5_err(context, 1, errno, "open(%s)", fn);
sp = krb5_storage_from_fd(fd);
if (sp == NULL)
krb5_errx(context, 1, "krb5_storage_from_fd: %s no mem", fn);
test_truncate(context, sp, fd);
krb5_storage_free(sp);
close(fd);
unlink(fn);

View File

@@ -606,6 +606,7 @@ HEIMDAL_KRB5_2.0 {
krb5_storage_set_byteorder;
krb5_storage_set_eof_code;
krb5_storage_set_flags;
krb5_storage_set_max_alloc;
krb5_storage_to_data;
krb5_storage_truncate;
krb5_storage_write;