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

This reverts commit 8ad6679a5b which is
commit 8ce8849dd1e78dadcee0ec9acbd259d239b7069f upstream.

It breaks the Android abi.  If it is required in the future, it can come
back in an abi-safe way.

Bug: 161946584
Change-Id: I44be0f7b4df730e599bf80939b6d40d4f8d04a57
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2023-08-04 07:11:13 +00:00
parent f829d76234
commit 7233414aeb
2 changed files with 14 additions and 19 deletions

View File

@ -124,7 +124,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

@ -138,30 +138,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)