->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