Fix: lttng: add-trigger: invalid access past end of exclusions buffer
[lttng-tools.git] / src / common / index-allocator.c
1 /*
2 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #include <assert.h>
9 #include <inttypes.h>
10
11 #include <urcu.h>
12 #include <urcu/list.h>
13
14 #include "macros.h"
15 #include "error.h"
16
17 #include "index-allocator.h"
18
19 struct lttng_index_allocator {
20 struct cds_list_head unused_list;
21 uint64_t size;
22 uint64_t position;
23 uint64_t nb_allocated_indexes;
24 };
25
26 struct lttng_index {
27 uint64_t index;
28 struct cds_list_head head;
29 };
30
31 struct lttng_index_allocator *lttng_index_allocator_create(
32 uint64_t index_count)
33 {
34 struct lttng_index_allocator *allocator = NULL;
35
36 allocator = zmalloc(sizeof(*allocator));
37 if (!allocator) {
38 PERROR("Failed to allocate index allocator");
39 goto end;
40 }
41
42 allocator->size = index_count;
43 allocator->position = 0;
44 allocator->nb_allocated_indexes = 0;
45
46 CDS_INIT_LIST_HEAD(&allocator->unused_list);
47
48 end:
49 return allocator;
50 }
51
52 uint64_t lttng_index_allocator_get_index_count(struct lttng_index_allocator *allocator)
53 {
54 return allocator->nb_allocated_indexes;
55 }
56
57 enum lttng_index_allocator_status lttng_index_allocator_alloc(
58 struct lttng_index_allocator *allocator,
59 uint64_t *allocated_index)
60 {
61 enum lttng_index_allocator_status status =
62 LTTNG_INDEX_ALLOCATOR_STATUS_OK;
63
64 if (cds_list_empty(&allocator->unused_list)) {
65 if (allocator->position >= allocator->size) {
66 /* No indices left. */
67 status = LTTNG_INDEX_ALLOCATOR_STATUS_EMPTY;
68 goto end;
69 }
70
71 *allocated_index = allocator->position++;
72 } else {
73 struct lttng_index *index;
74
75 index = cds_list_first_entry(&allocator->unused_list,
76 typeof(*index), head);
77 cds_list_del(&index->head);
78 *allocated_index = index->index;
79 free(index);
80 }
81
82 allocator->nb_allocated_indexes++;
83 end:
84 return status;
85 }
86
87 enum lttng_index_allocator_status lttng_index_allocator_release(
88 struct lttng_index_allocator *allocator, uint64_t idx)
89 {
90 struct lttng_index *index = NULL;
91 enum lttng_index_allocator_status status =
92 LTTNG_INDEX_ALLOCATOR_STATUS_OK;
93
94 assert(idx < allocator->size);
95
96 index = zmalloc(sizeof(*index));
97 if (!index) {
98 PERROR("Failed to allocate free index queue");
99 status = LTTNG_INDEX_ALLOCATOR_STATUS_ERROR;
100 goto end;
101 }
102
103 index->index = idx;
104 cds_list_add_tail(&index->head, &allocator->unused_list);
105 allocator->nb_allocated_indexes--;
106
107 end:
108 return status;
109 }
110
111 void lttng_index_allocator_destroy(struct lttng_index_allocator *allocator)
112 {
113 struct lttng_index *index = NULL, *tmp_index = NULL;
114
115 if (!allocator) {
116 return;
117 }
118
119 if (lttng_index_allocator_get_index_count(allocator) > 0) {
120 WARN("Destroying index allocator with %" PRIu64
121 " slot indexes still in use",
122 lttng_index_allocator_get_index_count(allocator));
123 }
124
125 cds_list_for_each_entry_safe(index, tmp_index,
126 &allocator->unused_list, head) {
127 cds_list_del(&index->head);
128 free(index);
129 }
130
131 free(allocator);
132 }
This page took 0.03227 seconds and 4 git commands to generate.