call_usermodehelper(): increase reliability
Presently call_usermodehelper_setup() uses GFP_ATOMIC. but it can return NULL _very_ easily. GFP_ATOMIC is needed only when we can't sleep. and, GFP_KERNEL is robust and better. thus, I add gfp_mask argument to call_usermodehelper_setup(). So, its callers pass the gfp_t as below: call_usermodehelper() and call_usermodehelper_keys(): depend on 'wait' argument. call_usermodehelper_pipe(): always GFP_KERNEL because always run under process context. orderly_poweroff(): pass to GFP_ATOMIC because may run under interrupt context. Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: "Paul Menage" <menage@google.com> Reviewed-by: Li Zefan <lizf@cn.fujitsu.com> Acked-by: Jeremy Fitzhardinge <jeremy@xensource.com> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Andi Kleen <andi@firstfloor.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									f557d0996a
								
							
						
					
					
						commit
						ac331d158e
					
				| @ -19,6 +19,7 @@ | ||||
|  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/gfp.h> | ||||
| #include <linux/stddef.h> | ||||
| #include <linux/errno.h> | ||||
| #include <linux/compiler.h> | ||||
| @ -41,8 +42,8 @@ struct file; | ||||
| struct subprocess_info; | ||||
| 
 | ||||
| /* Allocate a subprocess_info structure */ | ||||
| struct subprocess_info *call_usermodehelper_setup(char *path, | ||||
| 						  char **argv, char **envp); | ||||
| struct subprocess_info *call_usermodehelper_setup(char *path, char **argv, | ||||
| 						  char **envp, gfp_t gfp_mask); | ||||
| 
 | ||||
| /* Set various pieces of state into the subprocess_info structure */ | ||||
| void call_usermodehelper_setkeys(struct subprocess_info *info, | ||||
| @ -69,8 +70,9 @@ static inline int | ||||
| call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait) | ||||
| { | ||||
| 	struct subprocess_info *info; | ||||
| 	gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL; | ||||
| 
 | ||||
| 	info = call_usermodehelper_setup(path, argv, envp); | ||||
| 	info = call_usermodehelper_setup(path, argv, envp, gfp_mask); | ||||
| 	if (info == NULL) | ||||
| 		return -ENOMEM; | ||||
| 	return call_usermodehelper_exec(info, wait); | ||||
| @ -81,8 +83,9 @@ call_usermodehelper_keys(char *path, char **argv, char **envp, | ||||
| 			 struct key *session_keyring, enum umh_wait wait) | ||||
| { | ||||
| 	struct subprocess_info *info; | ||||
| 	gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL; | ||||
| 
 | ||||
| 	info = call_usermodehelper_setup(path, argv, envp); | ||||
| 	info = call_usermodehelper_setup(path, argv, envp, gfp_mask); | ||||
| 	if (info == NULL) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
|  | ||||
| @ -352,16 +352,17 @@ static inline void register_pm_notifier_callback(void) {} | ||||
|  * @path: path to usermode executable | ||||
|  * @argv: arg vector for process | ||||
|  * @envp: environment for process | ||||
|  * @gfp_mask: gfp mask for memory allocation | ||||
|  * | ||||
|  * Returns either %NULL on allocation failure, or a subprocess_info | ||||
|  * structure.  This should be passed to call_usermodehelper_exec to | ||||
|  * exec the process and free the structure. | ||||
|  */ | ||||
| struct subprocess_info *call_usermodehelper_setup(char *path, | ||||
| 						  char **argv, char **envp) | ||||
| struct subprocess_info *call_usermodehelper_setup(char *path, char **argv, | ||||
| 						  char **envp, gfp_t gfp_mask) | ||||
| { | ||||
| 	struct subprocess_info *sub_info; | ||||
| 	sub_info = kzalloc(sizeof(struct subprocess_info),  GFP_ATOMIC); | ||||
| 	sub_info = kzalloc(sizeof(struct subprocess_info), gfp_mask); | ||||
| 	if (!sub_info) | ||||
| 		goto out; | ||||
| 
 | ||||
| @ -494,7 +495,7 @@ int call_usermodehelper_pipe(char *path, char **argv, char **envp, | ||||
| 	struct subprocess_info *sub_info; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	sub_info = call_usermodehelper_setup(path, argv, envp); | ||||
| 	sub_info = call_usermodehelper_setup(path, argv, envp, GFP_KERNEL); | ||||
| 	if (sub_info == NULL) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
|  | ||||
| @ -1795,7 +1795,7 @@ int orderly_poweroff(bool force) | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	info = call_usermodehelper_setup(argv[0], argv, envp); | ||||
| 	info = call_usermodehelper_setup(argv[0], argv, envp, GFP_ATOMIC); | ||||
| 	if (info == NULL) { | ||||
| 		argv_free(argv); | ||||
| 		goto out; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user