@@ -245,16 +245,18 @@ enum gsm_encoding {
245
245
246
246
enum gsm_mux_state {
247
247
GSM_SEARCH ,
248
- GSM_START ,
249
- GSM_ADDRESS ,
250
- GSM_CONTROL ,
251
- GSM_LEN ,
252
- GSM_DATA ,
253
- GSM_FCS ,
254
- GSM_OVERRUN ,
255
- GSM_LEN0 ,
256
- GSM_LEN1 ,
257
- GSM_SSOF ,
248
+ GSM0_ADDRESS ,
249
+ GSM0_CONTROL ,
250
+ GSM0_LEN0 ,
251
+ GSM0_LEN1 ,
252
+ GSM0_DATA ,
253
+ GSM0_FCS ,
254
+ GSM0_SSOF ,
255
+ GSM1_START ,
256
+ GSM1_ADDRESS ,
257
+ GSM1_CONTROL ,
258
+ GSM1_DATA ,
259
+ GSM1_OVERRUN ,
258
260
};
259
261
260
262
/*
@@ -2847,6 +2849,30 @@ static void gsm_queue(struct gsm_mux *gsm)
2847
2849
return ;
2848
2850
}
2849
2851
2852
+ /**
2853
+ * gsm0_receive_state_check_and_fix - check and correct receive state
2854
+ * @gsm: gsm data for this ldisc instance
2855
+ *
2856
+ * Ensures that the current receive state is valid for basic option mode.
2857
+ */
2858
+
2859
+ static void gsm0_receive_state_check_and_fix (struct gsm_mux * gsm )
2860
+ {
2861
+ switch (gsm -> state ) {
2862
+ case GSM_SEARCH :
2863
+ case GSM0_ADDRESS :
2864
+ case GSM0_CONTROL :
2865
+ case GSM0_LEN0 :
2866
+ case GSM0_LEN1 :
2867
+ case GSM0_DATA :
2868
+ case GSM0_FCS :
2869
+ case GSM0_SSOF :
2870
+ break ;
2871
+ default :
2872
+ gsm -> state = GSM_SEARCH ;
2873
+ break ;
2874
+ }
2875
+ }
2850
2876
2851
2877
/**
2852
2878
* gsm0_receive - perform processing for non-transparency
@@ -2860,26 +2886,27 @@ static void gsm0_receive(struct gsm_mux *gsm, u8 c)
2860
2886
{
2861
2887
unsigned int len ;
2862
2888
2889
+ gsm0_receive_state_check_and_fix (gsm );
2863
2890
switch (gsm -> state ) {
2864
2891
case GSM_SEARCH : /* SOF marker */
2865
2892
if (c == GSM0_SOF ) {
2866
- gsm -> state = GSM_ADDRESS ;
2893
+ gsm -> state = GSM0_ADDRESS ;
2867
2894
gsm -> address = 0 ;
2868
2895
gsm -> len = 0 ;
2869
2896
gsm -> fcs = INIT_FCS ;
2870
2897
}
2871
2898
break ;
2872
- case GSM_ADDRESS : /* Address EA */
2899
+ case GSM0_ADDRESS : /* Address EA */
2873
2900
gsm -> fcs = gsm_fcs_add (gsm -> fcs , c );
2874
2901
if (gsm_read_ea (& gsm -> address , c ))
2875
- gsm -> state = GSM_CONTROL ;
2902
+ gsm -> state = GSM0_CONTROL ;
2876
2903
break ;
2877
- case GSM_CONTROL : /* Control Byte */
2904
+ case GSM0_CONTROL : /* Control Byte */
2878
2905
gsm -> fcs = gsm_fcs_add (gsm -> fcs , c );
2879
2906
gsm -> control = c ;
2880
- gsm -> state = GSM_LEN0 ;
2907
+ gsm -> state = GSM0_LEN0 ;
2881
2908
break ;
2882
- case GSM_LEN0 : /* Length EA */
2909
+ case GSM0_LEN0 : /* Length EA */
2883
2910
gsm -> fcs = gsm_fcs_add (gsm -> fcs , c );
2884
2911
if (gsm_read_ea (& gsm -> len , c )) {
2885
2912
if (gsm -> len > gsm -> mru ) {
@@ -2889,14 +2916,14 @@ static void gsm0_receive(struct gsm_mux *gsm, u8 c)
2889
2916
}
2890
2917
gsm -> count = 0 ;
2891
2918
if (!gsm -> len )
2892
- gsm -> state = GSM_FCS ;
2919
+ gsm -> state = GSM0_FCS ;
2893
2920
else
2894
- gsm -> state = GSM_DATA ;
2921
+ gsm -> state = GSM0_DATA ;
2895
2922
break ;
2896
2923
}
2897
- gsm -> state = GSM_LEN1 ;
2924
+ gsm -> state = GSM0_LEN1 ;
2898
2925
break ;
2899
- case GSM_LEN1 :
2926
+ case GSM0_LEN1 :
2900
2927
gsm -> fcs = gsm_fcs_add (gsm -> fcs , c );
2901
2928
len = c ;
2902
2929
gsm -> len |= len << 7 ;
@@ -2907,26 +2934,29 @@ static void gsm0_receive(struct gsm_mux *gsm, u8 c)
2907
2934
}
2908
2935
gsm -> count = 0 ;
2909
2936
if (!gsm -> len )
2910
- gsm -> state = GSM_FCS ;
2937
+ gsm -> state = GSM0_FCS ;
2911
2938
else
2912
- gsm -> state = GSM_DATA ;
2939
+ gsm -> state = GSM0_DATA ;
2913
2940
break ;
2914
- case GSM_DATA : /* Data */
2941
+ case GSM0_DATA : /* Data */
2915
2942
gsm -> buf [gsm -> count ++ ] = c ;
2916
- if (gsm -> count == gsm -> len ) {
2943
+ if (gsm -> count >= MAX_MRU ) {
2944
+ gsm -> bad_size ++ ;
2945
+ gsm -> state = GSM_SEARCH ;
2946
+ } else if (gsm -> count >= gsm -> len ) {
2917
2947
/* Calculate final FCS for UI frames over all data */
2918
2948
if ((gsm -> control & ~PF ) != UIH ) {
2919
2949
gsm -> fcs = gsm_fcs_add_block (gsm -> fcs , gsm -> buf ,
2920
2950
gsm -> count );
2921
2951
}
2922
- gsm -> state = GSM_FCS ;
2952
+ gsm -> state = GSM0_FCS ;
2923
2953
}
2924
2954
break ;
2925
- case GSM_FCS : /* FCS follows the packet */
2955
+ case GSM0_FCS : /* FCS follows the packet */
2926
2956
gsm -> fcs = gsm_fcs_add (gsm -> fcs , c );
2927
- gsm -> state = GSM_SSOF ;
2957
+ gsm -> state = GSM0_SSOF ;
2928
2958
break ;
2929
- case GSM_SSOF :
2959
+ case GSM0_SSOF :
2930
2960
gsm -> state = GSM_SEARCH ;
2931
2961
if (c == GSM0_SOF )
2932
2962
gsm_queue (gsm );
@@ -2939,6 +2969,29 @@ static void gsm0_receive(struct gsm_mux *gsm, u8 c)
2939
2969
}
2940
2970
}
2941
2971
2972
+ /**
2973
+ * gsm1_receive_state_check_and_fix - check and correct receive state
2974
+ * @gsm: gsm data for this ldisc instance
2975
+ *
2976
+ * Ensures that the current receive state is valid for advanced option mode.
2977
+ */
2978
+
2979
+ static void gsm1_receive_state_check_and_fix (struct gsm_mux * gsm )
2980
+ {
2981
+ switch (gsm -> state ) {
2982
+ case GSM_SEARCH :
2983
+ case GSM1_START :
2984
+ case GSM1_ADDRESS :
2985
+ case GSM1_CONTROL :
2986
+ case GSM1_DATA :
2987
+ case GSM1_OVERRUN :
2988
+ break ;
2989
+ default :
2990
+ gsm -> state = GSM_SEARCH ;
2991
+ break ;
2992
+ }
2993
+ }
2994
+
2942
2995
/**
2943
2996
* gsm1_receive - perform processing for non-transparency
2944
2997
* @gsm: gsm data for this ldisc instance
@@ -2949,6 +3002,7 @@ static void gsm0_receive(struct gsm_mux *gsm, u8 c)
2949
3002
2950
3003
static void gsm1_receive (struct gsm_mux * gsm , u8 c )
2951
3004
{
3005
+ gsm1_receive_state_check_and_fix (gsm );
2952
3006
/* handle XON/XOFF */
2953
3007
if ((c & ISO_IEC_646_MASK ) == XON ) {
2954
3008
gsm -> constipated = true;
@@ -2961,11 +3015,11 @@ static void gsm1_receive(struct gsm_mux *gsm, u8 c)
2961
3015
}
2962
3016
if (c == GSM1_SOF ) {
2963
3017
/* EOF is only valid in frame if we have got to the data state */
2964
- if (gsm -> state == GSM_DATA ) {
3018
+ if (gsm -> state == GSM1_DATA ) {
2965
3019
if (gsm -> count < 1 ) {
2966
3020
/* Missing FSC */
2967
3021
gsm -> malformed ++ ;
2968
- gsm -> state = GSM_START ;
3022
+ gsm -> state = GSM1_START ;
2969
3023
return ;
2970
3024
}
2971
3025
/* Remove the FCS from data */
@@ -2981,14 +3035,14 @@ static void gsm1_receive(struct gsm_mux *gsm, u8 c)
2981
3035
gsm -> fcs = gsm_fcs_add (gsm -> fcs , gsm -> buf [gsm -> count ]);
2982
3036
gsm -> len = gsm -> count ;
2983
3037
gsm_queue (gsm );
2984
- gsm -> state = GSM_START ;
3038
+ gsm -> state = GSM1_START ;
2985
3039
return ;
2986
3040
}
2987
3041
/* Any partial frame was a runt so go back to start */
2988
- if (gsm -> state != GSM_START ) {
3042
+ if (gsm -> state != GSM1_START ) {
2989
3043
if (gsm -> state != GSM_SEARCH )
2990
3044
gsm -> malformed ++ ;
2991
- gsm -> state = GSM_START ;
3045
+ gsm -> state = GSM1_START ;
2992
3046
}
2993
3047
/* A SOF in GSM_START means we are still reading idling or
2994
3048
framing bytes */
@@ -3009,30 +3063,30 @@ static void gsm1_receive(struct gsm_mux *gsm, u8 c)
3009
3063
gsm -> escape = false;
3010
3064
}
3011
3065
switch (gsm -> state ) {
3012
- case GSM_START : /* First byte after SOF */
3066
+ case GSM1_START : /* First byte after SOF */
3013
3067
gsm -> address = 0 ;
3014
- gsm -> state = GSM_ADDRESS ;
3068
+ gsm -> state = GSM1_ADDRESS ;
3015
3069
gsm -> fcs = INIT_FCS ;
3016
3070
fallthrough ;
3017
- case GSM_ADDRESS : /* Address continuation */
3071
+ case GSM1_ADDRESS : /* Address continuation */
3018
3072
gsm -> fcs = gsm_fcs_add (gsm -> fcs , c );
3019
3073
if (gsm_read_ea (& gsm -> address , c ))
3020
- gsm -> state = GSM_CONTROL ;
3074
+ gsm -> state = GSM1_CONTROL ;
3021
3075
break ;
3022
- case GSM_CONTROL : /* Control Byte */
3076
+ case GSM1_CONTROL : /* Control Byte */
3023
3077
gsm -> fcs = gsm_fcs_add (gsm -> fcs , c );
3024
3078
gsm -> control = c ;
3025
3079
gsm -> count = 0 ;
3026
- gsm -> state = GSM_DATA ;
3080
+ gsm -> state = GSM1_DATA ;
3027
3081
break ;
3028
- case GSM_DATA : /* Data */
3029
- if (gsm -> count > gsm -> mru ) { /* Allow one for the FCS */
3030
- gsm -> state = GSM_OVERRUN ;
3082
+ case GSM1_DATA : /* Data */
3083
+ if (gsm -> count > gsm -> mru || gsm -> count > MAX_MRU ) { /* Allow one for the FCS */
3084
+ gsm -> state = GSM1_OVERRUN ;
3031
3085
gsm -> bad_size ++ ;
3032
3086
} else
3033
3087
gsm -> buf [gsm -> count ++ ] = c ;
3034
3088
break ;
3035
- case GSM_OVERRUN : /* Over-long - eg a dropped SOF */
3089
+ case GSM1_OVERRUN : /* Over-long - eg a dropped SOF */
3036
3090
break ;
3037
3091
default :
3038
3092
pr_debug ("%s: unhandled state: %d\n" , __func__ , gsm -> state );
0 commit comments