->max_alloc to krb5_storage and use it
This commit is contained in:
@@ -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__ */
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user