public inbox for libc-ports@sourceware.org
 help / color / mirror / Atom feed
From: "Carlos O'Donell" <carlos@redhat.com>
To: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
Cc: libc-alpha@sourceware.org, libc-ports@sourceware.org
Subject: Re: [PATCH 2/5] __FD_ELT: Implement correct buffer overflow check
Date: Wed, 01 May 2013 02:42:00 -0000	[thread overview]
Message-ID: <518080FD.1090402@redhat.com> (raw)
In-Reply-To: <1365900451-19026-3-git-send-email-kosaki.motohiro@gmail.com>

On 04/13/2013 08:47 PM, KOSAKI Motohiro wrote:
> Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
> ---
>  ChangeLog                 |   14 ++++++++++++++
>  bits/select.h             |    6 +++---
>  debug/Versions            |    3 +++
>  debug/fdelt_chk.c         |   11 +++++++++++
>  misc/bits/select2.h       |   23 +++++++++++++----------
>  misc/sys/select.h         |    2 +-
>  sysdeps/x86/bits/select.h |    6 +++---
>  7 files changed, 48 insertions(+), 17 deletions(-)
> 
> diff --git a/ChangeLog b/ChangeLog
> index 5311919..36bac6a 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,17 @@
> +2013-04-13  KOSAKI Motohiro  <kosaki.motohiro@gmail.com>
> +
> +	* misc/sys/select.h (__FD_ELT): Add fdset new argument.
> +	* bits/select.h (__FD_SET, __FD_CLR, __FD_ISSET): Adapt
> +	an above change.
> +	* sysdeps/x86/bits/select.h (__FD_SET, __FD_CLR, __FD_ISSET):
> +	Likewise.
> +
> +	* debug/fdelt_chk.c (__fdelt_buffer_chk): New.
> +	* misc/bits/select2.h (__FD_ELT): Implement correct buffer
> +	overflow check instead of hardcoded FD_SET_SIZE.
> +
> +	* debug/Versions: Added __fdelt_buffer_chk and __fdelt_buffer_warn.
> +
>  2013-03-25  KOSAKI Motohiro  <kosaki.motohiro@gmail.com>
>  
>  	* debug/fdelt_chk.c (__fdelt_chk): Removed range check
> diff --git a/bits/select.h b/bits/select.h
> index ca87676..a10e18a 100644
> --- a/bits/select.h
> +++ b/bits/select.h
> @@ -30,8 +30,8 @@
>        __FDS_BITS (__arr)[__i] = 0;					      \
>    } while (0)
>  #define __FD_SET(d, s) \
> -  ((void) (__FDS_BITS (s)[__FD_ELT(d)] |= __FD_MASK(d)))
> +  ((void) (__FDS_BITS (s)[__FD_ELT(d, s)] |= __FD_MASK(d)))
>  #define __FD_CLR(d, s) \
> -  ((void) (__FDS_BITS (s)[__FD_ELT(d)] &= ~__FD_MASK(d)))
> +  ((void) (__FDS_BITS (s)[__FD_ELT(d, s)] &= ~__FD_MASK(d)))
>  #define __FD_ISSET(d, s) \
> -  ((__FDS_BITS (s)[__FD_ELT (d)] & __FD_MASK (d)) != 0)
> +  ((__FDS_BITS (s)[__FD_ELT (d, s)] & __FD_MASK (d)) != 0)
> diff --git a/debug/Versions b/debug/Versions
> index c1722fa..1ef2994 100644
> --- a/debug/Versions
> +++ b/debug/Versions
> @@ -55,6 +55,9 @@ libc {
>    GLIBC_2.16 {
>      __poll_chk; __ppoll_chk;
>    }
> +  GLIBC_2.18 {
> +    __fdelt_buffer_chk; __fdelt_buffer_warn;
> +  }
>    GLIBC_PRIVATE {
>      __fortify_fail;
>    }
> diff --git a/debug/fdelt_chk.c b/debug/fdelt_chk.c
> index 6588be0..8e16dc5 100644
> --- a/debug/fdelt_chk.c
> +++ b/debug/fdelt_chk.c
> @@ -15,6 +15,7 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#include <sys/types.h>
>  #include <sys/select.h>
>  
>  
> @@ -25,3 +26,13 @@ __fdelt_nochk (long int d)
>  }
>  strong_alias (__fdelt_nochk, __fdelt_chk)
>  strong_alias (__fdelt_nochk, __fdelt_warn)
> +
> +long int
> +__fdelt_buffer_chk (long int fd, size_t buflen)
> +{
> +  if (fd / 8 >= buflen)
> +    __chk_fail ();
> +
> +  return fd / __NFDBITS;;
> +}
> +strong_alias (__fdelt_buffer_chk, __fdelt_buffer_warn)
> diff --git a/misc/bits/select2.h b/misc/bits/select2.h
> index 03558c9..a0ffbb7 100644
> --- a/misc/bits/select2.h
> +++ b/misc/bits/select2.h
> @@ -21,15 +21,18 @@
>  #endif
>  
>  /* Helper functions to issue warnings and errors when needed.  */
> -extern long int __fdelt_chk (long int __d);
> -extern long int __fdelt_warn (long int __d)
> +extern long int __fdelt_buffer_chk (long int __d, size_t buflen);
> +extern long int __fdelt_buffer_warn (long int __d, size_t buflen)
>    __warnattr ("bit outside of fd_set selected");
> +
>  #undef __FD_ELT
> -#define	__FD_ELT(d) \
> -  __extension__								    \
> -  ({ long int __d = (d);						    \
> -     (__builtin_constant_p (__d)					    \
> -      ? (0 <= __d && __d < __FD_SETSIZE					    \
> -	 ? (__d / __NFDBITS)						    \
> -	 : __fdelt_warn (__d))						    \
> -      : __fdelt_chk (__d)); })
> +#define	__FD_ELT(d, s)							\
> +  __extension__								\
> +  ({									\
> +    long int __d = (d);							\
> +    (__bos0 (s) != (size_t) -1)						\
> +      ? (__builtin_constant_p (__d) && ((__d / 8) >= __bos0 (s)))	\
> +	? __fdelt_buffer_warn(__d, __bos0 (s))				\

Space between function and bracket e.g. foo () not foo().

> +	: __fdelt_buffer_chk(__d, __bos0 (s))				\
> +      : __d / __NFDBITS;						\

I'm not happy that this isn't very conservative.

If __bos0 fails should we fall back to static FD_SETSIZE checking
e.g. "__fdelt_buffer_warn (__d, FD_SETSIZE)"?

It seems that that would be better than no checking.

I know why you want to fall back to no check, because that
way you don't require any kind of new flag to disable the
check in the event it triggers when you don't want it to
(when __bos0 fails).

Does compiling ruby (or similar code) with this header
result in calls to __fdelt_buffer_warn or __fdelt_buffer_chk?

> +  })
> diff --git a/misc/sys/select.h b/misc/sys/select.h
> index 21351fe..341190c 100644
> --- a/misc/sys/select.h
> +++ b/misc/sys/select.h
> @@ -57,7 +57,7 @@ typedef long int __fd_mask;
>  #undef	__NFDBITS
>  /* It's easier to assume 8-bit bytes than to get CHAR_BIT.  */
>  #define __NFDBITS	(8 * (int) sizeof (__fd_mask))
> -#define	__FD_ELT(d)	((d) / __NFDBITS)
> +#define	__FD_ELT(d, s)	((d) / __NFDBITS)
>  #define	__FD_MASK(d)	((__fd_mask) 1 << ((d) % __NFDBITS))
>  
>  /* fd_set for select and pselect.  */
> diff --git a/sysdeps/x86/bits/select.h b/sysdeps/x86/bits/select.h
> index 8b87188..b29f301 100644
> --- a/sysdeps/x86/bits/select.h
> +++ b/sysdeps/x86/bits/select.h
> @@ -56,8 +56,8 @@
>  #endif	/* GNU CC */
>  
>  #define __FD_SET(d, set) \
> -  ((void) (__FDS_BITS (set)[__FD_ELT (d)] |= __FD_MASK (d)))
> +  ((void) (__FDS_BITS (set)[__FD_ELT (d, set)] |= __FD_MASK (d)))
>  #define __FD_CLR(d, set) \
> -  ((void) (__FDS_BITS (set)[__FD_ELT (d)] &= ~__FD_MASK (d)))
> +  ((void) (__FDS_BITS (set)[__FD_ELT (d, set)] &= ~__FD_MASK (d)))
>  #define __FD_ISSET(d, set) \
> -  ((__FDS_BITS (set)[__FD_ELT (d)] & __FD_MASK (d)) != 0)
> +  ((__FDS_BITS (set)[__FD_ELT (d, set)] & __FD_MASK (d)) != 0)
> 

