ps/display.c: Harden show_tree().
1/ Do not go deeper than the size of forest_prefix[], to prevent a buffer overflow (sizeof(forest_prefix) is roughly 128K, but the maximum /proc/sys/kernel/pid_max is 4M). (actually, we go deeper, but we stop adding bytes to forest_prefix[]) 2/ Always null-terminate forest_prefix[] at the current level.
This commit is contained in:
		
							
								
								
									
										18
									
								
								ps/display.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								ps/display.c
									
									
									
									
									
								
							| @@ -468,14 +468,22 @@ static void show_proc_array(PROCTAB *restrict ptp, int n){ | |||||||
| /***** show tree */ | /***** show tree */ | ||||||
| /* this needs some optimization work */ | /* this needs some optimization work */ | ||||||
| #define ADOPTED(x) 1 | #define ADOPTED(x) 1 | ||||||
|  |  | ||||||
|  | #define IS_LEVEL_SAFE(level) \ | ||||||
|  |   ((level) >= 0 && (size_t)(level) < sizeof(forest_prefix)) | ||||||
|  |  | ||||||
| static void show_tree(const int self, const int n, const int level, const int have_sibling){ | static void show_tree(const int self, const int n, const int level, const int have_sibling){ | ||||||
|   int i = 0; |   int i = 0; | ||||||
|  |  | ||||||
|  |   if(!IS_LEVEL_SAFE(level)) | ||||||
|  |     catastrophic_failure(__FILE__, __LINE__, _("please report this bug")); | ||||||
|  |  | ||||||
|   if(level){ |   if(level){ | ||||||
|     /* add prefix of "+" or "L" */ |     /* add prefix of "+" or "L" */ | ||||||
|     if(have_sibling) forest_prefix[level-1] = '+'; |     if(have_sibling) forest_prefix[level-1] = '+'; | ||||||
|     else             forest_prefix[level-1] = 'L'; |     else             forest_prefix[level-1] = 'L'; | ||||||
|     forest_prefix[level] = '\0'; |  | ||||||
|   } |   } | ||||||
|  |   forest_prefix[level] = '\0'; | ||||||
|   show_one_proc(processes[self],format_list);  /* first show self */ |   show_one_proc(processes[self],format_list);  /* first show self */ | ||||||
|   for(;;){  /* look for children */ |   for(;;){  /* look for children */ | ||||||
|     if(i >= n) return; /* no children */ |     if(i >= n) return; /* no children */ | ||||||
| @@ -486,8 +494,8 @@ static void show_tree(const int self, const int n, const int level, const int ha | |||||||
|     /* change our prefix to "|" or " " for the children */ |     /* change our prefix to "|" or " " for the children */ | ||||||
|     if(have_sibling) forest_prefix[level-1] = '|'; |     if(have_sibling) forest_prefix[level-1] = '|'; | ||||||
|     else             forest_prefix[level-1] = ' '; |     else             forest_prefix[level-1] = ' '; | ||||||
|     forest_prefix[level] = '\0'; |  | ||||||
|   } |   } | ||||||
|  |   forest_prefix[level] = '\0'; | ||||||
|   for(;;){ |   for(;;){ | ||||||
|     int self_pid; |     int self_pid; | ||||||
|     int more_children = 1; |     int more_children = 1; | ||||||
| @@ -500,14 +508,16 @@ static void show_tree(const int self, const int n, const int level, const int ha | |||||||
|     if(self_pid==1 && ADOPTED(processes[i]) && forest_type!='u') |     if(self_pid==1 && ADOPTED(processes[i]) && forest_type!='u') | ||||||
|       show_tree(i++, n, level, more_children); |       show_tree(i++, n, level, more_children); | ||||||
|     else |     else | ||||||
|       show_tree(i++, n, level+1, more_children); |       show_tree(i++, n, IS_LEVEL_SAFE(level+1) ? level+1 : level, more_children); | ||||||
|     if(!more_children) break; |     if(!more_children) break; | ||||||
|   } |   } | ||||||
|   /* chop prefix that children added -- do we need this? */ |   /* chop prefix that children added */ | ||||||
|   forest_prefix[level] = '\0'; |   forest_prefix[level] = '\0'; | ||||||
| //  memset(processes[self], '$', sizeof(proc_t));  /* debug */ | //  memset(processes[self], '$', sizeof(proc_t));  /* debug */ | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #undef IS_LEVEL_SAFE | ||||||
|  |  | ||||||
| /***** show forest */ | /***** show forest */ | ||||||
| static void show_forest(const int n){ | static void show_forest(const int n){ | ||||||
|   int i = n; |   int i = n; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user