shadow-maint/shadow

How large is the universe?

alejandro-colomar opened this issue · 0 comments

shadow/lib/chkname.c

Lines 36 to 48 in 63297e8

size_t
login_name_max_size(void)
{
long conf;
errno = 0;
conf = sysconf(_SC_LOGIN_NAME_MAX);
if (conf == -1 && errno != 0)
return LOGIN_NAME_MAX;
return conf;
}

Cc: @stoeckmann

The maximum number of elements in an array object in C is PTRDIFF_MAX.

Long story:

The ISO C standard says that an implementation must support objects of at least 2^16 - 1 bytes. This is of course not the actual limit.

The standard specifies that it is valid to subtract two pointers that point to different elements of the same array object, and that the result is of ptrdiff_t type. This implies that the number of elements in an array object must be representable in a ptrdiff_t, and so the maximum number of elements in an array object is implicitly defined as not larger than PTRDIFF_MAX.

Since both the compiler and libc usually have to access objects as raw bytes, they'll also have to subtract pointers to bytes, and so the limit is further restricted to just PTRDIFF_MAX bytes (not just elements).

Here's some proof that the compiler doesn't allow objects larger than PTRDIFF_MAX bytes:

$ cat huge.c 
#include <stdint.h>

int
main(void)
{
	char  a[PTRDIFF_MAX - 1];
	char  b[PTRDIFF_MAX];
	char  c[PTRDIFF_MAX + 1ul];

	int   d[PTRDIFF_MAX - 1];
	int   e[PTRDIFF_MAX];
	int   f[PTRDIFF_MAX + 1ul];

	int   g[PTRDIFF_MAX/4 - 1];
	int   h[PTRDIFF_MAX/4];
	int   i[PTRDIFF_MAX/4 + 1];
}
$ cc -Wall -Wextra huge.c -Wno-unused-variable
huge.c: In functionmain’:
huge.c:8:15: error: size of arraycis too large
    8 |         char  c[PTRDIFF_MAX + 1ul];
      |               ^
huge.c:10:15: error: size of arraydexceeds maximum object size922337203685477580710 |         int   d[PTRDIFF_MAX - 1];
      |               ^
huge.c:11:15: error: size of arrayeexceeds maximum object size922337203685477580711 |         int   e[PTRDIFF_MAX];
      |               ^
huge.c:12:15: error: size of arrayfis too large
   12 |         int   f[PTRDIFF_MAX + 1ul];
      |               ^
huge.c:16:15: error: size9223372036854775808of arrayiexceeds maximum object size922337203685477580716 |         int   i[PTRDIFF_MAX/4 + 1];
      |               ^

https://discourse.llvm.org/t/problems-with-objects-larger-than-ptrdiff-max/41126/6


Thus, whether implementations want to recognize it or not, objects have size limits. If an implementation claims that there's no limit, it's probably lying or unaware of its own limitations.

Let's hard code a strong limit of MIN(whatever, PTRDIFF_MAX).