There are other concerns. Let me see if I understand this. A thread (other than the leader) can exec and we then need to change the real_timer to wake the new task which will NOT be using the same task struct.
That's correct. de_thread will turn the thread calling exec into the new
leader and kill off all the other threads, including the old leader. The
exec'ing thread's existing task_struct is reassigned to the PID of the
original leader.
My looking at the code shows that the thread leader can exit and then stays around as a zombi until the last thread in the group exits.
That is correct.
If an alarm comes during this wait I suspect it will wake this zombi and
cause problems.
You are mistaken. The signal code handles process signals sent when the
leader is a zombie. The group leader sticks around with the PID that
matches the TGID, until there are no live threads with its TGID. That is
how process-wide kill can still work.