db-d2/primevul-codebert-embeddings huggingface dataset:
Commit message: ftrace, perf: Add support to use function tracepoint in perf

Adding perf registration support for the ftrace function event,
so it is now possible to register it via perf interface.

The perf_event struct statically contains ftrace_ops as a handle
for function tracer. The function tracer is registered/unregistered
in open/close actions.

To be efficient, we enable/disable ftrace_ops each time the traced
process is scheduled in/out (via TRACE_REG_PERF_(ADD|DELL) handlers).
This way tracing is enabled only when the process is running.
Intentionally using this way instead of the event's hw state
PERF_HES_STOPPED, which would not disable the ftrace_ops.

It is now possible to use function trace within perf commands
like:

  perf record -e ftrace:function ls
  perf stat -e ftrace:function ls

Allowed only for root.

Link: http://lkml.kernel.org/r/1329317514-8131-6-git-send-email-jolsa@redhat.com

Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
CVE: None
Vulnerability description: None

Project: linux
File: trace_event_perf.c

static int perf_ftrace_function_unregister(struct perf_event *event)
{
	struct ftrace_ops *ops = &event->ftrace_ops;
	return unregister_ftrace_function(ops);
}

Project: linux
File: trace_event_perf.c

perf_ftrace_function_call(unsigned long ip, unsigned long parent_ip)
{
	struct ftrace_entry *entry;
	struct hlist_head *head;
	struct pt_regs regs;
	int rctx;

#define ENTRY_SIZE (ALIGN(sizeof(struct ftrace_entry) + sizeof(u32), \
		    sizeof(u64)) - sizeof(u32))

	BUILD_BUG_ON(ENTRY_SIZE > PERF_MAX_TRACE_SIZE);

	perf_fetch_caller_regs(&regs);

	entry = perf_trace_buf_prepare(ENTRY_SIZE, TRACE_FN, NULL, &rctx);
	if (!entry)
		return;

	entry->ip = ip;
	entry->parent_ip = parent_ip;

	head = this_cpu_ptr(event_function.perf_events);
	perf_trace_buf_submit(entry, ENTRY_SIZE, rctx, 0,
			      1, &regs, head);

#undef ENTRY_SIZE
}

Project: linux
File: trace_export.c

int ftrace_event_is_function(struct ftrace_event_call *call)
{
	return call == &event_function;
}

Project: linux
File: trace_event_perf.c

__kprobes void *perf_trace_buf_prepare(int size, unsigned short type,
				       struct pt_regs *regs, int *rctxp)
{
	struct trace_entry *entry;
	unsigned long flags;
	char *raw_data;
	int pc;

	BUILD_BUG_ON(PERF_MAX_TRACE_SIZE % sizeof(unsigned long));

	pc = preempt_count();

	*rctxp = perf_swevent_get_recursion_context();
	if (*rctxp < 0)
		return NULL;

	raw_data = this_cpu_ptr(perf_trace_buf[*rctxp]);

	/* zero the dead bytes from align to not leak stack to user */
	memset(&raw_data[size - sizeof(u64)], 0, sizeof(u64));

	entry = (struct trace_entry *)raw_data;
	local_save_flags(flags);
	tracing_generic_entry_update(entry, flags, pc);
	entry->type = type;

	return raw_data;
}
Commit message: Bug 698888: Keep one-to-many state when splitting nodes in cmap splay trees.

Thanks to oss-fuzz for reporting this.
CVE: CVE-2018-1000039
Vulnerability description: In MuPDF 1.12.0 and earlier, multiple heap use after free bugs in the PDF parser could allow an attacker to execute arbitrary code, read memory, or cause a denial of service via a crafted file.

Project: mupdf
File: pdf-cmap.c

do_check(cmap_splay *node, void *arg)
{
	cmap_splay *tree = arg;
	unsigned int num = node - tree;
	assert(node->left == EMPTY || tree[node->left].parent == num);
	assert(node->right == EMPTY || tree[node->right].parent == num);
}
Commit message: bpf: Dont allow vmlinux BTF to be used in map_create and prog_load.

