Revert "posix-timers: Ensure timer ID search-loop limit is valid"

This reverts commit ef535e0315 which is
commit 8ce8849dd1 upstream.

It breaks the Android kernel abi and can be brought back in the future
in an abi-safe way if it is really needed.

Bug: 161946584
Change-Id: Icdf91cda9a996fef8c8f5413b1b406a5fa936afb
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2024-04-19 13:40:21 +00:00
parent 05c0bbb7b1
commit 792aa870d5
2 changed files with 14 additions and 19 deletions

View File

@@ -126,7 +126,7 @@ struct signal_struct {
#ifdef CONFIG_POSIX_TIMERS
/* POSIX.1b Interval Timers */
unsigned int next_posix_timer_id;
int posix_timer_id;
struct list_head posix_timers;
/* ITIMER_REAL timer for the process */

View File

@@ -140,30 +140,25 @@ static struct k_itimer *posix_timer_by_id(timer_t id)
static int posix_timer_add(struct k_itimer *timer)
{
struct signal_struct *sig = current->signal;
int first_free_id = sig->posix_timer_id;
struct hlist_head *head;
unsigned int cnt, id;
int ret = -ENOENT;
/*
* FIXME: Replace this by a per signal struct xarray once there is
* a plan to handle the resulting CRIU regression gracefully.
*/
for (cnt = 0; cnt <= INT_MAX; cnt++) {
do {
spin_lock(&hash_lock);
id = sig->next_posix_timer_id;
/* Write the next ID back. Clamp it to the positive space */
sig->next_posix_timer_id = (id + 1) & INT_MAX;
head = &posix_timers_hashtable[hash(sig, id)];
if (!__posix_timers_find(head, sig, id)) {
head = &posix_timers_hashtable[hash(sig, sig->posix_timer_id)];
if (!__posix_timers_find(head, sig, sig->posix_timer_id)) {
hlist_add_head_rcu(&timer->t_hash, head);
spin_unlock(&hash_lock);
return id;
ret = sig->posix_timer_id;
}
if (++sig->posix_timer_id < 0)
sig->posix_timer_id = 0;
if ((sig->posix_timer_id == first_free_id) && (ret == -ENOENT))
/* Loop over all possible ids completed */
ret = -EAGAIN;
spin_unlock(&hash_lock);
}
/* POSIX return code when no timer ID could be allocated */
return -EAGAIN;
} while (ret == -ENOENT);
return ret;
}
static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)