->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*);
|
void (*free)(struct krb5_storage_data*);
|
||||||
krb5_flags flags;
|
krb5_flags flags;
|
||||||
int eof_code;
|
int eof_code;
|
||||||
|
size_t max_alloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __store_int_h__ */
|
#endif /* __store_int_h__ */
|
||||||
|
@@ -119,6 +119,41 @@ krb5_storage_get_byteorder(krb5_storage *sp)
|
|||||||
return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
|
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.
|
* Seek to a new offset.
|
||||||
*
|
*
|
||||||
@@ -263,9 +298,9 @@ krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
|
|||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
return HEIM_ERR_NOT_SEEKABLE;
|
return HEIM_ERR_NOT_SEEKABLE;
|
||||||
size = sp->seek(sp, 0, SEEK_END);
|
size = sp->seek(sp, 0, SEEK_END);
|
||||||
/* don't allocate unresonable amount of memory */
|
ret = size_too_large(sp, size);
|
||||||
if (size > UINT_MAX/8)
|
if (ret)
|
||||||
return HEIM_ERR_TOO_BIG;
|
return ret;
|
||||||
ret = krb5_data_alloc(data, size);
|
ret = krb5_data_alloc(data, size);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
sp->seek(sp, pos, SEEK_SET);
|
sp->seek(sp, pos, SEEK_SET);
|
||||||
@@ -645,6 +680,9 @@ krb5_ret_data(krb5_storage *sp,
|
|||||||
ret = krb5_ret_int32(sp, &size);
|
ret = krb5_ret_int32(sp, &size);
|
||||||
if(ret)
|
if(ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
ret = size_too_large(sp, size);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
ret = krb5_data_alloc (data, size);
|
ret = krb5_data_alloc (data, size);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -757,6 +795,9 @@ krb5_ret_stringz(krb5_storage *sp,
|
|||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
len++;
|
len++;
|
||||||
|
ret = size_too_large(sp, len);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
tmp = realloc (s, len);
|
tmp = realloc (s, len);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
free (s);
|
free (s);
|
||||||
@@ -823,6 +864,9 @@ krb5_ret_stringnl(krb5_storage *sp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
len++;
|
len++;
|
||||||
|
ret = size_too_large(sp, len);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
tmp = realloc (s, len);
|
tmp = realloc (s, len);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
free (s);
|
free (s);
|
||||||
@@ -923,6 +967,11 @@ krb5_ret_principal(krb5_storage *sp,
|
|||||||
free(p);
|
free(p);
|
||||||
return EINVAL;
|
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_type = type;
|
||||||
p->name.name_string.len = ncomp;
|
p->name.name_string.len = ncomp;
|
||||||
ret = krb5_ret_string(sp, &p->realm);
|
ret = krb5_ret_string(sp, &p->realm);
|
||||||
@@ -930,7 +979,7 @@ krb5_ret_principal(krb5_storage *sp,
|
|||||||
free(p);
|
free(p);
|
||||||
return ret;
|
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){
|
if(p->name.name_string.val == NULL && ncomp != 0){
|
||||||
free(p->realm);
|
free(p->realm);
|
||||||
free(p);
|
free(p);
|
||||||
@@ -1153,6 +1202,8 @@ krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
|
|||||||
|
|
||||||
ret = krb5_ret_int32(sp, &tmp);
|
ret = krb5_ret_int32(sp, &tmp);
|
||||||
if(ret) return ret;
|
if(ret) return ret;
|
||||||
|
ret = size_too_large_num(sp, tmp, sizeof(adr->val[0]));
|
||||||
|
if (ret) return ret;
|
||||||
adr->len = tmp;
|
adr->len = tmp;
|
||||||
ALLOC(adr->val, adr->len);
|
ALLOC(adr->val, adr->len);
|
||||||
if (adr->val == NULL && adr->len != 0)
|
if (adr->val == NULL && adr->len != 0)
|
||||||
@@ -1211,6 +1262,8 @@ krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
|
|||||||
int i;
|
int i;
|
||||||
ret = krb5_ret_int32(sp, &tmp);
|
ret = krb5_ret_int32(sp, &tmp);
|
||||||
if(ret) return ret;
|
if(ret) return ret;
|
||||||
|
ret = size_too_large_num(sp, tmp, sizeof(auth->val[0]));
|
||||||
|
if (ret) return ret;
|
||||||
ALLOC_SEQ(auth, tmp);
|
ALLOC_SEQ(auth, tmp);
|
||||||
if (auth->val == NULL && tmp != 0)
|
if (auth->val == NULL && tmp != 0)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
@@ -190,5 +190,6 @@ krb5_storage_emem(void)
|
|||||||
sp->seek = emem_seek;
|
sp->seek = emem_seek;
|
||||||
sp->trunc = emem_trunc;
|
sp->trunc = emem_trunc;
|
||||||
sp->free = emem_free;
|
sp->free = emem_free;
|
||||||
|
sp->max_alloc = UINT_MAX/8;
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
@@ -128,5 +128,6 @@ krb5_storage_from_fd(krb5_socket_t fd_in)
|
|||||||
sp->seek = fd_seek;
|
sp->seek = fd_seek;
|
||||||
sp->trunc = fd_trunc;
|
sp->trunc = fd_trunc;
|
||||||
sp->free = fd_free;
|
sp->free = fd_free;
|
||||||
|
sp->max_alloc = UINT_MAX/8;
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
@@ -145,6 +145,7 @@ krb5_storage_from_mem(void *buf, size_t len)
|
|||||||
sp->seek = mem_seek;
|
sp->seek = mem_seek;
|
||||||
sp->trunc = mem_trunc;
|
sp->trunc = mem_trunc;
|
||||||
sp->free = NULL;
|
sp->free = NULL;
|
||||||
|
sp->max_alloc = UINT_MAX/8;
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,5 +204,6 @@ krb5_storage_from_readonly_mem(const void *buf, size_t len)
|
|||||||
sp->seek = mem_seek;
|
sp->seek = mem_seek;
|
||||||
sp->trunc = mem_no_trunc;
|
sp->trunc = mem_no_trunc;
|
||||||
sp->free = NULL;
|
sp->free = NULL;
|
||||||
|
sp->max_alloc = UINT_MAX/8;
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
@@ -193,8 +193,6 @@ test_storage(krb5_context context, krb5_storage *sp)
|
|||||||
test_uint8(context, sp);
|
test_uint8(context, sp);
|
||||||
test_uint16(context, sp);
|
test_uint16(context, sp);
|
||||||
test_uint32(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");
|
krb5_err(context, 1, errno, "fstat");
|
||||||
if (sb.st_size != 1024)
|
if (sb.st_size != 1024)
|
||||||
krb5_errx(context, 1, "length not 2");
|
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");
|
krb5_errx(context, 1, "krb5_storage_emem: no mem");
|
||||||
|
|
||||||
test_storage(context, sp);
|
test_storage(context, sp);
|
||||||
|
check_too_large(context, sp);
|
||||||
|
krb5_storage_free(sp);
|
||||||
|
|
||||||
|
|
||||||
fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0600);
|
fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0600);
|
||||||
if (fd < 0)
|
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);
|
sp = krb5_storage_from_fd(fd);
|
||||||
close(fd);
|
close(fd);
|
||||||
@@ -295,6 +311,7 @@ main(int argc, char **argv)
|
|||||||
krb5_errx(context, 1, "krb5_storage_from_fd: %s no mem", fn);
|
krb5_errx(context, 1, "krb5_storage_from_fd: %s no mem", fn);
|
||||||
|
|
||||||
test_storage(context, sp);
|
test_storage(context, sp);
|
||||||
|
krb5_storage_free(sp);
|
||||||
unlink(fn);
|
unlink(fn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -303,13 +320,14 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0600);
|
fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0600);
|
||||||
if (fd < 0)
|
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);
|
sp = krb5_storage_from_fd(fd);
|
||||||
if (sp == NULL)
|
if (sp == NULL)
|
||||||
krb5_errx(context, 1, "krb5_storage_from_fd: %s no mem", fn);
|
krb5_errx(context, 1, "krb5_storage_from_fd: %s no mem", fn);
|
||||||
|
|
||||||
test_truncate(context, sp, fd);
|
test_truncate(context, sp, fd);
|
||||||
|
krb5_storage_free(sp);
|
||||||
close(fd);
|
close(fd);
|
||||||
unlink(fn);
|
unlink(fn);
|
||||||
|
|
||||||
|
@@ -606,6 +606,7 @@ HEIMDAL_KRB5_2.0 {
|
|||||||
krb5_storage_set_byteorder;
|
krb5_storage_set_byteorder;
|
||||||
krb5_storage_set_eof_code;
|
krb5_storage_set_eof_code;
|
||||||
krb5_storage_set_flags;
|
krb5_storage_set_flags;
|
||||||
|
krb5_storage_set_max_alloc;
|
||||||
krb5_storage_to_data;
|
krb5_storage_to_data;
|
||||||
krb5_storage_truncate;
|
krb5_storage_truncate;
|
||||||
krb5_storage_write;
|
krb5_storage_write;
|
||||||
|
Reference in New Issue
Block a user