edit:
Finally, I was able to pass <= 256KB as a single command line argument (see Edit (4) below). However, please read carefully how I did this and decide for yourself whether you want to go this route. At the very least, you should understand why you were “stuck” differently from what I found out.
With the ARG_MAX clutch, the introduction of MAX_ARG_STRLEN as max. argument length:
...
#ifdef CONFIG_MMU
...
static bool valid_arg_len(struct linux_binprm *bprm, long len) { return len <= MAX_ARG_STRLEN; }
...
#else
...
static bool valid_arg_len(struct linux_binprm *bprm, long len) { return len <= bprm->p; } #endif
...
static int copy_strings(int argc, struct user_arg_ptr argv, struct linux_binprm *bprm) {
...
str = get_user_arg_ptr(argv, argc);
...
len = strnlen_user(str, MAX_ARG_STRLEN); if (!len) goto out; ret = -E2BIG; if (!valid_arg_len(bprm, len)) goto out;
...
}
...
MAX_ARG_STRLEN defined as a MAX_ARG_STRLEN page size in linux/include/uapi/linux/binfmts.h :
...
#define MAX_ARG_STRLEN (PAGE_SIZE * 32) #define MAX_ARG_STRINGS 0x7FFFFFFF
...
The default page size is 4 KB, so arguments cannot be passed longer than 128 KB.
I can't try it now, but maybe switching to huge page mode (4 MB page size), if possible on your system, solves this problem.
See this answer to a similar question on Unix & Linux SE for more details and links.
edits:
(1) According to this answer, you can resize the x86_64 Linux page size to 1 MB by enabling CONFIG_TRANSPARENT_HUGEPAGE and setting CONFIG_TRANSPARENT_HUGEPAGE_MADVISE to n in the kernel configuration.
(2) After recompiling my kernel with the above configuration changes, getconf PAGESIZE still returns 4096. According to this answer , CONFIG_HUGETLB_PAGE also needed, which I could get through CONFIG_HUGETLBFS . I will recompile now and will test again.
(3) I recompiled my kernel with CONFIG_HUGETLBFS enabled and now /proc/meminfo contains the corresponding HugePages_* entries mentioned in the corresponding section of the kernel documentation . However, the page size according to getconf PAGESIZE remains unchanged. Therefore, although I should now be able to request huge pages through mmap calls, the default page size in the kernel that defines MAX_ARG_STRLEN is still set to 4 KB.
(4) I changed linux/include/uapi/linux/binfmts.h to #define MAX_ARG_STRLEN (PAGE_SIZE * 64) , recompiled my kernel, and now your code produces:
...
117037 123196 123196 129680 129680 136505 143689 151251 159211
...
227982 227982 239981 239981 252611 252611 265906 ./testCL: line 11: ./foo: Argument list too long 279901 ./testCL: line 11: ./foo: Argument list too long 294632 ./testCL: line 11: ./foo: Argument list too long
Thus, the limit is now increased from 128 KB to 256 KB, as expected. I don't know about potential side effects though. As far as I can tell, my system is working fine.