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);
 | 
							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