mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Willy Tarreau <w@1wt.eu>
To: David Laight <David.Laight@aculab.com>
Cc: "Paul E . McKenney" <paulmck@kernel.org>,
	Mark Brown <broonie@kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 11/42] tools/nolibc/types: move the FD_* functions to macros in types.h
Date: Tue, 8 Feb 2022 06:14:43 +0100	[thread overview]
Message-ID: <20220208051443.GB18521@1wt.eu> (raw)
In-Reply-To: <083fac943c8c422a9f667f6b0371153c@AcuMS.aculab.com>

Hi David,

On Mon, Feb 07, 2022 at 05:05:21PM +0000, David Laight wrote:
> From: Willy Tarreau
> > Sent: 07 February 2022 16:23
> > 
> > FD_SET, FD_CLR, FD_ISSET, FD_ZERO are supposed to be macros and not
> > functions.
> 
> Are you sure?
> I'd have thought they could be either.
> There are certainly systems where they are functions.

I've rechecked and you're right, they can be both. But I now remember
why I mentioned this, I used to have some early userland code that used
to redefine these based on #ifndef FD_CLR and that started to fail to
build depending on the include order (i.e. macro defined first, then
nolibc being included from another file).

> They can be implemented as an array of fd numbers rather than a bitmap.

I didn't think about the array of FDs but I see how that can be done,
indeed!

> > In addition we already have a file dedicated to such macros
> > and types used by syscalls, it's types.h, so let's move them
> > there and turn them to macros. FD_CLR() and FD_ISSET() were missing,
> > so they were added. FD_ZERO() now deals with its own loop so that it
> > doesn't rely on memset() that sets one byte at a time.
> > 
> ....
> > +#define FD_CLR(fd, set) do {                                            \
> > +		int __fd = (int)(fd);                                   \
> > +		fd_set *__set = (fd_set *)(set);                        \
> 
> I'm not sure you really want either cast.
> They are just likely to hide some horrid bugs.

I generally hate casts exactly for the reason you mentioned, but wanted
to stick as close as possible to the equivalent of the original function.
However now that there are these local variables the casts are not needed
anymore at all and I agree we should drop them. I'll do that.

> +		if (__fd >= 0 && __fd < FD_SETSIZE)                     \
> +			__set->fd32[__fd / 32] &= ~(1U << (__fd & 31)); \
> +	} while (0)
> +
> 
> Do you need the range check?
> I don't think glibc has one.
> Things just break in obscure ways when you use select on big fd.

Sadly, some versions of glibc have enforced such checks "recently".
I've seen code that used to work fine for 20 years with arbitrary
fd_set array lengths start to break because the libc was seeing some
out-of-bounds accesses, to the point that I finally completely stopped
using select() around 2013, and also stopped using FD_SET/FD_CLR to
manipulate arbitrary bitmaps and implement my own instead (see the
__FD_ELT macro in glibc for this).

The select(2) man page says:

  An fd_set is a fixed size buffer.  Executing FD_CLR() or FD_SET() with
  a value of fd that is negative or is equal to or larger than FD_SETSIZE
  will result in undefined behavior.  

The main reason for the check here in fact is to avoid annoying compiler
warnings such as -Warray-bounds and limit side effects if FDs are not
tested immediately before being passed to FD_SET (we're supposed to be
dealing with ugly early code where tests are often non-existent). I
think it's a reasonable compromise. I would also be fine with only
keeping the test on (fd >= 0) and dropping the one on FD_SETSIZE though.

Paul, I'll send a V2 of that patch once updated.

