@@ -215,7 +215,7 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
215215 unsigned int * _toklen )
216216{
217217 const __be32 * xdr = * _xdr ;
218- unsigned int toklen = * _toklen , n_parts , loop , tmp ;
218+ unsigned int toklen = * _toklen , n_parts , loop , tmp , paddedlen ;
219219
220220 /* there must be at least one name, and at least #names+1 length
221221 * words */
@@ -245,16 +245,16 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
245245 toklen -= 4 ;
246246 if (tmp <= 0 || tmp > AFSTOKEN_STRING_MAX )
247247 return - EINVAL ;
248- if (tmp > toklen )
248+ paddedlen = (tmp + 3 ) & ~3 ;
249+ if (paddedlen > toklen )
249250 return - EINVAL ;
250251 princ -> name_parts [loop ] = kmalloc (tmp + 1 , GFP_KERNEL );
251252 if (!princ -> name_parts [loop ])
252253 return - ENOMEM ;
253254 memcpy (princ -> name_parts [loop ], xdr , tmp );
254255 princ -> name_parts [loop ][tmp ] = 0 ;
255- tmp = (tmp + 3 ) & ~3 ;
256- toklen -= tmp ;
257- xdr += tmp >> 2 ;
256+ toklen -= paddedlen ;
257+ xdr += paddedlen >> 2 ;
258258 }
259259
260260 if (toklen < 4 )
@@ -263,16 +263,16 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
263263 toklen -= 4 ;
264264 if (tmp <= 0 || tmp > AFSTOKEN_K5_REALM_MAX )
265265 return - EINVAL ;
266- if (tmp > toklen )
266+ paddedlen = (tmp + 3 ) & ~3 ;
267+ if (paddedlen > toklen )
267268 return - EINVAL ;
268269 princ -> realm = kmalloc (tmp + 1 , GFP_KERNEL );
269270 if (!princ -> realm )
270271 return - ENOMEM ;
271272 memcpy (princ -> realm , xdr , tmp );
272273 princ -> realm [tmp ] = 0 ;
273- tmp = (tmp + 3 ) & ~3 ;
274- toklen -= tmp ;
275- xdr += tmp >> 2 ;
274+ toklen -= paddedlen ;
275+ xdr += paddedlen >> 2 ;
276276
277277 _debug ("%s/...@%s" , princ -> name_parts [0 ], princ -> realm );
278278
@@ -291,7 +291,7 @@ static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td,
291291 unsigned int * _toklen )
292292{
293293 const __be32 * xdr = * _xdr ;
294- unsigned int toklen = * _toklen , len ;
294+ unsigned int toklen = * _toklen , len , paddedlen ;
295295
296296 /* there must be at least one tag and one length word */
297297 if (toklen <= 8 )
@@ -305,15 +305,17 @@ static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td,
305305 toklen -= 8 ;
306306 if (len > max_data_size )
307307 return - EINVAL ;
308+ paddedlen = (len + 3 ) & ~3 ;
309+ if (paddedlen > toklen )
310+ return - EINVAL ;
308311 td -> data_len = len ;
309312
310313 if (len > 0 ) {
311314 td -> data = kmemdup (xdr , len , GFP_KERNEL );
312315 if (!td -> data )
313316 return - ENOMEM ;
314- len = (len + 3 ) & ~3 ;
315- toklen -= len ;
316- xdr += len >> 2 ;
317+ toklen -= paddedlen ;
318+ xdr += paddedlen >> 2 ;
317319 }
318320
319321 _debug ("tag %x len %x" , td -> tag , td -> data_len );
@@ -385,7 +387,7 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
385387 const __be32 * * _xdr , unsigned int * _toklen )
386388{
387389 const __be32 * xdr = * _xdr ;
388- unsigned int toklen = * _toklen , len ;
390+ unsigned int toklen = * _toklen , len , paddedlen ;
389391
390392 /* there must be at least one length word */
391393 if (toklen <= 4 )
@@ -397,6 +399,9 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
397399 toklen -= 4 ;
398400 if (len > AFSTOKEN_K5_TIX_MAX )
399401 return - EINVAL ;
402+ paddedlen = (len + 3 ) & ~3 ;
403+ if (paddedlen > toklen )
404+ return - EINVAL ;
400405 * _tktlen = len ;
401406
402407 _debug ("ticket len %u" , len );
@@ -405,9 +410,8 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
405410 * _ticket = kmemdup (xdr , len , GFP_KERNEL );
406411 if (!* _ticket )
407412 return - ENOMEM ;
408- len = (len + 3 ) & ~3 ;
409- toklen -= len ;
410- xdr += len >> 2 ;
413+ toklen -= paddedlen ;
414+ xdr += paddedlen >> 2 ;
411415 }
412416
413417 * _xdr = xdr ;
@@ -550,7 +554,7 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
550554{
551555 const __be32 * xdr = prep -> data , * token ;
552556 const char * cp ;
553- unsigned int len , tmp , loop , ntoken , toklen , sec_ix ;
557+ unsigned int len , paddedlen , loop , ntoken , toklen , sec_ix ;
554558 size_t datalen = prep -> datalen ;
555559 int ret ;
556560
@@ -576,22 +580,21 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
576580 if (len < 1 || len > AFSTOKEN_CELL_MAX )
577581 goto not_xdr ;
578582 datalen -= 4 ;
579- tmp = (len + 3 ) & ~3 ;
580- if (tmp > datalen )
583+ paddedlen = (len + 3 ) & ~3 ;
584+ if (paddedlen > datalen )
581585 goto not_xdr ;
582586
583587 cp = (const char * ) xdr ;
584588 for (loop = 0 ; loop < len ; loop ++ )
585589 if (!isprint (cp [loop ]))
586590 goto not_xdr ;
587- if (len < tmp )
588- for (; loop < tmp ; loop ++ )
589- if (cp [loop ])
590- goto not_xdr ;
591+ for (; loop < paddedlen ; loop ++ )
592+ if (cp [loop ])
593+ goto not_xdr ;
591594 _debug ("cellname: [%u/%u] '%*.*s'" ,
592- len , tmp , len , len , (const char * ) xdr );
593- datalen -= tmp ;
594- xdr += tmp >> 2 ;
595+ len , paddedlen , len , len , (const char * ) xdr );
596+ datalen -= paddedlen ;
597+ xdr += paddedlen >> 2 ;
595598
596599 /* get the token count */
597600 if (datalen < 12 )
@@ -612,10 +615,11 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
612615 sec_ix = ntohl (* xdr );
613616 datalen -= 4 ;
614617 _debug ("token: [%x/%zx] %x" , toklen , datalen , sec_ix );
615- if (toklen < 20 || toklen > datalen )
618+ paddedlen = (toklen + 3 ) & ~3 ;
619+ if (toklen < 20 || toklen > datalen || paddedlen > datalen )
616620 goto not_xdr ;
617- datalen -= ( toklen + 3 ) & ~ 3 ;
618- xdr += ( toklen + 3 ) >> 2 ;
621+ datalen -= paddedlen ;
622+ xdr += paddedlen >> 2 ;
619623
620624 } while (-- loop > 0 );
621625
0 commit comments