On Mon, Jan 4, 2016 at 5:17 PM, David Howells <dhowells@xxxxxxxxxx> wrote: > There are still a couple of minor issues in the X.509 leap year handling: > > (1) To avoid doing a modulus-by-400 in addition to a modulus-by-100 when > determining whether the year is a leap year or not, I divided the year > by 100 after doing the modulus-by-100, thereby letting the compiler do > one instruction for both, and then did a modulus-by-4. > > Unfortunately, I then passed the now-modified year value to mktime64() > to construct a time value. > > Since this isn't a fast path and since mktime64() does a bunch of > divisions, just condense down to "% 400". It's also easier to read. > > (2) The default month length for any February where the year doesn't > divide by four exactly is obtained from the month_length[] array where > the value is 29, not 28. > > This is fixed by altering the table. > > Reported-by: Rudolf Polzer <rpolzer@xxxxxxxxxx> > Signed-off-by: David Howells <dhowells@xxxxxxxxxx> > Acked-By: David Woodhouse <David.Woodhouse@xxxxxxxxx> > cc: stable@xxxxxxxxxxxxxxx > --- > > crypto/asymmetric_keys/x509_cert_parser.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c > index 021d39c0ba75..13c4e5a5fe8c 100644 > --- a/crypto/asymmetric_keys/x509_cert_parser.c > +++ b/crypto/asymmetric_keys/x509_cert_parser.c > @@ -494,7 +494,7 @@ int x509_decode_time(time64_t *_t, size_t hdrlen, > unsigned char tag, > const unsigned char *value, size_t vlen) > { > - static const unsigned char month_lengths[] = { 31, 29, 31, 30, 31, 30, > + static const unsigned char month_lengths[] = { 31, 28, 31, 30, 31, 30, > 31, 31, 30, 31, 30, 31 }; > const unsigned char *p = value; > unsigned year, mon, day, hour, min, sec, mon_len; > @@ -540,9 +540,9 @@ int x509_decode_time(time64_t *_t, size_t hdrlen, > if (year % 4 == 0) { > mon_len = 29; > if (year % 100 == 0) { > - year /= 100; > - if (year % 4 != 0) > - mon_len = 28; > + mon_len = 28; > + if (year % 400 == 0) > + mon_len = 29; > } > } > } > Looks good. In particular this is a lot more legible than before, as it now reads exactly like the leap year rules everyone knows. A small nit: could it be that the month_lengths array also exists elsewhere in the kernel? Can it possibly be shared? A quick glance around didn't pop up anything that's not static, so, looks like it's okay to add yet another one... Best regards, Rudolf Polzer -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html