mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	md: don't use flush_signals in userspace processes
The function flush_signals clears all pending signals for the process. It may be used by kernel threads when we need to prepare a kernel thread for responding to signals. However using this function for an userspaces processes is incorrect - clearing signals without the program expecting it can cause misbehavior. The raid1 and raid5 code uses flush_signals in its request routine because it wants to prepare for an interruptible wait. This patch drops flush_signals and uses sigprocmask instead to block all signals (including SIGKILL) around the schedule() call. The signals are not lost, but the schedule() call won't respond to them. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org Acked-by: NeilBrown <neilb@suse.com> Signed-off-by: Shaohua Li <shli@fb.com>
This commit is contained in:
		
							parent
							
								
									cc27b0c78c
								
							
						
					
					
						commit
						f9c79bc05a
					
				
					 2 changed files with 8 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -1334,7 +1334,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
 | 
			
		|||
		 */
 | 
			
		||||
		DEFINE_WAIT(w);
 | 
			
		||||
		for (;;) {
 | 
			
		||||
			flush_signals(current);
 | 
			
		||||
			sigset_t full, old;
 | 
			
		||||
			prepare_to_wait(&conf->wait_barrier,
 | 
			
		||||
					&w, TASK_INTERRUPTIBLE);
 | 
			
		||||
			if (bio_end_sector(bio) <= mddev->suspend_lo ||
 | 
			
		||||
| 
						 | 
				
			
			@ -1344,7 +1344,10 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
 | 
			
		|||
				     bio->bi_iter.bi_sector,
 | 
			
		||||
				     bio_end_sector(bio))))
 | 
			
		||||
				break;
 | 
			
		||||
			sigfillset(&full);
 | 
			
		||||
			sigprocmask(SIG_BLOCK, &full, &old);
 | 
			
		||||
			schedule();
 | 
			
		||||
			sigprocmask(SIG_SETMASK, &old, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		finish_wait(&conf->wait_barrier, &w);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5693,12 +5693,15 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
 | 
			
		|||
				 * userspace, we want an interruptible
 | 
			
		||||
				 * wait.
 | 
			
		||||
				 */
 | 
			
		||||
				flush_signals(current);
 | 
			
		||||
				prepare_to_wait(&conf->wait_for_overlap,
 | 
			
		||||
						&w, TASK_INTERRUPTIBLE);
 | 
			
		||||
				if (logical_sector >= mddev->suspend_lo &&
 | 
			
		||||
				    logical_sector < mddev->suspend_hi) {
 | 
			
		||||
					sigset_t full, old;
 | 
			
		||||
					sigfillset(&full);
 | 
			
		||||
					sigprocmask(SIG_BLOCK, &full, &old);
 | 
			
		||||
					schedule();
 | 
			
		||||
					sigprocmask(SIG_SETMASK, &old, NULL);
 | 
			
		||||
					do_prepare = true;
 | 
			
		||||
				}
 | 
			
		||||
				goto retry;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue