ソースを参照

Fix different kinds of issues with string buffers and pointers

- Use NAME_MAX and PATH_MAX instead of hardcoded values
- Allow paths to be longer than 256 chars
- Check pointers everywhere
- Use strncpy/snprintf instead of strcpy/sprintf
- Validate controllers' name (-s flag + a very long name -> bad things happening)
- Get rid of globals for dir iteration
Abdullah ibn Nadjo 6 年 前
コミット
f62503b299
共有2 個のファイルを変更した141 個の追加83 個の削除を含む
  1. 6
    10
      include/light.h
  2. 135
    73
      src/light.c

+ 6
- 10
include/light.h ファイルの表示

5
 
5
 
6
 #include <sys/types.h>
6
 #include <sys/types.h>
7
 #include <dirent.h>
7
 #include <dirent.h>
8
+#include <linux/limits.h>
8
 
9
 
9
 #define LIGHT_VER_MAJOR 0
10
 #define LIGHT_VER_MAJOR 0
10
 #define LIGHT_VER_MINOR 9
11
 #define LIGHT_VER_MINOR 9
64
 typedef struct light_runtimeArguments_s {
65
 typedef struct light_runtimeArguments_s {
65
   /* Which controller to use */
66
   /* Which controller to use */
66
   LIGHT_CTRL_MODE controllerMode;
67
   LIGHT_CTRL_MODE controllerMode;
67
-  char            specifiedController[256];
68
+  char            specifiedController[NAME_MAX + 1];
68
 
69
 
69
   /* What to do with the controller */
70
   /* What to do with the controller */
70
   LIGHT_OP_MODE   operationMode;
71
   LIGHT_OP_MODE   operationMode;
81
 
82
 
82
 } light_runtimeArguments, *light_runtimeArguments_p;
83
 } light_runtimeArguments, *light_runtimeArguments_p;
83
 
84
 
84
-/* -- Global variables that handles iterating controllers -- */
85
-struct dirent *light_iterator;
86
-DIR           *light_iteratorDir;
87
-char          light_currentController[256];
88
-
89
 /* -- Global variable holding the settings for the current run -- */
85
 /* -- Global variable holding the settings for the current run -- */
90
 light_runtimeArguments light_Configuration;
86
 light_runtimeArguments light_Configuration;
91
 
87
 
116
 /* SECTION: Controller functionality */
112
 /* SECTION: Controller functionality */
117
 
113
 
118
 /* WARNING: `buffer` HAS to be freed by the user if not null once returned!
114
 /* WARNING: `buffer` HAS to be freed by the user if not null once returned!
119
- * Size is always 256 */
115
+ * Size is always NAME_MAX + 1 */
120
 LIGHT_BOOL light_genPath(char const *controller, LIGHT_TARGET target, LIGHT_FIELD type, char **buffer);
116
 LIGHT_BOOL light_genPath(char const *controller, LIGHT_TARGET target, LIGHT_FIELD type, char **buffer);
121
 
117
 
118
+LIGHT_BOOL light_validControllerName(char const *controller);
119
+
122
 LIGHT_BOOL light_getBrightness(char const *controller, unsigned long *v);
120
 LIGHT_BOOL light_getBrightness(char const *controller, unsigned long *v);
123
 
121
 
124
 LIGHT_BOOL light_getMaxBrightness(char const *controller, unsigned long *v);
122
 LIGHT_BOOL light_getMaxBrightness(char const *controller, unsigned long *v);
127
 
125
 
128
 LIGHT_BOOL light_controllerAccessible(char const *controller);
126
 LIGHT_BOOL light_controllerAccessible(char const *controller);
129
 
127
 
130
-LIGHT_BOOL light_iterateControllers(void);
131
-
132
-/* WARNING: `controller` HAS to be at least 256 bytes */
128
+/* WARNING: `controller` HAS to be at most NAME_MAX, otherwise fails */
133
 LIGHT_BOOL light_getBestController(char *controller);
129
 LIGHT_BOOL light_getBestController(char *controller);
134
 
130
 
135
 LIGHT_BOOL light_getMinCap(char const *controller, LIGHT_BOOL *hasMinCap, unsigned long *minCap);
131
 LIGHT_BOOL light_getMinCap(char const *controller, LIGHT_BOOL *hasMinCap, unsigned long *minCap);

+ 135
- 73
src/light.c ファイルの表示

11
 void light_defaultConfig()
11
 void light_defaultConfig()
12
 {
12
 {
13
   light_Configuration.controllerMode         = LIGHT_AUTO;
13
   light_Configuration.controllerMode         = LIGHT_AUTO;
14
-  memset(&light_Configuration.specifiedController, '\0', 256);
14
+  memset(&light_Configuration.specifiedController, '\0', NAME_MAX + 1);
15
   light_Configuration.operationMode          = LIGHT_GET;
15
   light_Configuration.operationMode          = LIGHT_GET;
16
   light_Configuration.valueMode              = LIGHT_PERCENT;
16
   light_Configuration.valueMode              = LIGHT_PERCENT;
17
   light_Configuration.specifiedValueRaw      = 0;
17
   light_Configuration.specifiedValueRaw      = 0;
74
   LIGHT_BOOL ctrlSet = FALSE;
74
   LIGHT_BOOL ctrlSet = FALSE;
75
   LIGHT_BOOL valSet = FALSE;
75
   LIGHT_BOOL valSet = FALSE;
76
 
76
 
77
-  unsigned long specLen = 0;
78
-
79
   while((currFlag = getopt(argc, argv, "HhVGSAULIObmclkas:prv:")) != -1)
77
   while((currFlag = getopt(argc, argv, "HhVGSAULIObmclkas:prv:")) != -1)
80
   {
78
   {
81
     switch(currFlag)
79
     switch(currFlag)
157
           light_printHelp();
155
           light_printHelp();
158
         }
156
         }
159
 
157
 
160
-        specLen = strlen(optarg);
161
-        if(specLen > 255)
158
+        if(!light_validControllerName(optarg))
162
         {
159
         {
163
-          specLen = 255;
160
+          fprintf(stderr, "can't handle controller '%s'\n", optarg);
161
+          return FALSE;
164
         }
162
         }
165
-
166
-        strncpy(light_Configuration.specifiedController, optarg, specLen);
167
-
168
-        light_Configuration.specifiedController[255] = '\0';
163
+        strncpy(light_Configuration.specifiedController, optarg, NAME_MAX);
164
+        light_Configuration.specifiedController[NAME_MAX] = '\0';
169
         break;
165
         break;
170
       /* -- Value modes -- */
166
       /* -- Value modes -- */
171
       case 'p':
167
       case 'p':
573
 
569
 
574
 }
570
 }
575
 
571
 
572
+LIGHT_BOOL light_validControllerName(char const *controller)
573
+{
574
+  if(!controller)
575
+  {
576
+    return FALSE;
577
+  }
578
+
579
+  if(strlen(controller) > NAME_MAX)
580
+  {
581
+    LIGHT_WARN_FMT("controller \"%s\"'s name is too long", controller);
582
+    return FALSE;
583
+  }
584
+  return TRUE;
585
+}
586
+
576
 LIGHT_BOOL light_genPath(char const *controller, LIGHT_TARGET target, LIGHT_FIELD type, char **buffer)
587
 LIGHT_BOOL light_genPath(char const *controller, LIGHT_TARGET target, LIGHT_FIELD type, char **buffer)
577
 {
588
 {
578
-  char* returner = malloc(256);
589
+  char* returner;
579
   int spfVal = -1;
590
   int spfVal = -1;
580
 
591
 
581
-  if(returner == NULL)
592
+  if(!light_validControllerName(controller))
593
+  {
594
+    LIGHT_ERR("invalid controller, couldn't generate path");
595
+    return FALSE;
596
+  }
597
+
598
+  if(!buffer)
599
+  {
600
+    LIGHT_ERR("a valid buffer is required");
601
+    return FALSE;
602
+  }
603
+  *buffer = NULL;
604
+
605
+  /* PATH_MAX define includes the '\0' character, so no + 1 here*/
606
+  if((returner = malloc(PATH_MAX)) == NULL)
582
   {
607
   {
583
     LIGHT_MEMERR();
608
     LIGHT_MEMERR();
584
-    buffer = NULL;
585
     return FALSE;
609
     return FALSE;
586
   }
610
   }
587
 
611
 
588
-  memset(returner, '\0', 256);
589
   if(target == LIGHT_BACKLIGHT)
612
   if(target == LIGHT_BACKLIGHT)
590
   {
613
   {
591
     switch(type)
614
     switch(type)
592
     {
615
     {
593
       case LIGHT_BRIGHTNESS:
616
       case LIGHT_BRIGHTNESS:
594
-        spfVal = sprintf(returner, "/sys/class/backlight/%s/brightness", controller);
617
+        spfVal = snprintf(returner, PATH_MAX, "/sys/class/backlight/%s/brightness", controller);
595
         break;
618
         break;
596
       case LIGHT_MAX_BRIGHTNESS:
619
       case LIGHT_MAX_BRIGHTNESS:
597
-        spfVal = sprintf(returner, "/sys/class/backlight/%s/max_brightness", controller);
620
+        spfVal = snprintf(returner, PATH_MAX, "/sys/class/backlight/%s/max_brightness", controller);
598
         break;
621
         break;
599
       case LIGHT_MIN_CAP:
622
       case LIGHT_MIN_CAP:
600
-        spfVal = sprintf(returner, "/etc/light/mincap/%s", controller);
623
+        spfVal = snprintf(returner, PATH_MAX, "/etc/light/mincap/%s", controller);
601
         break;
624
         break;
602
       case LIGHT_SAVERESTORE:
625
       case LIGHT_SAVERESTORE:
603
-        spfVal = sprintf(returner, "/etc/light/save/%s", controller);
626
+        spfVal = snprintf(returner, PATH_MAX, "/etc/light/save/%s", controller);
604
         break;
627
         break;
605
     }
628
     }
606
   }else{
629
   }else{
607
     switch(type)
630
     switch(type)
608
     {
631
     {
609
       case LIGHT_BRIGHTNESS:
632
       case LIGHT_BRIGHTNESS:
610
-        spfVal = sprintf(returner, "/sys/class/leds/%s/brightness", controller);
633
+        spfVal = snprintf(returner, PATH_MAX, "/sys/class/leds/%s/brightness", controller);
611
         break;
634
         break;
612
       case LIGHT_MAX_BRIGHTNESS:
635
       case LIGHT_MAX_BRIGHTNESS:
613
-        spfVal = sprintf(returner, "/sys/class/leds/%s/max_brightness", controller);
636
+        spfVal = snprintf(returner, PATH_MAX, "/sys/class/leds/%s/max_brightness", controller);
614
         break;
637
         break;
615
       case LIGHT_MIN_CAP:
638
       case LIGHT_MIN_CAP:
616
-        spfVal = sprintf(returner, "/etc/light/mincap/kbd/%s", controller);
639
+        spfVal = snprintf(returner, PATH_MAX, "/etc/light/mincap/kbd/%s", controller);
617
         break;
640
         break;
618
       case LIGHT_SAVERESTORE:
641
       case LIGHT_SAVERESTORE:
619
-        spfVal = sprintf(returner, "/etc/light/save/kbd/%s", controller);
642
+        spfVal = snprintf(returner, PATH_MAX, "/etc/light/save/kbd/%s", controller);
620
         break;
643
         break;
621
     }
644
     }
622
   }
645
   }
646
+
623
   if(spfVal < 0)
647
   if(spfVal < 0)
624
   {
648
   {
625
-    LIGHT_ERR("sprintf failed");
649
+    LIGHT_ERR("snprintf failed");
626
     free(returner);
650
     free(returner);
627
-    buffer = NULL;
651
+    return FALSE;
652
+  }
653
+
654
+  /* PATH_MAX define includes the '\0' character, so - 1 here*/
655
+  if(spfVal > PATH_MAX - 1)
656
+  {
657
+    LIGHT_ERR("generated path is too long to be handled");
628
     return FALSE;
658
     return FALSE;
629
   }
659
   }
630
 
660
 
769
   return TRUE;
799
   return TRUE;
770
 }
800
 }
771
 
801
 
772
-LIGHT_BOOL light_iterateControllers()
802
+LIGHT_BOOL light_prepareControllerIteration(DIR **dir)
773
 {
803
 {
774
-  LIGHT_BOOL dotsKilled = FALSE;
804
+  if(!dir)
805
+  {
806
+    LIGHT_ERR("specified dir was NULL");
807
+    return FALSE;
808
+  }
775
 
809
 
776
-  if(light_iteratorDir == NULL)
810
+  if(light_Configuration.target == LIGHT_KEYBOARD)
777
   {
811
   {
778
-    if(light_Configuration.target == LIGHT_KEYBOARD)
779
-    {
780
-      light_iteratorDir = opendir("/sys/class/leds");
781
-    }
782
-    else
783
-    {
784
-      light_iteratorDir = opendir("/sys/class/backlight");
785
-    }
786
-    if(light_iteratorDir == NULL)
787
-    {
788
-      LIGHT_ERR("could not open backlight or leds directory in /sys/class");
789
-      return FALSE;
790
-    }
812
+    *dir = opendir("/sys/class/leds");
813
+  }
814
+  else
815
+  {
816
+    *dir = opendir("/sys/class/backlight");
817
+  }
818
+  if(dir == NULL)
819
+  {
820
+    LIGHT_ERR("could not open backlight or leds directory in /sys/class");
821
+    return FALSE;
822
+  }
823
+  return TRUE;
824
+}
825
+
826
+LIGHT_BOOL light_iterateControllers(DIR *dir, char *currentController)
827
+{
828
+  struct dirent *file;
829
+  LIGHT_BOOL controllerFound = FALSE;
830
+
831
+  if(!dir || !currentController)
832
+  {
833
+    LIGHT_ERR("one of the arguments was NULL");
834
+    return FALSE;
791
   }
835
   }
792
 
836
 
793
-  while(!dotsKilled)
837
+  while(!controllerFound)
794
   {
838
   {
795
-    light_iterator = readdir(light_iteratorDir);
796
-    if(light_iterator == NULL)
839
+    file = readdir(dir);
840
+    if(file == NULL)
797
     {
841
     {
798
-      if(light_iteratorDir != NULL)
799
-      {
800
-        closedir(light_iteratorDir);
801
-        light_iteratorDir = NULL;
802
-      }
803
       return FALSE;
842
       return FALSE;
804
     }
843
     }
805
 
844
 
806
-    if(light_iterator->d_name[0] != '.')
845
+    if(file->d_name[0] != '.')
807
     {
846
     {
808
-      dotsKilled = TRUE;
847
+      if(!light_validControllerName(file->d_name))
848
+      {
849
+        LIGHT_WARN_FMT("invalid controller '%s' found, continuing...", file->d_name);
850
+        continue;
851
+      }
852
+      controllerFound = TRUE;
809
     }
853
     }
810
   }
854
   }
811
 
855
 
812
-  strcpy(light_currentController, light_iterator->d_name);
813
-
856
+  strncpy(currentController, file->d_name, NAME_MAX);
857
+  currentController[NAME_MAX] = '\0';
814
   return TRUE;
858
   return TRUE;
815
 }
859
 }
816
 
860
 
817
 LIGHT_BOOL light_getBestController(char *controller)
861
 LIGHT_BOOL light_getBestController(char *controller)
818
 {
862
 {
819
-  char bestYet[256];
863
+  DIR *dir;
820
   unsigned long bestValYet = 0;
864
   unsigned long bestValYet = 0;
821
   LIGHT_BOOL foundOkController = FALSE;
865
   LIGHT_BOOL foundOkController = FALSE;
866
+  char bestYet[NAME_MAX + 1];
867
+  char currentController[NAME_MAX + 1];
822
 
868
 
823
-  memset(bestYet, '\0', 256);
869
+  if(!controller)
870
+  {
871
+    LIGHT_ERR("controller buffer was NULL");
872
+    return FALSE;
873
+  }
874
+
875
+  if(!light_prepareControllerIteration(&dir))
876
+  {
877
+    LIGHT_ERR("can't list controllers");
878
+    return FALSE;
879
+  }
824
 
880
 
825
-  while(light_iterateControllers())
881
+  while(light_iterateControllers(dir, currentController))
826
   {
882
   {
827
     unsigned long currVal = 0;
883
     unsigned long currVal = 0;
828
 
884
 
829
-    LIGHT_NOTE_FMT("found '%s' controller", light_currentController);
830
-    if(light_controllerAccessible(light_currentController))
885
+    LIGHT_NOTE_FMT("found '%s' controller", currentController);
886
+    if(light_controllerAccessible(currentController))
831
     {
887
     {
832
 
888
 
833
-      if(light_getMaxBrightness(light_currentController, &currVal))
889
+      if(light_getMaxBrightness(currentController, &currVal))
834
       {
890
       {
835
         if(currVal > bestValYet)
891
         if(currVal > bestValYet)
836
         {
892
         {
837
-        foundOkController = TRUE;
838
-        bestValYet = currVal;
839
-        memset(bestYet, '\0', 256);
840
-        strcpy(bestYet, light_currentController);
841
-        light_Configuration.hasCachedMaxBrightness = TRUE;
842
-        light_Configuration.cachedMaxBrightness = currVal;
893
+          foundOkController = TRUE;
894
+          bestValYet = currVal;
895
+          strncpy(bestYet, currentController, NAME_MAX);
896
+          bestYet[NAME_MAX] = '\0';
897
+          light_Configuration.hasCachedMaxBrightness = TRUE;
898
+          light_Configuration.cachedMaxBrightness = currVal;
843
         }else{
899
         }else{
844
           LIGHT_NOTE("ignoring controller as better one already found");
900
           LIGHT_NOTE("ignoring controller as better one already found");
845
         }
901
         }
851
     }
907
     }
852
   }
908
   }
853
 
909
 
910
+  closedir(dir);
911
+
854
   if(!foundOkController)
912
   if(!foundOkController)
855
   {
913
   {
856
     LIGHT_ERR("could not find an accessible controller");
914
     LIGHT_ERR("could not find an accessible controller");
863
     return FALSE;
921
     return FALSE;
864
   }
922
   }
865
 
923
 
866
-  memset(controller, '\0', 256);
867
-  strcpy(controller, bestYet);
868
-
924
+  strncpy(controller, bestYet, NAME_MAX);
925
+  controller[NAME_MAX] = '\0';
869
   return TRUE;
926
   return TRUE;
870
 }
927
 }
871
 
928
 
923
 
980
 
924
 LIGHT_BOOL light_listControllers()
981
 LIGHT_BOOL light_listControllers()
925
 {
982
 {
983
+  DIR *dir;
984
+  char controller[NAME_MAX + 1];
926
   LIGHT_BOOL foundController = FALSE;
985
   LIGHT_BOOL foundController = FALSE;
927
 
986
 
928
-  while(light_iterateControllers())
987
+  if(!light_prepareControllerIteration(&dir))
929
   {
988
   {
930
-    if(!foundController)
931
-    {
932
-      foundController = TRUE;
933
-    }
989
+    LIGHT_ERR("can't list controllers");
990
+    return FALSE;
991
+  }
934
 
992
 
935
-    printf("%s\n", light_currentController);
993
+  while(light_iterateControllers(dir, controller))
994
+  {
995
+    printf("%s\n", controller);
996
+    foundController = TRUE;
936
   }
997
   }
937
 
998
 
938
   if(!foundController)
999
   if(!foundController)
946
 
1007
 
947
 LIGHT_BOOL light_saveBrightness(char const *controller, unsigned long v){
1008
 LIGHT_BOOL light_saveBrightness(char const *controller, unsigned long v){
948
   char *savePath = NULL;
1009
   char *savePath = NULL;
1010
+
949
   if(!light_genPath(controller, light_Configuration.target, LIGHT_SAVERESTORE, &savePath))
1011
   if(!light_genPath(controller, light_Configuration.target, LIGHT_SAVERESTORE, &savePath))
950
   {
1012
   {
951
     LIGHT_ERR("could not generate path to save/restore file");
1013
     LIGHT_ERR("could not generate path to save/restore file");