Cheers,
Carlos.

  reply	other threads:[~2013-05-01  2:42 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-14  0:47 [PATCH v4 0/5] fix wrong program abort on __FD_ELT KOSAKI Motohiro
2013-04-14  0:47 ` [PATCH 3/5] update libc.abilist KOSAKI Motohiro
2013-04-14  0:47 ` [PATCH 5/5] __FDS_BITS: Added cast to __fd_mask* to avoid warning KOSAKI Motohiro
2013-05-01  2:44   ` Carlos O'Donell
2013-04-14  0:47 ` [PATCH 2/5] __FD_ELT: Implement correct buffer overflow check KOSAKI Motohiro
2013-05-01  2:42   ` Carlos O'Donell [this message]
2013-05-01  6:28     ` KOSAKI Motohiro
2013-05-01 14:42       ` Carlos O'Donell
2013-05-01 20:32         ` KOSAKI Motohiro
2013-05-03  3:15           ` Carlos O'Donell
2013-05-01 20:11       ` KOSAKI Motohiro
2013-05-03  3:15         ` Carlos O'Donell
2013-04-14  0:47 ` [PATCH 4/5] tst-chk1: add fd_set dynamic allocation test KOSAKI Motohiro
2013-05-01  2:44   ` Carlos O'Donell
2013-05-01  6:29     ` KOSAKI Motohiro
2013-04-14  0:47 ` [PATCH 1/5] __fdelt_chk: Removed range check KOSAKI Motohiro
2013-05-01  2:25   ` Carlos O'Donell
2013-05-01  6:40     ` KOSAKI Motohiro
2013-05-01 14:45       ` Carlos O'Donell
2013-05-01 22:13         ` KOSAKI Motohiro
2013-05-03  2:52           ` Carlos O'Donell
2013-05-01  3:08 ` [PATCH v4 0/5] fix wrong program abort on __FD_ELT Carlos O'Donell
2013-05-01  5:31   ` KOSAKI Motohiro
2013-05-01 14:38     ` Carlos O'Donell
2013-05-01 22:21       ` KOSAKI Motohiro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=518080FD.1090402@redhat.com \
    --to=carlos@redhat.com \
    --cc=kosaki.motohiro@gmail.com \
    --cc=libc-alpha@sourceware.org \
    --cc=libc-ports@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).