forked from mirrors/linux
		
	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); | 		DEFINE_WAIT(w); | ||||||
| 		for (;;) { | 		for (;;) { | ||||||
| 			flush_signals(current); | 			sigset_t full, old; | ||||||
| 			prepare_to_wait(&conf->wait_barrier, | 			prepare_to_wait(&conf->wait_barrier, | ||||||
| 					&w, TASK_INTERRUPTIBLE); | 					&w, TASK_INTERRUPTIBLE); | ||||||
| 			if (bio_end_sector(bio) <= mddev->suspend_lo || | 			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->bi_iter.bi_sector, | ||||||
| 				     bio_end_sector(bio)))) | 				     bio_end_sector(bio)))) | ||||||
| 				break; | 				break; | ||||||
|  | 			sigfillset(&full); | ||||||
|  | 			sigprocmask(SIG_BLOCK, &full, &old); | ||||||
| 			schedule(); | 			schedule(); | ||||||
|  | 			sigprocmask(SIG_SETMASK, &old, NULL); | ||||||
| 		} | 		} | ||||||
| 		finish_wait(&conf->wait_barrier, &w); | 		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 | 				 * userspace, we want an interruptible | ||||||
| 				 * wait. | 				 * wait. | ||||||
| 				 */ | 				 */ | ||||||
| 				flush_signals(current); |  | ||||||
| 				prepare_to_wait(&conf->wait_for_overlap, | 				prepare_to_wait(&conf->wait_for_overlap, | ||||||
| 						&w, TASK_INTERRUPTIBLE); | 						&w, TASK_INTERRUPTIBLE); | ||||||
| 				if (logical_sector >= mddev->suspend_lo && | 				if (logical_sector >= mddev->suspend_lo && | ||||||
| 				    logical_sector < mddev->suspend_hi) { | 				    logical_sector < mddev->suspend_hi) { | ||||||
|  | 					sigset_t full, old; | ||||||
|  | 					sigfillset(&full); | ||||||
|  | 					sigprocmask(SIG_BLOCK, &full, &old); | ||||||
| 					schedule(); | 					schedule(); | ||||||
|  | 					sigprocmask(SIG_SETMASK, &old, NULL); | ||||||
| 					do_prepare = true; | 					do_prepare = true; | ||||||
| 				} | 				} | ||||||
| 				goto retry; | 				goto retry; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Mikulas Patocka
						Mikulas Patocka