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

This reverts commit 6a0ac84501 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: Ie271fbc9312fe3c85aa472ecad68db55985fd96c
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2024-10-01 12:57:11 +00:00
parent 3e3e85a2c0
commit db06d215a8
2 changed files with 14 additions and 19 deletions

View File

@@ -136,7 +136,7 @@ struct signal_struct {
#ifdef CONFIG_POSIX_TIMERS #ifdef CONFIG_POSIX_TIMERS
/* POSIX.1b Interval Timers */ /* POSIX.1b Interval Timers */
unsigned int next_posix_timer_id; int posix_timer_id;
struct list_head posix_timers; struct list_head posix_timers;
/* ITIMER_REAL timer for the process */ /* 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) static int posix_timer_add(struct k_itimer *timer)
{ {
struct signal_struct *sig = current->signal; struct signal_struct *sig = current->signal;
int first_free_id = sig->posix_timer_id;
struct hlist_head *head; struct hlist_head *head;
unsigned int cnt, id; int ret = -ENOENT;
/* do {
* 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++) {
spin_lock(&hash_lock); spin_lock(&hash_lock);
id = sig->next_posix_timer_id; head = &posix_timers_hashtable[hash(sig, sig->posix_timer_id)];
if (!__posix_timers_find(head, sig, sig->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)) {
hlist_add_head_rcu(&timer->t_hash, head); hlist_add_head_rcu(&timer->t_hash, head);
spin_unlock(&hash_lock); ret = sig->posix_timer_id;
return 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); spin_unlock(&hash_lock);
} } while (ret == -ENOENT);
/* POSIX return code when no timer ID could be allocated */ return ret;
return -EAGAIN;
} }
static inline void unlock_timer(struct k_itimer *timr, unsigned long flags) static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)