Thank you!
Willy

  reply	other threads:[~2022-02-08  5:33 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-07 16:23 [PATCH 00/42] nolibc: update to resync with out-of-tree project Willy Tarreau
2022-02-07 16:23 ` [PATCH 01/42] tools/nolibc: use pselect6 on RISCV Willy Tarreau
2022-02-07 16:23 ` [PATCH 02/42] tools/nolibc: guard the main file against multiple inclusion Willy Tarreau
2022-02-07 16:23 ` [PATCH 03/42] tools/nolibc/std: move the standard type definitions to std.h Willy Tarreau
2022-02-07 16:23 ` [PATCH 04/42] tools/nolibc/types: split syscall-specific definitions into their own files Willy Tarreau
2022-02-07 16:23 ` [PATCH 05/42] tools/nolibc/arch: split arch-specific code into individual files Willy Tarreau
2022-02-07 16:23 ` [PATCH 06/42] tools/nolibc/sys: split the syscall definitions into their own file Willy Tarreau
2022-02-07 16:23 ` [PATCH 07/42] tools/nolibc/stdlib: extract the stdlib-specific functions to " Willy Tarreau
2022-02-07 16:23 ` [PATCH 08/42] tools/nolibc/string: split the string functions into string.h Willy Tarreau
2022-02-07 16:23 ` [PATCH 09/42] tools/nolibc/ctype: split the is* functions to ctype.h Willy Tarreau
2022-02-07 16:23 ` [PATCH 10/42] tools/nolibc/ctype: add the missing is* functions Willy Tarreau
2022-02-07 16:23 ` [PATCH 11/42] tools/nolibc/types: move the FD_* functions to macros in types.h Willy Tarreau
2022-02-07 17:05   ` David Laight
2022-02-08  5:14     ` Willy Tarreau [this message]
2022-02-13  8:52   ` [PATCH v2 " Willy Tarreau
2022-02-07 16:23 ` [PATCH 12/42] tools/nolibc/types: make FD_SETSIZE configurable Willy Tarreau
2022-02-13  8:53   ` [PATCH v2 " Willy Tarreau
2022-02-14 20:17     ` Paul E. McKenney
2022-02-07 16:23 ` [PATCH 13/42] tools/nolibc/types: move makedev to types.h and make it a macro Willy Tarreau
2022-02-07 16:23 ` [PATCH 14/42] tools/nolibc/stdlib: move ltoa() to stdlib.h Willy Tarreau
2022-02-07 16:23 ` [PATCH 15/42] tools/nolibc/stdlib: replace the ltoa() function with more efficient ones Willy Tarreau
2022-02-07 16:23 ` [PATCH 16/42] tools/nolibc/stdlib: add i64toa() and u64toa() Willy Tarreau
2022-02-07 16:23 ` [PATCH 17/42] tools/nolibc/stdlib: add utoh() and u64toh() Willy Tarreau
2022-02-07 16:23 ` [PATCH 18/42] tools/nolibc/stdio: add a minimal set of stdio functions Willy Tarreau
2022-02-07 16:23 ` [PATCH 19/42] tools/nolibc/stdio: add stdin/stdout/stderr and fget*/fput* functions Willy Tarreau
2022-02-07 16:23 ` [PATCH 20/42] tools/nolibc/stdio: add fwrite() to stdio Willy Tarreau
2022-02-07 16:23 ` [PATCH 21/42] tools/nolibc/stdio: add a minimal [vf]printf() implementation Willy Tarreau
2022-02-07 16:23 ` [PATCH 22/42] tools/nolibc/types: define EXIT_SUCCESS and EXIT_FAILURE Willy Tarreau
2022-02-07 16:23 ` [PATCH 23/42] tools/nolibc/stdio: add perror() to report the errno value Willy Tarreau
2022-02-07 16:23 ` [PATCH 24/42] tools/nolibc/sys: make open() take a vararg on the 3rd argument Willy Tarreau
2022-02-07 16:23 ` [PATCH 25/42] tools/nolibc/stdlib: avoid a 64-bit shift in u64toh_r() Willy Tarreau
2022-02-07 16:23 ` [PATCH 26/42] tools/nolibc/stdlib: make raise() use the lower level syscalls only Willy Tarreau
2022-02-07 16:23 ` [PATCH 27/42] tools/nolibc/sys: make getpgrp(), getpid(), gettid() not set errno Willy Tarreau
2022-02-07 16:23 ` [PATCH 28/42] tools/nolibc/string: use unidirectional variants for memcpy() Willy Tarreau
2022-02-07 16:23 ` [PATCH 29/42] tools/nolibc/string: slightly simplify memmove() Willy Tarreau
2022-02-07 16:23 ` [PATCH 30/42] tools/nolibc/string: add strncpy() and strlcpy() Willy Tarreau
2022-02-07 16:23 ` [PATCH 31/42] tools/nolibc/string: add tiny versions of strncat() and strlcat() Willy Tarreau
2022-02-07 16:23 ` [PATCH 32/42] tools/nolibc: move exported functions to their own section Willy Tarreau
2022-02-07 16:23 ` [PATCH 33/42] tools/nolibc/arch: mark the _start symbol as weak Willy Tarreau
2022-02-07 16:23 ` [PATCH 34/42] tools/nolibc/types: define PATH_MAX and MAXPATHLEN Willy Tarreau
2022-02-07 16:23 ` [PATCH 35/42] tools/nolibc/string: export memset() and memmove() Willy Tarreau
2022-02-07 16:23 ` [PATCH 36/42] tools/nolibc/errno: extract errno.h from sys.h Willy Tarreau
2022-02-07 16:23 ` [PATCH 37/42] tools/nolibc/unistd: extract msleep(), sleep(), tcsetpgrp() to unistd.h Willy Tarreau
2022-02-07 16:23 ` [PATCH 38/42] tools/nolibc/unistd: add usleep() Willy Tarreau
2022-02-07 16:23 ` [PATCH 39/42] tools/nolibc/signal: move raise() to signal.h Willy Tarreau
2022-02-07 16:23 ` [PATCH 40/42] tools/nolibc/time: create time.h with time() Willy Tarreau
2022-02-07 16:23 ` [PATCH 41/42] tools/nolibc: also mention how to build by just setting the include path Willy Tarreau
2022-02-07 16:23 ` [PATCH 42/42] tools/nolibc/stdlib: implement abort() Willy Tarreau
2022-02-08  0:00 ` [PATCH 00/42] nolibc: update to resync with out-of-tree project Paul E. McKenney
2022-02-08  4:41   ` Willy Tarreau
2022-02-08  5:10     ` Paul E. McKenney

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=20220208051443.GB18521@1wt.eu \
    --to=w@1wt.eu \
    --cc=David.Laight@aculab.com \
    --cc=broonie@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulmck@kernel.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

all inboxes | Powered by JetHome®