@@ -81,8 +81,6 @@ static int sctp_process_param(struct sctp_association *asoc,
81
81
gfp_t gfp );
82
82
static void * sctp_addto_param (struct sctp_chunk * chunk , int len ,
83
83
const void * data );
84
- static void * sctp_addto_chunk_fixed (struct sctp_chunk * , int len ,
85
- const void * data );
86
84
87
85
/* Control chunk destructor */
88
86
static void sctp_control_release_owner (struct sk_buff * skb )
@@ -154,46 +152,28 @@ static const struct sctp_paramhdr prsctp_param = {
154
152
cpu_to_be16 (sizeof (struct sctp_paramhdr )),
155
153
};
156
154
157
- /* A helper to initialize an op error inside a
158
- * provided chunk, as most cause codes will be embedded inside an
159
- * abort chunk.
155
+ /* A helper to initialize an op error inside a provided chunk, as most
156
+ * cause codes will be embedded inside an abort chunk.
160
157
*/
161
- void sctp_init_cause (struct sctp_chunk * chunk , __be16 cause_code ,
162
- size_t paylen )
158
+ int sctp_init_cause (struct sctp_chunk * chunk , __be16 cause_code ,
159
+ size_t paylen )
163
160
{
164
161
struct sctp_errhdr err ;
165
162
__u16 len ;
166
163
167
164
/* Cause code constants are now defined in network order. */
168
165
err .cause = cause_code ;
169
166
len = sizeof (err ) + paylen ;
170
- err .length = htons (len );
171
- chunk -> subh .err_hdr = sctp_addto_chunk (chunk , sizeof (err ), & err );
172
- }
173
-
174
- /* A helper to initialize an op error inside a
175
- * provided chunk, as most cause codes will be embedded inside an
176
- * abort chunk. Differs from sctp_init_cause in that it won't oops
177
- * if there isn't enough space in the op error chunk
178
- */
179
- static int sctp_init_cause_fixed (struct sctp_chunk * chunk , __be16 cause_code ,
180
- size_t paylen )
181
- {
182
- struct sctp_errhdr err ;
183
- __u16 len ;
184
-
185
- /* Cause code constants are now defined in network order. */
186
- err .cause = cause_code ;
187
- len = sizeof (err ) + paylen ;
188
- err .length = htons (len );
167
+ err .length = htons (len );
189
168
190
169
if (skb_tailroom (chunk -> skb ) < len )
191
170
return - ENOSPC ;
192
171
193
- chunk -> subh .err_hdr = sctp_addto_chunk_fixed (chunk , sizeof (err ), & err );
172
+ chunk -> subh .err_hdr = sctp_addto_chunk (chunk , sizeof (err ), & err );
194
173
195
174
return 0 ;
196
175
}
176
+
197
177
/* 3.3.2 Initiation (INIT) (1)
198
178
*
199
179
* This chunk is used to initiate a SCTP association between two
@@ -1257,20 +1237,26 @@ static struct sctp_chunk *sctp_make_op_error_space(
1257
1237
return retval ;
1258
1238
}
1259
1239
1260
- /* Create an Operation Error chunk of a fixed size,
1261
- * specifically, max(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT)
1262
- * This is a helper function to allocate an error chunk for
1263
- * for those invalid parameter codes in which we may not want
1264
- * to report all the errors, if the incoming chunk is large
1240
+ /* Create an Operation Error chunk of a fixed size, specifically,
1241
+ * min(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT) - overheads.
1242
+ * This is a helper function to allocate an error chunk for for those
1243
+ * invalid parameter codes in which we may not want to report all the
1244
+ * errors, if the incoming chunk is large. If it can't fit in a single
1245
+ * packet, we ignore it.
1265
1246
*/
1266
- static inline struct sctp_chunk * sctp_make_op_error_fixed (
1247
+ static inline struct sctp_chunk * sctp_make_op_error_limited (
1267
1248
const struct sctp_association * asoc ,
1268
1249
const struct sctp_chunk * chunk )
1269
1250
{
1270
- size_t size = asoc ? asoc -> pathmtu : 0 ;
1251
+ size_t size = SCTP_DEFAULT_MAXSEGMENT ;
1252
+ struct sctp_sock * sp = NULL ;
1271
1253
1272
- if (!size )
1273
- size = SCTP_DEFAULT_MAXSEGMENT ;
1254
+ if (asoc ) {
1255
+ size = min_t (size_t , size , asoc -> pathmtu );
1256
+ sp = sctp_sk (asoc -> base .sk );
1257
+ }
1258
+
1259
+ size = sctp_mtu_payload (sp , size , sizeof (struct sctp_errhdr ));
1274
1260
1275
1261
return sctp_make_op_error_space (asoc , chunk , size );
1276
1262
}
@@ -1522,18 +1508,6 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data)
1522
1508
return target ;
1523
1509
}
1524
1510
1525
- /* Append bytes to the end of a chunk. Returns NULL if there isn't sufficient
1526
- * space in the chunk
1527
- */
1528
- static void * sctp_addto_chunk_fixed (struct sctp_chunk * chunk ,
1529
- int len , const void * data )
1530
- {
1531
- if (skb_tailroom (chunk -> skb ) >= len )
1532
- return sctp_addto_chunk (chunk , len , data );
1533
- else
1534
- return NULL ;
1535
- }
1536
-
1537
1511
/* Append bytes from user space to the end of a chunk. Will panic if
1538
1512
* chunk is not big enough.
1539
1513
* Returns a kernel err value.
@@ -1828,6 +1802,9 @@ struct sctp_association *sctp_unpack_cookie(
1828
1802
kt = ktime_get_real ();
1829
1803
1830
1804
if (!asoc && ktime_before (bear_cookie -> expiration , kt )) {
1805
+ suseconds_t usecs = ktime_to_us (ktime_sub (kt , bear_cookie -> expiration ));
1806
+ __be32 n = htonl (usecs );
1807
+
1831
1808
/*
1832
1809
* Section 3.3.10.3 Stale Cookie Error (3)
1833
1810
*
@@ -1836,17 +1813,12 @@ struct sctp_association *sctp_unpack_cookie(
1836
1813
* Stale Cookie Error: Indicates the receipt of a valid State
1837
1814
* Cookie that has expired.
1838
1815
*/
1839
- len = ntohs (chunk -> chunk_hdr -> length );
1840
- * errp = sctp_make_op_error_space (asoc , chunk , len );
1841
- if (* errp ) {
1842
- suseconds_t usecs = ktime_to_us (ktime_sub (kt , bear_cookie -> expiration ));
1843
- __be32 n = htonl (usecs );
1844
-
1845
- sctp_init_cause (* errp , SCTP_ERROR_STALE_COOKIE ,
1846
- sizeof (n ));
1847
- sctp_addto_chunk (* errp , sizeof (n ), & n );
1816
+ * errp = sctp_make_op_error (asoc , chunk ,
1817
+ SCTP_ERROR_STALE_COOKIE , & n ,
1818
+ sizeof (n ), 0 );
1819
+ if (* errp )
1848
1820
* error = - SCTP_IERROR_STALE_COOKIE ;
1849
- } else
1821
+ else
1850
1822
* error = - SCTP_IERROR_NOMEM ;
1851
1823
1852
1824
goto fail ;
@@ -1997,12 +1969,8 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
1997
1969
if (* errp )
1998
1970
sctp_chunk_free (* errp );
1999
1971
2000
- * errp = sctp_make_op_error_space (asoc , chunk , len );
2001
-
2002
- if (* errp ) {
2003
- sctp_init_cause (* errp , SCTP_ERROR_DNS_FAILED , len );
2004
- sctp_addto_chunk (* errp , len , param .v );
2005
- }
1972
+ * errp = sctp_make_op_error (asoc , chunk , SCTP_ERROR_DNS_FAILED ,
1973
+ param .v , len , 0 );
2006
1974
2007
1975
/* Stop processing this chunk. */
2008
1976
return 0 ;
@@ -2127,23 +2095,23 @@ static enum sctp_ierror sctp_process_unk_param(
2127
2095
/* Make an ERROR chunk, preparing enough room for
2128
2096
* returning multiple unknown parameters.
2129
2097
*/
2130
- if (NULL == * errp )
2131
- * errp = sctp_make_op_error_fixed (asoc , chunk );
2132
-
2133
- if (* errp ) {
2134
- if (!sctp_init_cause_fixed (* errp , SCTP_ERROR_UNKNOWN_PARAM ,
2135
- SCTP_PAD4 (ntohs (param .p -> length ))))
2136
- sctp_addto_chunk_fixed (* errp ,
2137
- SCTP_PAD4 (ntohs (param .p -> length )),
2138
- param .v );
2139
- } else {
2140
- /* If there is no memory for generating the ERROR
2141
- * report as specified, an ABORT will be triggered
2142
- * to the peer and the association won't be
2143
- * established.
2144
- */
2145
- retval = SCTP_IERROR_NOMEM ;
2098
+ if (!* errp ) {
2099
+ * errp = sctp_make_op_error_limited (asoc , chunk );
2100
+ if (!* errp ) {
2101
+ /* If there is no memory for generating the
2102
+ * ERROR report as specified, an ABORT will be
2103
+ * triggered to the peer and the association
2104
+ * won't be established.
2105
+ */
2106
+ retval = SCTP_IERROR_NOMEM ;
2107
+ break ;
2108
+ }
2146
2109
}
2110
+
2111
+ if (!sctp_init_cause (* errp , SCTP_ERROR_UNKNOWN_PARAM ,
2112
+ ntohs (param .p -> length )))
2113
+ sctp_addto_chunk (* errp , ntohs (param .p -> length ),
2114
+ param .v );
2147
2115
break ;
2148
2116
default :
2149
2117
break ;
@@ -2219,10 +2187,10 @@ static enum sctp_ierror sctp_verify_param(struct net *net,
2219
2187
* MUST be aborted. The ABORT chunk SHOULD contain the error
2220
2188
* cause 'Protocol Violation'.
2221
2189
*/
2222
- if (SCTP_AUTH_RANDOM_LENGTH !=
2223
- ntohs ( param . p -> length ) - sizeof (struct sctp_paramhdr )) {
2190
+ if (SCTP_AUTH_RANDOM_LENGTH != ntohs ( param . p -> length ) -
2191
+ sizeof (struct sctp_paramhdr )) {
2224
2192
sctp_process_inv_paramlength (asoc , param .p ,
2225
- chunk , err_chunk );
2193
+ chunk , err_chunk );
2226
2194
retval = SCTP_IERROR_ABORT ;
2227
2195
}
2228
2196
break ;
0 commit comments