From patchwork Mon Oct 26 15:01:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 40874 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 61F933939C37; Mon, 26 Oct 2020 15:01:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 61F933939C37 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1603724495; bh=34Iw4i9rPrQCJJKQMjMsaI6qhO/glNwV9YzDgu9zuLM=; h=Subject:To:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=v/6NjJLrnsfxp0yOXwhvPEyJNL1ZNdZx9GXOom5GBJegOcl7XqspeIdtCbskqzK5a 3PHuw5LzqvjkXztEIUsLMt8uz2oFK/vHyPennUBObbHRVEOn2qsAreveT/0KmW387s KxmWZ39x0dYeJkaUfklK/QvyH30QZebcWwjcZC4I= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ot1-x333.google.com (mail-ot1-x333.google.com [IPv6:2607:f8b0:4864:20::333]) by sourceware.org (Postfix) with ESMTPS id 279AE385782D for ; Mon, 26 Oct 2020 15:01:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 279AE385782D Received: by mail-ot1-x333.google.com with SMTP id k68so8226736otk.10 for ; Mon, 26 Oct 2020 08:01:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:subject:to:message-id:date:user-agent :mime-version:content-language; bh=34Iw4i9rPrQCJJKQMjMsaI6qhO/glNwV9YzDgu9zuLM=; b=oEJJEFCy2NBc2M519aHOLKR5pjaek7CQYotLXwBTkUwen74VK6EAVW7Dkc3U6YB0KZ vJ08WSGla/n+Vfb28WdJwtQZ1yylirGz/hB4FsYQ9RV0k5z4Zoq7do2sVhwJbdBPkPDp k9COofq5KcPaVUj8Nu7wE3Dd/hczWjeil7qRxFM4nR+b5eJJWvie72T87wES1ag7AWsP HUcZQKCcovumow9K4i+M6Qz8o2buzfU5mgz5hOdjtAs9/H4Xmoy90ZhIcrApIVov83dg ta3J7pJZKoaZlDZ8tj1YBsO/0xq1y6QLzpahSt4GQUILO7BpGQMukmWj83rlRNLwLNyV cOVQ== X-Gm-Message-State: AOAM530+FjvrQxTBkpvYTEodYnLPzFste0IdqGWdvm5sZUt1+q+bnTt+ 9KMr4rk5xF9Pur0BTAV6iVyGsXPgIzw= X-Google-Smtp-Source: ABdhPJyKRIsJgdSirR6tH5lnyKsWn06WNfpZUeNpGtEYQRExfvzsKT2U2F4u+lH4bipFftAlEdXRHQ== X-Received: by 2002:a9d:6307:: with SMTP id q7mr14122126otk.218.1603724489575; Mon, 26 Oct 2020 08:01:29 -0700 (PDT) Received: from [192.168.0.41] (174-16-106-146.hlrn.qwest.net. [174.16.106.146]) by smtp.gmail.com with ESMTPSA id 98sm3508064otm.54.2020.10.26.08.01.28 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 26 Oct 2020 08:01:28 -0700 (PDT) Subject: [PATCH] more out of bounds checking improvements To: GNU C Library Message-ID: <176ba75f-4299-073f-8319-66dbf9fe3f42@gmail.com> Date: Mon, 26 Oct 2020 09:01:24 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Martin Sebor via Libc-alpha From: Martin Sebor Reply-To: Martin Sebor Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" The attached patch continues the improvements to out of bounds checking(*) by decorating more APIs with either attribute access, or by explicitly providing the array bound in APIs such as tmpnam() that expect arrays of some minimum size as arguments. (The latter feature is new in GCC 11.) The only effects of the attribute and/or the array bound is to check and diagnose calls to the functions that fail to provide a sufficient number of elements, and the definitions of the functions that access elements outside the specified bounds. (There is no interplay with _FORTIFY_SOURCE here yet.) For example, because the patch specifies the bound in the tmpnam declaration like so: extern char *tmpnam (char[L_tmpnam]) __THROW __wur; the following call to the function: char* warn_tmpnam (void) { char a[16]; return tmpnam (a); } triggers the warning below: t.c: In function ‘warn_tmpnam’: t.c:8:10: warning: ‘tmpnam’ accessing 20 bytes in a region of size 16 [-Wstringop-overflow=] 8 | return tmpnam (a); | ^~~~~~~~~~ t.c:8:10: note: referencing argument 1 of type ‘char *’ In file included from ../include/stdio.h:14, from test-access-warn.c:1: ../libio/stdio.h:187:14: note: in a call to function ‘tmpnam’ 187 | extern char *tmpnam (char[L_tmpnam]) __THROW __wur; | ^~~~~~ Unlike the [static N] notation, the plain array notation doesn't require the argument to be nonnull. Besides attribute access, the change adds attribute nonnull to the readv and writev functions in misc/sys/uio.h. The functions don't necessarily access the array elements when their count is zero but neither POSIX nor the Linux manual document this so it seems appropriate to warn. The patch introduces the _L_tmpnam macro to avoid polluting the POSIX namespace with L_tmpnam when the latter is only supposed to be defined in . This in turn causes the a number of POSIX conformance test failures that I haven't been able to figure how to deal with and need some help with. In file included from ../include/unistd.h:2, from /tmp/tmpzm39v4n3/test.c:1: ../posix/unistd.h:1159:32: error: ‘_L_ctermid’ undeclared here (not in a function) extern char *ctermid (char __s[_L_ctermid]) __THROW ^~~~~~~~~~ I expected adding the new macros to stdio-common/stdio_lim.h.in would do the trick but clearly something else is needed and I'm at a lost as to what that might be. I haven't been able to find my way out of the maze of scripts and makefiles that tie all this together. Thanks Martin [*] https://sourceware.org/pipermail/libc-alpha/2020-April/113503.html diff --git a/inet/if_index.c b/inet/if_index.c index ddef419230..36f1806ac1 100644 --- a/inet/if_index.c +++ b/inet/if_index.c @@ -31,7 +31,7 @@ libc_hidden_weak (if_nametoindex) stub_warning (if_nametoindex) char * -__if_indextoname (unsigned int ifindex, char *ifname) +__if_indextoname (unsigned int ifindex, char ifname[IF_NAMESIZE]) { __set_errno (ENOSYS); return NULL; diff --git a/io/bits/poll2.h b/io/bits/poll2.h index dca49717db..8cbedb7542 100644 --- a/io/bits/poll2.h +++ b/io/bits/poll2.h @@ -26,13 +26,14 @@ __BEGIN_DECLS extern int __REDIRECT (__poll_alias, (struct pollfd *__fds, nfds_t __nfds, int __timeout), poll); extern int __poll_chk (struct pollfd *__fds, nfds_t __nfds, int __timeout, - __SIZE_TYPE__ __fdslen); + __SIZE_TYPE__ __fdslen) + __attr_access ((__write_only__, 1, 2)); extern int __REDIRECT (__poll_chk_warn, (struct pollfd *__fds, nfds_t __nfds, int __timeout, __SIZE_TYPE__ __fdslen), __poll_chk) __warnattr ("poll called with fds buffer too small file nfds entries"); -__fortify_function int +__fortify_function __attr_access ((__write_only__, 1, 2)) int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) { if (__bos (__fds) != (__SIZE_TYPE__) -1) @@ -53,7 +54,8 @@ extern int __REDIRECT (__ppoll_alias, (struct pollfd *__fds, nfds_t __nfds, const __sigset_t *__ss), ppoll); extern int __ppoll_chk (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout, - const __sigset_t *__ss, __SIZE_TYPE__ __fdslen); + const __sigset_t *__ss, __SIZE_TYPE__ __fdslen) + __attr_access ((__write_only__, 1, 2)); extern int __REDIRECT (__ppoll_chk_warn, (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout, const __sigset_t *__ss, @@ -61,7 +63,7 @@ extern int __REDIRECT (__ppoll_chk_warn, (struct pollfd *__fds, nfds_t __nfds, __ppoll_chk) __warnattr ("ppoll called with fds buffer too small file nfds entries"); -__fortify_function int +__fortify_function __attr_access ((__write_only__, 1, 2)) int ppoll (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout, const __sigset_t *__ss) { diff --git a/io/sys/poll.h b/io/sys/poll.h index 857be0f5ac..aa145a1737 100644 --- a/io/sys/poll.h +++ b/io/sys/poll.h @@ -51,7 +51,8 @@ __BEGIN_DECLS This function is a cancellation point and therefore not marked with __THROW. */ -extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout); +extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) + __attr_access ((__write_only__, 1, 2)); #ifdef __USE_GNU /* Like poll, but before waiting the threads signal mask is replaced @@ -62,7 +63,9 @@ extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout); __THROW. */ extern int ppoll (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout, - const __sigset_t *__ss); + const __sigset_t *__ss) + __attr_access ((__write_only__, 1, 2)); + #endif __END_DECLS diff --git a/libio/stdio.h b/libio/stdio.h index 998470943e..59f2ee01ab 100644 --- a/libio/stdio.h +++ b/libio/stdio.h @@ -184,12 +184,12 @@ extern FILE *tmpfile64 (void) __wur; #endif /* Generate a temporary filename. */ -extern char *tmpnam (char *__s) __THROW __wur; +extern char *tmpnam (char[L_tmpnam]) __THROW __wur; #ifdef __USE_MISC /* This is the reentrant variant of `tmpnam'. The only difference is that it does not allow S to be NULL. */ -extern char *tmpnam_r (char *__s) __THROW __wur; +extern char *tmpnam_r (char __s[L_tmpnam]) __THROW __wur; #endif @@ -808,13 +808,13 @@ extern int pclose (FILE *__stream); #ifdef __USE_POSIX /* Return the name of the controlling terminal. */ -extern char *ctermid (char *__s) __THROW; +extern char *ctermid (char __s[_L_ctermid]) __THROW; #endif /* Use POSIX. */ #if (defined __USE_XOPEN && !defined __USE_XOPEN2K) || defined __USE_GNU /* Return the name of the current user. */ -extern char *cuserid (char *__s); +extern char *cuserid (char __s[_L_cuserid]); #endif /* Use X/Open, but not issue 6. */ diff --git a/misc/sys/uio.h b/misc/sys/uio.h index 26d87c9f34..04ad46d705 100644 --- a/misc/sys/uio.h +++ b/misc/sys/uio.h @@ -39,7 +39,7 @@ __BEGIN_DECLS This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t readv (int __fd, const struct iovec *__iovec, int __count) - __wur; + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); /* Write data pointed by the buffers described by IOVEC, which is a vector of COUNT 'struct iovec's, to file descriptor FD. @@ -50,7 +50,7 @@ extern ssize_t readv (int __fd, const struct iovec *__iovec, int __count) This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t writev (int __fd, const struct iovec *__iovec, int __count) - __wur; + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); #ifdef __USE_MISC @@ -65,7 +65,8 @@ extern ssize_t writev (int __fd, const struct iovec *__iovec, int __count) This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t preadv (int __fd, const struct iovec *__iovec, int __count, - __off_t __offset) __wur; + __off_t __offset) + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); /* Write data pointed by the buffers described by IOVEC, which is a vector of COUNT 'struct iovec's, to file descriptor FD at the given @@ -77,16 +78,19 @@ extern ssize_t preadv (int __fd, const struct iovec *__iovec, int __count, This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t pwritev (int __fd, const struct iovec *__iovec, int __count, - __off_t __offset) __wur; + __off_t __offset) + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); # else # ifdef __REDIRECT extern ssize_t __REDIRECT (preadv, (int __fd, const struct iovec *__iovec, int __count, __off64_t __offset), - preadv64) __wur; + preadv64) + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); extern ssize_t __REDIRECT (pwritev, (int __fd, const struct iovec *__iovec, int __count, __off64_t __offset), - pwritev64) __wur; + pwritev64) + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); # else # define preadv preadv64 # define pwritev pwritev64 @@ -104,7 +108,8 @@ extern ssize_t __REDIRECT (pwritev, (int __fd, const struct iovec *__iovec, This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t preadv64 (int __fd, const struct iovec *__iovec, int __count, - __off64_t __offset) __wur; + __off64_t __offset) + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); /* Write data pointed by the buffers described by IOVEC, which is a vector of COUNT 'struct iovec's, to file descriptor FD at the given @@ -116,7 +121,8 @@ extern ssize_t preadv64 (int __fd, const struct iovec *__iovec, int __count, This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t pwritev64 (int __fd, const struct iovec *__iovec, int __count, - __off64_t __offset) __wur; + __off64_t __offset) + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); # endif #endif /* Use misc. */ @@ -125,7 +131,8 @@ extern ssize_t pwritev64 (int __fd, const struct iovec *__iovec, int __count, # ifndef __USE_FILE_OFFSET64 /* Same as preadv but with an additional flag argumenti defined at uio.h. */ extern ssize_t preadv2 (int __fp, const struct iovec *__iovec, int __count, - __off_t __offset, int ___flags) __wur; + __off_t __offset, int ___flags) + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); /* Same as preadv but with an additional flag argument defined at uio.h. */ extern ssize_t pwritev2 (int __fd, const struct iovec *__iodev, int __count, @@ -136,11 +143,13 @@ extern ssize_t pwritev2 (int __fd, const struct iovec *__iodev, int __count, extern ssize_t __REDIRECT (pwritev2, (int __fd, const struct iovec *__iovec, int __count, __off64_t __offset, int __flags), - pwritev64v2) __wur; + pwritev64v2) + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); extern ssize_t __REDIRECT (preadv2, (int __fd, const struct iovec *__iovec, int __count, __off64_t __offset, int __flags), - preadv64v2) __wur; + preadv64v2) + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); # else # define preadv2 preadv64v2 # define pwritev2 pwritev64v2 @@ -151,12 +160,14 @@ extern ssize_t __REDIRECT (preadv2, (int __fd, const struct iovec *__iovec, /* Same as preadv but with an additional flag argumenti defined at uio.h. */ extern ssize_t preadv64v2 (int __fp, const struct iovec *__iovec, int __count, __off64_t __offset, - int ___flags) __wur; + int ___flags) + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); /* Same as preadv but with an additional flag argument defined at uio.h. */ extern ssize_t pwritev64v2 (int __fd, const struct iovec *__iodev, int __count, __off64_t __offset, - int __flags) __wur; + int __flags) + __wur __attr_access ((__read_only__, 2, 3)) __nonnull ((2)); # endif #endif /* Use GNU. */ diff --git a/posix/regex.h b/posix/regex.h index 5fe41c8685..75c9201fc6 100644 --- a/posix/regex.h +++ b/posix/regex.h @@ -536,7 +536,8 @@ extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax); 'regcomp', with a malloc'ed value, or set to NULL before calling 'regfree'. */ extern const char *re_compile_pattern (const char *__pattern, size_t __length, - struct re_pattern_buffer *__buffer); + struct re_pattern_buffer *__buffer) + __attr_access ((__read_only__, 1, 2)); /* Compile a fastmap for the compiled pattern in BUFFER; used to @@ -553,7 +554,8 @@ extern int re_compile_fastmap (struct re_pattern_buffer *__buffer); extern regoff_t re_search (struct re_pattern_buffer *__buffer, const char *__String, regoff_t __length, regoff_t __start, regoff_t __range, - struct re_registers *__regs); + struct re_registers *__regs) + __attr_access ((__read_only__, 2, 3)); /* Like 're_search', but search in the concatenation of STRING1 and @@ -563,14 +565,17 @@ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer, const char *__string2, regoff_t __length2, regoff_t __start, regoff_t __range, struct re_registers *__regs, - regoff_t __stop); + regoff_t __stop) + __attr_access ((__read_only__, 2, 3)) + __attr_access ((__read_only__, 4, 5)); /* Like 're_search', but return how many characters in STRING the regexp in BUFFER matched, starting at position START. */ extern regoff_t re_match (struct re_pattern_buffer *__buffer, const char *__String, regoff_t __length, - regoff_t __start, struct re_registers *__regs); + regoff_t __start, struct re_registers *__regs) + __attr_access ((__read_only__, 2, 3)); /* Relates to 're_match' as 're_search_2' relates to 're_search'. */ @@ -578,7 +583,9 @@ extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer, const char *__string1, regoff_t __length1, const char *__string2, regoff_t __length2, regoff_t __start, struct re_registers *__regs, - regoff_t __stop); + regoff_t __stop) + __attr_access ((__read_only__, 2, 3)) + __attr_access ((__read_only__, 4, 5)); /* Set REGS to hold NUM_REGS registers, storing them in STARTS and @@ -641,10 +648,12 @@ extern int regcomp (regex_t *_Restrict_ __preg, extern int regexec (const regex_t *_Restrict_ __preg, const char *_Restrict_ __String, size_t __nmatch, regmatch_t __pmatch[_Restrict_arr_], - int __eflags); + int __eflags) + __attr_access ((__write_only__, 4, 3)); extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, - char *_Restrict_ __errbuf, size_t __errbuf_size); + char *_Restrict_ __errbuf, size_t __errbuf_size) + __attr_access ((__write_only__, 3, 4)); extern void regfree (regex_t *__preg); diff --git a/posix/unistd.h b/posix/unistd.h index 32b8161619..0eb79fb6ce 100644 --- a/posix/unistd.h +++ b/posix/unistd.h @@ -1156,10 +1156,12 @@ extern void swab (const void *__restrict __from, void *__restrict __to, . */ #if defined __USE_XOPEN && !defined __USE_XOPEN2K /* Return the name of the controlling terminal. */ -extern char *ctermid (char *__s) __THROW; +extern char *ctermid (char __s[_L_ctermid]) __THROW + __attr_access ((__write_only__, 1)); /* Return the name of the current user. */ -extern char *cuserid (char *__s); +extern char *cuserid (char __s[_L_cuserid]) + __attr_access ((__write_only__, 1)) #endif diff --git a/pwd/pwd.h b/pwd/pwd.h index bbc29479cd..065a19bade 100644 --- a/pwd/pwd.h +++ b/pwd/pwd.h @@ -139,20 +139,23 @@ extern struct passwd *getpwnam (const char *__name) __nonnull ((1)); extern int getpwent_r (struct passwd *__restrict __resultbuf, char *__restrict __buffer, size_t __buflen, struct passwd **__restrict __result) - __nonnull ((1, 2, 4)); + __nonnull ((1, 2, 4)) + __attr_access ((__write_only__, 2, 3)); # endif extern int getpwuid_r (__uid_t __uid, struct passwd *__restrict __resultbuf, char *__restrict __buffer, size_t __buflen, struct passwd **__restrict __result) - __nonnull ((2, 3, 5)); + __nonnull ((2, 3, 5)) + __attr_access ((__write_only__, 3, 4)); extern int getpwnam_r (const char *__restrict __name, struct passwd *__restrict __resultbuf, char *__restrict __buffer, size_t __buflen, struct passwd **__restrict __result) - __nonnull ((1, 2, 3, 5)); + __nonnull ((1, 2, 3, 5)) + __attr_access ((__write_only__, 3, 4)); # ifdef __USE_MISC @@ -167,7 +170,8 @@ extern int fgetpwent_r (FILE *__restrict __stream, struct passwd *__restrict __resultbuf, char *__restrict __buffer, size_t __buflen, struct passwd **__restrict __result) - __nonnull ((1, 2, 3, 5)); + __nonnull ((1, 2, 3, 5)) + __attr_access ((__write_only__, 3, 4)); # endif #endif /* POSIX or reentrant */ diff --git a/stdio-common/cuserid.c b/stdio-common/cuserid.c index d4f1861c99..578887e82b 100644 --- a/stdio-common/cuserid.c +++ b/stdio-common/cuserid.c @@ -22,7 +22,7 @@ If S is not NULL, it points to a buffer of at least L_cuserid bytes into which the name is copied; otherwise, a static buffer is used. */ char * -cuserid (char *s) +cuserid (char s[L_cuserid]) { __set_errno (ENOSYS); return NULL; diff --git a/stdio-common/stdio_lim.h.in b/stdio-common/stdio_lim.h.in index de0caa5fee..9e3c59c942 100644 --- a/stdio-common/stdio_lim.h.in +++ b/stdio-common/stdio_lim.h.in @@ -26,6 +26,9 @@ #define TMP_MAX @TMP_MAX@ #define FILENAME_MAX @FILENAME_MAX@ +#define _L_ctermid @L_ctermid@ +#define _L_cuserid @L_cuserid@ + #ifdef __USE_POSIX # define L_ctermid @L_ctermid@ # if !defined __USE_XOPEN2K || defined __USE_GNU diff --git a/stdio-common/tmpnam.c b/stdio-common/tmpnam.c index a8e0ca5b3b..cdd64e1d54 100644 --- a/stdio-common/tmpnam.c +++ b/stdio-common/tmpnam.c @@ -24,7 +24,7 @@ static char tmpnam_buffer[L_tmpnam]; This function is *not* thread safe! */ char * -tmpnam (char *s) +tmpnam (char s[L_tmpnam]) { /* By using two buffers we manage to be thread safe in the case where S != NULL. */ diff --git a/stdio-common/tmpnam_r.c b/stdio-common/tmpnam_r.c index 49f762f392..e359e4808a 100644 --- a/stdio-common/tmpnam_r.c +++ b/stdio-common/tmpnam_r.c @@ -20,7 +20,7 @@ /* Generate a unique filename in P_tmpdir. If S is NULL return NULL. This makes this function thread safe. */ char * -tmpnam_r (char *s) +tmpnam_r (char s[L_tmpnam]) { if (s == NULL) return NULL; diff --git a/stdlib/monetary.h b/stdlib/monetary.h index c9d3c64e14..37ee8ab6d2 100644 --- a/stdlib/monetary.h +++ b/stdlib/monetary.h @@ -37,7 +37,8 @@ __BEGIN_DECLS /* Formatting a monetary value according to the current locale. */ extern ssize_t strfmon (char *__restrict __s, size_t __maxsize, const char *__restrict __format, ...) - __THROW __attribute_format_strfmon__ (3, 4); + __THROW __attribute_format_strfmon__ (3, 4) + __attr_access ((__write_only__, 1, 2)); #ifdef __USE_XOPEN2K8 /* POSIX.1-2008 extended locale interface (see locale.h). */ @@ -47,7 +48,8 @@ extern ssize_t strfmon (char *__restrict __s, size_t __maxsize, extern ssize_t strfmon_l (char *__restrict __s, size_t __maxsize, locale_t __loc, const char *__restrict __format, ...) - __THROW __attribute_format_strfmon__ (4, 5); + __THROW __attribute_format_strfmon__ (4, 5) + __attr_access ((__write_only__, 1, 2)); #endif #include diff --git a/sysdeps/gnu/net/if.h b/sysdeps/gnu/net/if.h index e587a5ce59..30f3e281e5 100644 --- a/sysdeps/gnu/net/if.h +++ b/sysdeps/gnu/net/if.h @@ -191,7 +191,9 @@ __BEGIN_DECLS /* Convert an interface name to an index, and vice versa. */ extern unsigned int if_nametoindex (const char *__ifname) __THROW; -extern char *if_indextoname (unsigned int __ifindex, char *__ifname) __THROW; +extern char *if_indextoname (unsigned int __ifindex, + char __ifname[IF_NAMESIZE]) __THROW + __attr_access ((__write_only__, 2)); /* Return a list of all interfaces and their indices. */ extern struct if_nameindex *if_nameindex (void) __THROW; diff --git a/sysdeps/mach/hurd/if_index.c b/sysdeps/mach/hurd/if_index.c index 32dceccdbf..f92cd5723a 100644 --- a/sysdeps/mach/hurd/if_index.c +++ b/sysdeps/mach/hurd/if_index.c @@ -166,7 +166,7 @@ libc_hidden_weak (if_nameindex) IFNAME (which has space for at least IFNAMSIZ characters). Return IFNAME, or NULL on error. */ char * -__if_indextoname (unsigned int ifindex, char *ifname) +__if_indextoname (unsigned int ifindex, char ifname[IF_NAMESIZE]) { struct ifreq ifr; int fd = __opensock (); diff --git a/sysdeps/posix/ctermid.c b/sysdeps/posix/ctermid.c index 49f3f08a6f..4112cb0f2f 100644 --- a/sysdeps/posix/ctermid.c +++ b/sysdeps/posix/ctermid.c @@ -24,7 +24,7 @@ long), otherwise we return a pointer to a non-const but read-only string literal, that POSIX states the caller must not modify. */ char * -ctermid (char *s) +ctermid (char s[L_ctermid]) { char *name = (char /*drop const*/ *) "/dev/tty"; diff --git a/sysdeps/posix/cuserid.c b/sysdeps/posix/cuserid.c index 401b100333..213802f0f9 100644 --- a/sysdeps/posix/cuserid.c +++ b/sysdeps/posix/cuserid.c @@ -25,7 +25,7 @@ If S is not NULL, it points to a buffer of at least L_cuserid bytes into which the name is copied; otherwise, a static buffer is used. */ char * -cuserid (char *s) +cuserid (char s[L_cuserid]) { static char name[L_cuserid]; char buf[NSS_BUFLEN_PASSWD]; diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c index dffa363931..5509da2c21 100644 --- a/sysdeps/unix/sysv/linux/if_index.c +++ b/sysdeps/unix/sysv/linux/if_index.c @@ -215,7 +215,7 @@ libc_hidden_weak (if_nameindex) char * -__if_indextoname (unsigned int ifindex, char *ifname) +__if_indextoname (unsigned int ifindex, char ifname[IF_NAMESIZE]) { /* We may be able to do the conversion directly, rather than searching a list. This ioctl is not present in kernels before version 2.1.50. */