diff options
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 20 |
1 files changed, 17 insertions, 3 deletions
| @@ -642,6 +642,18 @@ static inline int de_thread(struct task_struct *tsk) | |||
| 642 | count = 2; | 642 | count = 2; |
| 643 | if (thread_group_leader(current)) | 643 | if (thread_group_leader(current)) |
| 644 | count = 1; | 644 | count = 1; |
| 645 | else { | ||
| 646 | /* | ||
| 647 | * The SIGALRM timer survives the exec, but needs to point | ||
| 648 | * at us as the new group leader now. We have a race with | ||
| 649 | * a timer firing now getting the old leader, so we need to | ||
| 650 | * synchronize with any firing (by calling del_timer_sync) | ||
| 651 | * before we can safely let the old group leader die. | ||
| 652 | */ | ||
| 653 | sig->real_timer.data = (unsigned long)current; | ||
| 654 | if (del_timer_sync(&sig->real_timer)) | ||
| 655 | add_timer(&sig->real_timer); | ||
| 656 | } | ||
| 645 | while (atomic_read(&sig->count) > count) { | 657 | while (atomic_read(&sig->count) > count) { |
| 646 | sig->group_exit_task = current; | 658 | sig->group_exit_task = current; |
| 647 | sig->notify_count = count; | 659 | sig->notify_count = count; |
| @@ -786,6 +798,7 @@ no_thread_group: | |||
| 786 | static inline void flush_old_files(struct files_struct * files) | 798 | static inline void flush_old_files(struct files_struct * files) |
| 787 | { | 799 | { |
| 788 | long j = -1; | 800 | long j = -1; |
| 801 | struct fdtable *fdt; | ||
| 789 | 802 | ||
| 790 | spin_lock(&files->file_lock); | 803 | spin_lock(&files->file_lock); |
| 791 | for (;;) { | 804 | for (;;) { |
| @@ -793,12 +806,13 @@ static inline void flush_old_files(struct files_struct * files) | |||
| 793 | 806 | ||
| 794 | j++; | 807 | j++; |
| 795 | i = j * __NFDBITS; | 808 | i = j * __NFDBITS; |
| 796 | if (i >= files->max_fds || i >= files->max_fdset) | 809 | fdt = files_fdtable(files); |
| 810 | if (i >= fdt->max_fds || i >= fdt->max_fdset) | ||
| 797 | break; | 811 | break; |
| 798 | set = files->close_on_exec->fds_bits[j]; | 812 | set = fdt->close_on_exec->fds_bits[j]; |
| 799 | if (!set) | 813 | if (!set) |
| 800 | continue; | 814 | continue; |
| 801 | files->close_on_exec->fds_bits[j] = 0; | 815 | fdt->close_on_exec->fds_bits[j] = 0; |
| 802 | spin_unlock(&files->file_lock); | 816 | spin_unlock(&files->file_lock); |
| 803 | for ( ; set ; i++,set >>= 1) { | 817 | for ( ; set ; i++,set >>= 1) { |
| 804 | if (set & 1) { | 818 | if (set & 1) { |
