Q: Given the following code slice:
```
1 static void
2 ble_hs_timer_sched(int32_t ticks_from_now)
3 {
4     ble_npl_time_t abs_time;
5 
6     if (ticks_from_now == BLE_HS_FOREVER) {
7         return;
8     }
9 
10     /* Reset timer if it is not currently scheduled or if the specified time is
11      * sooner than the previous expiration time.
12      */
13     abs_time = ble_npl_time_get() + ticks_from_now;
14     if (!ble_npl_callout_is_active(&ble_hs_timer) ||
15             ((ble_npl_stime_t)(abs_time -
16                                ble_npl_callout_get_ticks(&ble_hs_timer))) < 0) {
17         ble_hs_timer_reset(ticks_from_now);
18     }
19 }
20 int
21 ble_hs_is_enabled(void)
22 {
23     return ble_hs_enabled_state == BLE_HS_ENABLED_STATE_ON;
24 }
25 static int32_t
26 ble_gattc_extract_expired(struct ble_gattc_proc_list *dst_list)
27 {
28     struct ble_gattc_criteria_exp criteria;
29 
30     criteria.now = ble_npl_time_get();
31     criteria.next_exp_in = BLE_HS_FOREVER;
32 
33     STAILQ_INIT(dst_list);
34     ble_gattc_extract(ble_gattc_proc_matches_expired, &criteria, 0, dst_list);
35 
36     return criteria.next_exp_in;
37 }
38 static void
39 ble_gattc_extract(ble_gattc_match_fn *cb, void *arg, int max_procs,
40                   struct ble_gattc_proc_list *dst_list)
41 {
42     struct ble_gattc_proc *proc;
43     struct ble_gattc_proc *prev;
44     struct ble_gattc_proc *next;
45     int num_extracted;
46 
47     /* Only the parent task is allowed to remove entries from the list. */
48     BLE_HS_DBG_ASSERT(ble_hs_is_parent_task());
49 
50     STAILQ_INIT(dst_list);
51     num_extracted = 0;
52 
53     ble_hs_lock();
54 
55     prev = NULL;
56     proc = STAILQ_FIRST(&ble_gattc_procs);
57     while (proc != NULL) {
58         next = STAILQ_NEXT(proc, next);
59 
60         if (cb(proc, arg)) {
61             if (prev == NULL) {
62                 STAILQ_REMOVE_HEAD(&ble_gattc_procs, next);
63             } else {
64                 STAILQ_REMOVE_AFTER(&ble_gattc_procs, prev, next);
65             }
66             STAILQ_INSERT_TAIL(dst_list, proc, next);
67 
68             if (max_procs > 0) {
69                 num_extracted++;
70                 if (num_extracted >= max_procs) {
71                     break;
72                 }
73             }
74         } else {
75             prev = proc;
76         }
77 
78         proc = next;
79     }
80 
81     ble_hs_unlock();
82 }
83 static void
84 ble_gattc_proc_timeout(struct ble_gattc_proc *proc)
85 {
86     ble_gattc_tmo_fn *cb;
87 
88     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
89     ble_gattc_dbg_assert_proc_not_inserted(proc);
90 
91     cb = ble_gattc_tmo_dispatch_get(proc->op);
92     if (cb != NULL) {
93         cb(proc);
94     }
95 }
96 static void
97 ble_gattc_process_status(struct ble_gattc_proc *proc, int status)
98 {
99     switch (status) {
100     case 0:
101         if (!(proc->flags & BLE_GATTC_PROC_F_STALLED)) {
102             ble_gattc_proc_set_exp_timer(proc);
103         }
104 
105         ble_gattc_proc_insert(proc);
106         ble_hs_timer_resched();
107         break;
108 
109     default:
110         ble_gattc_proc_free(proc);
111         break;
112     }
113 }
114 static void
115 ble_gattc_extract_stalled(struct ble_gattc_proc_list *dst_list)
116 {
117     ble_gattc_extract(ble_gattc_proc_matches_stalled, NULL, 0, dst_list);
118 }
119 static inline uint32_t
120 ble_npl_time_get(void)
121 {
122     return os_time_get();
123 }
124 static void
125 ble_hs_timer_sched(int32_t ticks_from_now)
126 {
127     ble_npl_time_t abs_time;
128 
129     if (ticks_from_now == BLE_HS_FOREVER) {
130         return;
131     }
132 
133     /* Reset timer if it is not currently scheduled or if the specified time is
134      * sooner than the previous expiration time.
135      */
136     abs_time = ble_npl_time_get() + ticks_from_now;
137     if (!ble_npl_callout_is_active(&ble_hs_timer) ||
138             ((ble_npl_stime_t)(abs_time -
139                                ble_npl_callout_get_ticks(&ble_hs_timer))) < 0) {
140         ble_hs_timer_reset(ticks_from_now);
141     }
142 }
143 static ble_gattc_resume_fn *
144 ble_gattc_resume_dispatch_get(uint8_t op)
145 {
146     BLE_HS_DBG_ASSERT(op < BLE_GATT_OP_CNT);
147     return ble_gattc_resume_dispatch[op];
148 }
149 static ble_gattc_tmo_fn *
150 ble_gattc_tmo_dispatch_get(uint8_t op)
151 {
152     BLE_HS_DBG_ASSERT(op < BLE_GATT_OP_CNT);
153     return ble_gattc_tmo_dispatch[op];
154 }
155 static int32_t
156 ble_gattc_ticks_until_resume(void)
157 {
158     ble_npl_time_t now;
159     int32_t diff;
160 
161     /* Resume timer not set. */
162     if (ble_gattc_resume_at == 0) {
163         return BLE_HS_FOREVER;
164     }
165 
166     now = ble_npl_time_get();
167     diff = ble_gattc_resume_at - now;
168     if (diff <= 0) {
169         /* Timer already expired; resume immediately. */
170         return 0;
171     }
172 
173     return diff;
174 }
175 int32_t ble_hs_conn_timer(void)
176 {
177 
178     struct ble_hs_conn *conn;
179     ble_npl_time_t now = ble_npl_time_get();
180     int32_t next_exp_in = BLE_HS_FOREVER;
181     int32_t next_exp_in_new;
182     bool next_exp_in_updated;
183     int32_t time_diff;
184 
185     ble_hs_lock();
186 
187     /* This loop performs one of two tasks:
188      * 1. Determine if any connections need to be terminated due to timeout. If
189      *    so connection is disconnected.
190      * 2. Otherwise, determine when the next timeout will occur.
191      */
192     SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
193         if (!(conn->bhc_flags & BLE_HS_CONN_F_TERMINATING)) {
194             next_exp_in_updated = false;
195 
196             /* Check each connection's rx fragment timer.  If too much time
197              * passes after a partial packet is received, the connection is
198              * terminated.
199              */
200             if (conn->bhc_rx_chan != NULL) {
201                 time_diff = conn->bhc_rx_timeout - now;
202 
203                 /* Determine if this connection is the soonest to time out. */
204                 if (time_diff < next_exp_in) {
205                     next_exp_in_new = time_diff;
206                     next_exp_in_updated = true;
207                 }
208             }
209             if (next_exp_in_updated) {
210                 next_exp_in = next_exp_in_new;
211             }
212         }
213     }
214 
215     ble_hs_unlock();
216 
217     return next_exp_in;
218 }
219 static inline bool
220 ble_npl_callout_is_active(struct ble_npl_callout *co)
221 {
222     return os_callout_queued(&co->co);
223 }
224 static void
225 ble_hs_timer_exp(struct ble_npl_event *ev)
226 {
227     int32_t ticks_until_next;
228 
229     switch (ble_hs_sync_state) {
230     case BLE_HS_SYNC_STATE_GOOD:
231 #if NIMBLE_BLE_CONNECT
232         ticks_until_next = ble_gattc_timer();
233         ble_hs_timer_sched(ticks_until_next);
234 
235         ticks_until_next = ble_l2cap_sig_timer();
236         ble_hs_timer_sched(ticks_until_next);
237 
238         ticks_until_next = ble_sm_timer();
239         ble_hs_timer_sched(ticks_until_next);
240 
241         ticks_until_next = ble_hs_conn_timer();
242         ble_hs_timer_sched(ticks_until_next);
243 #endif
244 
245         ticks_until_next = ble_gap_timer();
246         ble_hs_timer_sched(ticks_until_next);
247 
248         break;
249 
250     case BLE_HS_SYNC_STATE_BAD:
251         ble_hs_reset();
252         break;
253 
254     case BLE_HS_SYNC_STATE_BRINGUP:
255     default:
256         /* The timer should not be set in this state. */
257         assert(0);
258         break;
259     }
260 
261 }
262 static inline void
263 ble_npl_callout_stop(struct ble_npl_callout *co)
264 {
265     os_callout_stop(&co->co);
266 }
267 static void
268 ble_gattc_resume_procs(void)
269 {
270     struct ble_gattc_proc_list stall_list;
271     struct ble_gattc_proc *proc;
272     ble_gattc_resume_fn *resume_cb;
273     int rc;
274 
275     /* Cancel resume timer since it is being serviced. */
276     ble_gattc_resume_at = 0;
277 
278     ble_gattc_extract_stalled(&stall_list);
279 
280     STAILQ_FOREACH(proc, &stall_list, next) {
281         resume_cb = ble_gattc_resume_dispatch_get(proc->op);
282         BLE_HS_DBG_ASSERT(resume_cb != NULL);
283 
284         proc->flags &= ~BLE_GATTC_PROC_F_STALLED;
285         rc = resume_cb(proc);
286         ble_gattc_process_status(proc, rc);
287     }
288 }
289 static inline ble_npl_error_t
290 ble_npl_callout_reset(struct ble_npl_callout *co, ble_npl_time_t ticks)
291 {
292     return (ble_npl_error_t)os_callout_reset(&co->co, ticks);
293 }
294 static void
295 ble_hs_timer_reset(uint32_t ticks)
296 {
297     int rc;
298 
299     if (!ble_hs_is_enabled()) {
300         ble_npl_callout_stop(&ble_hs_timer);
301     } else {
302         rc = ble_npl_callout_reset(&ble_hs_timer, ticks);
303         BLE_HS_DBG_ASSERT_EVAL(rc == 0);
304     }
305 }
306 static inline ble_npl_time_t
307 ble_npl_callout_get_ticks(struct ble_npl_callout *co)
308 {
309     return co->co.c_ticks;
310 }
311 int32_t
312 ble_gattc_timer(void)
313 {
314     struct ble_gattc_proc_list exp_list;
315     struct ble_gattc_proc *proc;
316     int32_t ticks_until_resume;
317     int32_t ticks_until_exp;
318 
319     /* Remove timed-out procedures from the main list and insert them into a
320      * temporary list.  This function also calculates the number of ticks until
321      * the next expiration will occur.
322      */
323     ticks_until_exp = ble_gattc_extract_expired(&exp_list);
324 
325     /* Terminate the connection associated with each timed-out procedure. */
326     while ((proc = STAILQ_FIRST(&exp_list)) != NULL) {
327         STATS_INC(ble_gattc_stats, proc_timeout);
328 
329         ble_gattc_proc_timeout(proc);
330 
331         ble_gap_terminate(proc->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
332 
333         STAILQ_REMOVE_HEAD(&exp_list, next);
334         ble_gattc_proc_free(proc);
335     }
336 
337     /* If there are stalled procedures, the GATT client will need to wake up to
338      * resume them.
339      */
340     ticks_until_resume = ble_gattc_ticks_until_resume();
341     if (ticks_until_resume == 0) {
342         ble_gattc_resume_procs();
343         ticks_until_resume = ble_gattc_ticks_until_resume();
344     }
345 
346     return min(ticks_until_exp, ticks_until_resume);
347 }
```
which has a vulnerability among CWE-476 and among lines:
```
13     abs_time = ble_npl_time_get() + ticks_from_now;
```
Please generate five possible patches for the vulnerability.