The syzbot got FD of vmlinux BTF and passed it into map_create which caused
crash in btf_type_id_size() when it tried to access resolved_ids. The vmlinux
BTF doesn't have 'resolved_ids' and 'resolved_sizes' initialized to save
memory. To avoid such issues disallow using vmlinux BTF in prog_load and
map_create commands.

Fixes: 5329722057d4 ("bpf: Assign ID to vmlinux BTF and return extra info for BTF in GET_OBJ_INFO")
Reported-by: syzbot+8bab8ed346746e7540e8@syzkaller.appspotmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20210307225248.79031-1-alexei.starovoitov@gmail.com
CVE: CVE-2021-29648
CWE: CWE-307
Vulnerability description: An issue was discovered in the Linux kernel before 5.11.11. The BPF subsystem does not properly consider that resolved_ids and resolved_sizes are intentionally uninitialized in the vmlinux BPF Type Format (BTF), which can cause a system crash upon an unexpected access attempt (in map_create in kernel/bpf/syscall.c or check_btf_info in kernel/bpf/verifier.c), aka CID-350a5c4dd245.

Project: linux
File: syscall.c

static int link_detach(union bpf_attr *attr)
{
	struct bpf_link *link;
	int ret;

	if (CHECK_ATTR(BPF_LINK_DETACH))
		return -EINVAL;

	link = bpf_link_get_from_fd(attr->link_detach.link_fd);
	if (IS_ERR(link))
		return PTR_ERR(link);

	if (link->ops->detach)
		ret = link->ops->detach(link);
	else
		ret = -EOPNOTSUPP;

	bpf_link_put(link);
	return ret;
}
Commit message: Fix DCTStream::getChars we're reading past the buffer check

I wonder how this had never crashed before :S

Fixes #1011
CVE: CVE-2020-35702
CWE: CWE-787
Vulnerability description: DCTStream::getChars in DCTStream.cc in Poppler 20.12.1 has a heap-based buffer overflow via a crafted PDF document. NOTE: later reports indicate that this only affects builds from Poppler git clones in late December 2020, not the 20.12.1 release. In this situation, it should NOT be considered a Poppler vulnerability. However, several third-party Open Source projects directly rely on Poppler git clones made at arbitrary times, and therefore the CVE remains useful to users of those projects

Project: poppler
File: DCTStream.cc

int DCTStream::getChars(int nChars, unsigned char *buffer)
{
    for (int i = 0; i < nChars;) {
        if (current == limit) {
            if (!readLine())
                return i;
        }
        int left = limit - current;
        if (left + i > nChars)
            left = nChars - i;
        memcpy(buffer + i, current, left);
        current += left;
        i += left;
    }
    return nChars;
}
Commit message: ARM: amba: Fix race condition with driver_override

The driver_override implementation is susceptible to a race condition
when different threads are reading vs storing a different driver
override.  Add locking to avoid this race condition.

Cfr. commits 6265539776a0810b ("driver core: platform: fix race
condition with driver_override") and 9561475db680f714 ("PCI: Fix race
condition with driver_override").

Fixes: 3cf385713460eb2b ("ARM: 8256/1: driver coamba: add device binding path 'driver_override'")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Todd Kjos <tkjos@google.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CVE: CVE-2018-9415
CWE: CWE-415
Vulnerability description: In driver_override_store and driver_override_show of bus.c, there is a possible double free due to improper locking. This could lead to local escalation of privilege with System execution privileges needed. User interaction is not needed for exploitation. Product: Android Versions: Android kernel Android ID: A-69129004 References: Upstream kernel.

Project: linux
File: bus.c

static ssize_t driver_override_show(struct device *_dev,
				    struct device_attribute *attr, char *buf)
{
	struct amba_device *dev = to_amba_device(_dev);
	ssize_t len;

	device_lock(_dev);
	len = sprintf(buf, "%s\n", dev->driver_override);
	device_unlock(_dev);
	return len;
}
Commit message: Add extra check before integer conversion

end < p should never happen, but just be extra sure
CVE: CVE-2015-5291
CWE: CWE-119
Vulnerability description: Heap-based buffer overflow in PolarSSL 1.x before 1.2.17 and ARM mbed TLS (formerly PolarSSL) 1.3.x before 1.3.14 and 2.x before 2.1.2 allows remote SSL servers to cause a denial of service (client crash) and possibly execute arbitrary code via a long hostname to the server name indication (SNI) extension, which is not properly handled when creating a ClientHello message.  NOTE: this identifier has been SPLIT per ADT3 due to different affected version ranges. See CVE-2015-8036 for the session ticket issue that was introduced in 1.3.0.

Project: mbedtls
File: ssl_cli.c

static void ssl_write_renegotiation_ext( ssl_context *ssl,
                                         unsigned char *buf,
                                         size_t *olen )
{
    unsigned char *p = buf;
    const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN;

    *olen = 0;

    if( ssl->renegotiation != SSL_RENEGOTIATION )
        return;

    SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );

    if( end < p || (size_t)(end - p) < 5 + ssl->verify_data_len )
    {
        SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
        return;
    }

    /*
     * Secure renegotiation
     */
    *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
    *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO      ) & 0xFF );

    *p++ = 0x00;
    *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
    *p++ = ssl->verify_data_len & 0xFF;

    memcpy( p, ssl->own_verify_data, ssl->verify_data_len );

    *olen = 5 + ssl->verify_data_len;
}
Commit message: fix regression in "epoll: Keep a reference on files added to the check list"

epoll_loop_check_proc() can run into a file already committed to destruction;
we can't grab a reference on those and don't need to add them to the set for
reverse path check anyway.

Tested-by: Marc Zyngier <maz@kernel.org>
Fixes: a9ed4a6560b8 ("epoll: Keep a reference on files added to the check list")
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
CVE: CVE-2021-1048
CWE: CWE-416
Vulnerability description: In ep_loop_check_proc of eventpoll.c, there is a possible way to corrupt memory due to a use after free. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.Product: AndroidVersions: Android kernelAndroid ID: A-204573007References: Upstream kernel

Project: linux
File: eventpoll.c

static int ep_loop_check_proc(void *priv, void *cookie, int call_nests)
{
	int error = 0;
	struct file *file = priv;
	struct eventpoll *ep = file->private_data;
	struct eventpoll *ep_tovisit;
	struct rb_node *rbp;
	struct epitem *epi;

	mutex_lock_nested(&ep->mtx, call_nests + 1);
	ep->visited = 1;
	list_add(&ep->visited_list_link, &visited_list);
	for (rbp = rb_first_cached(&ep->rbr); rbp; rbp = rb_next(rbp)) {
		epi = rb_entry(rbp, struct epitem, rbn);
		if (unlikely(is_file_epoll(epi->ffd.file))) {
			ep_tovisit = epi->ffd.file->private_data;
			if (ep_tovisit->visited)
				continue;
			error = ep_call_nested(&poll_loop_ncalls,
					ep_loop_check_proc, epi->ffd.file,
					ep_tovisit, current);
			if (error != 0)
				break;
		} else {
			/*
			 * If we've reached a file that is not associated with
			 * an ep, then we need to check if the newly added
			 * links are going to add too many wakeup paths. We do
			 * this by adding it to the tfile_check_list, if it's
			 * not already there, and calling reverse_path_check()
			 * during ep_insert().
			 */
			if (list_empty(&epi->ffd.file->f_tfile_llink)) {
				if (get_file_rcu(epi->ffd.file))
					list_add(&epi->ffd.file->f_tfile_llink,
						 &tfile_check_list);
			}
		}
	}
	mutex_unlock(&ep->mtx);

	return error;
}
Commit message: TRQ-2885 - clean up unit test so it passes when run as root
CVE: CVE-2014-3684
CWE: CWE-264
Vulnerability description: The tm_adopt function in lib/Libifl/tm.c in Terascale Open-Source Resource and Queue Manager (aka TORQUE Resource Manager) 5.0.x, 4.5.x, 4.2.x, and earlier does not validate that the owner of the process also owns the adopted session id, which allows remote authenticated users to kill arbitrary processes via a crafted executable.

Project: torque
File: test_tm.c

int fake_tm_init(

  void             *info,  /* in, currently unused */
  struct  tm_roots *roots) /* out */

  {
  tm_event_t  nevent, revent;
  /*char   *env, *hold;*/
  /*int   err;*/
  int   nerr = 0;
  /*struct tcp_chan *chan = NULL;*/

  init_done = 1;

  nevent = new_event();

  add_event(nevent, TM_ERROR_NODE, TM_INIT, (void *)roots);
  tm_poll(TM_NULL_EVENT, &revent, 1, &nerr);
  return(0);
  }

Project: torque
File: test_tm.c

START_TEST(test_tm_poll_bad_init)
  {
  fail_unless(TM_BADINIT == tm_poll(0, 0, 0, 0), "expected poll to return TM_BADINIT if no init called first.");
  }

Project: torque
File: test_tm.c

START_TEST(test_tm_adopt_ispidowner)
  {
  /* we are the owner of this pid so should return true */
  fail_unless(TRUE == ispidowner(getpid()));

  /* when unit test run as non-root user, owner of this pid is not the owner of pid 1 (init) */
  if (getuid() != 0)
    fail_unless(FALSE == ispidowner(1));
  }

Project: torque
File: test_tm.c

int main(void)
  {
  int number_failed = 0;
  SRunner *sr = NULL;
  rundebug();
  sr = srunner_create(tm_suite());
  srunner_set_log(sr, "tm_suite.log");
  srunner_run_all(sr, CK_NORMAL);
  number_failed = srunner_ntests_failed(sr);
  srunner_free(sr);
  return number_failed;
  }

Project: torque
File: test_tm.c

void rundebug()
  {
  }

Project: torque
File: test_tm.c

START_TEST(test_tm_poll_bad_result)
  {
  struct tm_roots roots;
  fake_tm_init(NULL, &roots);
  fail_unless(TM_EBADENVIRONMENT == tm_poll(0, 0, 0, 0), "expected poll to return TM_BADINIT if no init called first.");
  }

Project: torque
File: test_tm.c

Suite *tm_suite(void)
  {
  Suite *s = suite_create("tm_suite methods");
  TCase * tc = tcase_create("tm");

  tcase_add_test(tc, test_tm_poll_bad_init);
  tcase_add_test(tc, test_tm_poll_bad_result);
  tcase_add_test(tc, test_tm_adopt_ispidowner);
  
  suite_add_tcase(s, tc);
  return s;
  }
Commit message: Fixes to avoid a timing attack in TLS CBC record parsing.
CVE: CVE-2013-0169
CWE: CWE-310
Vulnerability description: The TLS protocol 1.1 and 1.2 and the DTLS protocol 1.0 and 1.2, as used in OpenSSL, OpenJDK, PolarSSL, and other products, do not properly consider timing side-channel attacks on a MAC check requirement during the processing of malformed CBC padding, which allows remote attackers to conduct distinguishing attacks and plaintext-recovery attacks via statistical analysis of timing data for crafted packets, aka the "Lucky Thirteen" issue.

Project: gnutls
File: gnutls_hash_int.h

_gnutls_get_hash_block_len (gnutls_digest_algorithm_t algo)
{
  switch (algo)
    {
    case GNUTLS_DIG_MD5:
    case GNUTLS_DIG_SHA1:
    case GNUTLS_DIG_RMD160:
    case GNUTLS_DIG_SHA256:
    case GNUTLS_DIG_SHA384:
    case GNUTLS_DIG_SHA512:
    case GNUTLS_DIG_SHA224:
      return 64;
    default:
      return 0;
    }
}
Commit message: Prevent infinite recursion with nested table and textarea

Bug-Debian: https://github.com/tats/w3m/issues/20
CVE: CVE-2016-9439
CWE: CWE-119
Vulnerability description: An issue was discovered in the Tatsuya Kinoshita w3m fork before 0.5.3-31. Infinite recursion vulnerability in w3m allows remote attackers to cause a denial of service via a crafted HTML page.

Project: w3m
File: table.c

renderCoTable(struct table *tbl, int maxlimit)
{
    struct readbuffer obuf;
    struct html_feed_environ h_env;
    struct environment envs[MAX_ENV_LEVEL];
    struct table *t;
    int i, col, row;
    int indent, maxwidth;
    static struct table *tbl_prev = NULL;
    static int cotbl_count;
#define MAX_COTABLE 100

    if (tbl == NULL)
	return;
    if (tbl != tbl_prev) {
	tbl_prev = tbl;
	cotbl_count = 0;
    }
    if (cotbl_count >= MAX_COTABLE)
	return;	/* workaround to prevent infinite recursion */
    cotbl_count++;

    for (i = 0; i < tbl->ntable; i++) {
	t = tbl->tables[i].ptr;
	col = tbl->tables[i].col;
	row = tbl->tables[i].row;
	indent = tbl->tables[i].indent;

	init_henv(&h_env, &obuf, envs, MAX_ENV_LEVEL, tbl->tables[i].buf,
		  get_spec_cell_width(tbl, row, col), indent);
	check_row(tbl, row);
	if (h_env.limit > maxlimit)
	    h_env.limit = maxlimit;
	if (t->total_width == 0)
	    maxwidth = h_env.limit - indent;
	else if (t->total_width > 0)
	    maxwidth = t->total_width;
	else
	    maxwidth = t->total_width = -t->total_width * h_env.limit / 100;
	renderTable(t, maxwidth, &h_env);
    }
}
Commit message: powerpc: Ensure random space between stack and mmaps

get_random_int() returns the same value within a 1 jiffy interval. This means
that the mmap and stack regions will almost always end up the same distance
apart, making a relative offset based attack possible.

To fix this, shift the randomness we use for the mmap region by 1 bit.

Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CVE: None
Vulnerability description: None

Project: linux

static inline unsigned long mmap_base(void)
{
	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;

	if (gap < MIN_GAP)
		gap = MIN_GAP;
	else if (gap > MAX_GAP)
		gap = MAX_GAP;

	return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
}

Project: linux

static inline int mmap_is_legacy(void)
{
	if (current->personality & ADDR_COMPAT_LAYOUT)
		return 1;

	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
		return 1;

	return sysctl_legacy_va_layout;
}
Commit message: Fix yet another buffer overflow in the braille table parser

Reported by Henri Salo

Fixes #592
CVE: CVE-2018-11684
CWE: CWE-787
Vulnerability description: Liblouis 3.5.0 has a stack-based Buffer Overflow in the function includeFile in compileTranslationTable.c.

Project: liblouis
File: compileTranslationTable.c

_lou_getTablePath() {
	char searchPath[MAXSTRING];
	char *path;
	char *cp;
	cp = searchPath;
	path = getenv("LOUIS_TABLEPATH");
	if (path != NULL && path[0] != '\0') cp += sprintf(cp, ",%s", path);
	path = lou_getDataPath();
	if (path != NULL && path[0] != '\0')
		cp += sprintf(cp, ",%s%c%s%c%s", path, DIR_SEP, "liblouis", DIR_SEP, "tables");
#ifdef _WIN32
	path = lou_getProgramPath();
	if (path != NULL) {
		if (path[0] != '\0')
			cp += sprintf(cp, ",%s%s", path, "\\share\\liblouis\\tables");
		free(path);
	}
#else
	cp += sprintf(cp, ",%s", TABLESDIR);
#endif
	if (searchPath[0] != '\0')
		return strdup(&searchPath[1]);
	else
		return strdup(".");
}

Project: liblouis
File: compileTranslationTable.c

compileBrailleIndicator(FileInfo *nested, char *ermsg, TranslationTableOpcode opcode,
		TranslationTableOffset *rule, int *lastToken,
		TranslationTableOffset *newRuleOffset, TranslationTableRule **newRule, int noback,
		int nofor, TranslationTableHeader **table) {
	CharsString token;
	CharsString cells;
	if (getToken(nested, &token, ermsg, lastToken))
		if (parseDots(nested, &cells, &token))
			if (!addRule(nested, opcode, NULL, &cells, 0, 0, newRuleOffset, newRule,
						noback, nofor, table))
				return 0;
	*rule = *newRuleOffset;
	return 1;
}

Project: liblouis
File: compileTranslationTable.c

compileWarning(FileInfo *nested, char *format, ...) {
#ifndef __SYMBIAN32__
	char buffer[MAXSTRING];
	va_list arguments;
	va_start(arguments, format);
	vsnprintf(buffer, sizeof(buffer), format, arguments);
	va_end(arguments);
	if (nested)
		_lou_logMessage(LOG_WARN, "%s:%d: warning: %s", nested->fileName,
				nested->lineNumber, buffer);
	else
		_lou_logMessage(LOG_WARN, "warning: %s", buffer);
	warningCount++;
#endif
}

Project: liblouis
File: compileTranslationTable.c

_lou_findOpcodeName(TranslationTableOpcode opcode) {
	static char scratchBuf[MAXSTRING];
	/* Used by tools such as lou_debug */
	if (opcode < 0 || opcode >= CTO_None) {
		sprintf(scratchBuf, "%d", opcode);
		return scratchBuf;
	}
	return opcodeNames[opcode];
}

Project: liblouis
File: compileTranslationTable.c

compileError(FileInfo *nested, char *format, ...) {
#ifndef __SYMBIAN32__
	char buffer[MAXSTRING];
	va_list arguments;
	va_start(arguments, format);
	vsnprintf(buffer, sizeof(buffer), format, arguments);
	va_end(arguments);
	if (nested)
		_lou_logMessage(LOG_ERROR, "%s:%d: error: %s", nested->fileName,
				nested->lineNumber, buffer);
	else
		_lou_logMessage(LOG_ERROR, "error: %s", buffer);
	errorCount++;
#endif
}
Commit message: exec: Limit arg stack to at most 75% of _STK_LIM

To avoid pathological stack usage or the need to special-case setuid
execs, just limit all arg stack usage to at most 75% of _STK_LIM (6MB).

Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
CVE: CVE-2018-14634
Vulnerability description: An integer overflow flaw was found in the Linux kernel's create_elf_tables() function. An unprivileged local user with access to SUID (or otherwise privileged) binary could use this flaw to escalate their privileges on the system. Kernel versions 2.6.x, 3.10.x and 4.14.x are believed to be vulnerable.

Project: linux
File: exec.c

static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
		int write)
{
	struct page *page;
	int ret;
	unsigned int gup_flags = FOLL_FORCE;

#ifdef CONFIG_STACK_GROWSUP
	if (write) {
		ret = expand_downwards(bprm->vma, pos);
		if (ret < 0)
			return NULL;
	}
#endif

	if (write)
		gup_flags |= FOLL_WRITE;

	/*
	 * We are doing an exec().  'current' is the process
	 * doing the exec and bprm->mm is the new process's mm.
	 */
	ret = get_user_pages_remote(current, bprm->mm, pos, 1, gup_flags,
			&page, NULL, NULL);
	if (ret <= 0)
		return NULL;

	if (write) {
		unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
		unsigned long ptr_size, limit;

		/*
		 * Since the stack will hold pointers to the strings, we
		 * must account for them as well.
		 *
		 * The size calculation is the entire vma while each arg page is
		 * built, so each time we get here it's calculating how far it
		 * is currently (rather than each call being just the newly
		 * added size from the arg page).  As a result, we need to
		 * always add the entire size of the pointers, so that on the
		 * last call to get_arg_page() we'll actually have the entire
		 * correct size.
		 */
		ptr_size = (bprm->argc + bprm->envc) * sizeof(void *);
		if (ptr_size > ULONG_MAX - size)
			goto fail;
		size += ptr_size;

		acct_arg_size(bprm, size / PAGE_SIZE);

		/*
		 * We've historically supported up to 32 pages (ARG_MAX)
		 * of argument strings even with small stacks
		 */
		if (size <= ARG_MAX)
			return page;

		/*
		 * Limit to 1/4 of the max stack size or 3/4 of _STK_LIM
		 * (whichever is smaller) for the argv+env strings.
		 * This ensures that:
		 *  - the remaining binfmt code will not run out of stack space,
		 *  - the program will have a reasonable amount of stack left
		 *    to work from.
		 */
		limit = _STK_LIM / 4 * 3;
		limit = min(limit, rlimit(RLIMIT_STACK) / 4);
		if (size > limit)
			goto fail;
	}

	return page;

fail:
	put_page(page);
	return NULL;
}