Dear maintainer,

Thank you for your work on maintaining GNU Coreutils.

I would like to report a potential security issue in pr. A specially crafted -D 
date format can cause an integer wraparound in nstrftime, resulting in an 
extremely large size being passed to memset.

The issue is still reproducible on the latest Coreutils 9.12 release.

Minimal reproducer

pr -D'%+_1z' /dev/null

With AddressSanitizer, this results in a negative-size-param error in:

lib/strftime.c:1939

Cause

The issue occurs in do_number_sign_and_padding():

byte_count_t shortage = width - !!sign_char - number_digits;
byte_count_t padding = (pad == NO_PAD || shortage <= 0 ? 0 : shortage);
...
memset_space (p, padding);

In the nstrftime build, byte_count_t is an unsigned type (size_t).

For the format above, the expression used to calculate shortage becomes 
negative. Because shortage is unsigned, the value wraps around to a very large 
positive value.

As a result, the following check:

shortage <= 0

does not detect the condition, and the wrapped value is subsequently used as 
the padding size. This eventually causes memset to be called with an invalid 
extremely large size.

UBSan also reports integer conversion immediately before the memory error.

The corresponding strftime.c in the current gnulib master contains the same 
logic, so the issue appears to remain present there as well.

A possible fix would be to calculate shortage using the signed sbyte_count_t 
type before determining the padding size.

Best regards,
Lingfeng Chen
Kyushu University

<<attachment: reproduce.zip>>

Reply via email to