Re: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2021-10-18 Thread Tim Düsterhus

Willy,

On 10/18/21 10:51 AM, Willy Tarreau wrote:

On Mon, Oct 18, 2021 at 09:18:12AM +0200, Tim Düsterhus wrote:

Hu, interesting. Is the GitHub Mirror Sync broken? I'm seeing changes in
https://git.haproxy.org/?p=haproxy.git, but not in GitHub.


So it was in relation with the Painful Access Token apparently. The
mirror user was not allowed anymore to push to .github/workflows:

   $ git push github
   Counting objects: 99, done.
   Delta compression using up to 2 threads.
   Compressing objects: 100% (63/63), done.
   Writing objects: 100% (63/63), 6.69 KiB | 0 bytes/s, done.
   Total 63 (delta 51), reused 0 (delta 0)
   remote: Resolving deltas: 100% (51/51), completed with 34 local objects.
   To https://github.com/haproxy/haproxy.git
! [remote rejected] master -> master (refusing to allow a Personal Access 
Token to create or update workflow `.github/workflows/codespell.yml` without 
`workflow` scope)

I don't really see the relation with any of the recent changes. Thus I
switched to SSH and got rid of the stupid clear-text PAT and now it's
OK again.



GitHub Action Workflows are pretty powerful and can do all kinds of 
stuff within a repository. I assume that GitHub wanted to increase the 
security by not allowing arbitrary tokens to change them, when the 
purpose of the token is something entirely different.


I assume that simply using SSH will be stable going forward. That's all 
I ever used for write access since I signed up to GitHub.


Best regards
Tim Düsterhus



Re: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2021-10-18 Thread Willy Tarreau
On Mon, Oct 18, 2021 at 09:18:12AM +0200, Tim Düsterhus wrote:
> Hu, interesting. Is the GitHub Mirror Sync broken? I'm seeing changes in
> https://git.haproxy.org/?p=haproxy.git, but not in GitHub.

So it was in relation with the Painful Access Token apparently. The
mirror user was not allowed anymore to push to .github/workflows:

  $ git push github
  Counting objects: 99, done.
  Delta compression using up to 2 threads.
  Compressing objects: 100% (63/63), done.
  Writing objects: 100% (63/63), 6.69 KiB | 0 bytes/s, done.
  Total 63 (delta 51), reused 0 (delta 0)
  remote: Resolving deltas: 100% (51/51), completed with 34 local objects.
  To https://github.com/haproxy/haproxy.git
   ! [remote rejected] master -> master (refusing to allow a Personal Access 
Token to create or update workflow `.github/workflows/codespell.yml` without 
`workflow` scope)

I don't really see the relation with any of the recent changes. Thus I
switched to SSH and got rid of the stupid clear-text PAT and now it's
OK again.

Thanks,
Willy



Re: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2021-10-18 Thread Willy Tarreau
On Mon, Oct 18, 2021 at 09:18:12AM +0200, Tim Düsterhus wrote:
> Willy,
> 
> On 10/18/21 9:15 AM, Willy Tarreau wrote:
> > On Mon, Oct 18, 2021 at 09:09:01AM +0200, Tim Düsterhus wrote:
> > > Feel free to replace 'unsigned int' with 'uint' and reformat the struct as
> > > needed.
> > 
> > Done an pushed, thank you!
> > Willy
> > 
> 
> Hu, interesting. Is the GitHub Mirror Sync broken? I'm seeing changes in
> https://git.haproxy.org/?p=haproxy.git, but not in GitHub.

Indeed, it seems that nothing was updated since dev10 this week-end.
I'll have a look.

Thanks for reporting it!
Willy



Re: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2021-10-18 Thread Tim Düsterhus

Willy,

On 10/18/21 9:15 AM, Willy Tarreau wrote:

On Mon, Oct 18, 2021 at 09:09:01AM +0200, Tim Düsterhus wrote:

Feel free to replace 'unsigned int' with 'uint' and reformat the struct as
needed.


Done an pushed, thank you!
Willy



Hu, interesting. Is the GitHub Mirror Sync broken? I'm seeing changes in 
https://git.haproxy.org/?p=haproxy.git, but not in GitHub.


Best regards
Tim Düsterhus



Re: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2021-10-18 Thread Willy Tarreau
On Mon, Oct 18, 2021 at 09:09:01AM +0200, Tim Düsterhus wrote:
> Feel free to replace 'unsigned int' with 'uint' and reformat the struct as
> needed.

Done an pushed, thank you!
Willy



Re: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2021-10-18 Thread Tim Düsterhus

Willy,

On 10/18/21 7:22 AM, Willy Tarreau wrote:

On Sat, Oct 16, 2021 at 06:24:18PM +0200, Tim Duesterhus wrote:

see 6a0dd733906611dea958cf74b9f51bb16028ae20

Found using GitHub's CodeQL scan.
---
  include/haproxy/stick_table-t.h | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/haproxy/stick_table-t.h b/include/haproxy/stick_table-t.h
index 3b1f2b3ef..133f992b5 100644
--- a/include/haproxy/stick_table-t.h
+++ b/include/haproxy/stick_table-t.h
@@ -125,8 +125,8 @@ struct stktable_data_type {
const char *name; /* name of the data type */
int std_type; /* standard type we can use for this data, STD_T_* */
int arg_type; /* type of optional argument, ARG_T_* */
-   int is_array:1;   /* this is an array of gpc/gpt */
-   int is_local:1;   /* this is local only and never learned */
+   unsigned int is_array:1;   /* this is an array of gpc/gpt */
+   unsigned int is_local:1;   /* this is local only and never learned */


Please note, since last patch we've added shorter type names like "uint"
for the unsigned int, that help preserve alignment. Do you mind if I adapt
your patch ?


Feel free to replace 'unsigned int' with 'uint' and reformat the struct 
as needed.


Best regards
Tim Düsterhus



Re: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2021-10-17 Thread Willy Tarreau
On Sat, Oct 16, 2021 at 06:24:18PM +0200, Tim Duesterhus wrote:
> see 6a0dd733906611dea958cf74b9f51bb16028ae20
> 
> Found using GitHub's CodeQL scan.
> ---
>  include/haproxy/stick_table-t.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/include/haproxy/stick_table-t.h b/include/haproxy/stick_table-t.h
> index 3b1f2b3ef..133f992b5 100644
> --- a/include/haproxy/stick_table-t.h
> +++ b/include/haproxy/stick_table-t.h
> @@ -125,8 +125,8 @@ struct stktable_data_type {
>   const char *name; /* name of the data type */
>   int std_type; /* standard type we can use for this data, STD_T_* */
>   int arg_type; /* type of optional argument, ARG_T_* */
> - int is_array:1;   /* this is an array of gpc/gpt */
> - int is_local:1;   /* this is local only and never learned */
> + unsigned int is_array:1;   /* this is an array of gpc/gpt */
> + unsigned int is_local:1;   /* this is local only and never learned */

Please note, since last patch we've added shorter type names like "uint"
for the unsigned int, that help preserve alignment. Do you mind if I adapt
your patch ?

Willy



[PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2021-10-16 Thread Tim Duesterhus
see 6a0dd733906611dea958cf74b9f51bb16028ae20

Found using GitHub's CodeQL scan.
---
 include/haproxy/stick_table-t.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/haproxy/stick_table-t.h b/include/haproxy/stick_table-t.h
index 3b1f2b3ef..133f992b5 100644
--- a/include/haproxy/stick_table-t.h
+++ b/include/haproxy/stick_table-t.h
@@ -125,8 +125,8 @@ struct stktable_data_type {
const char *name; /* name of the data type */
int std_type; /* standard type we can use for this data, STD_T_* */
int arg_type; /* type of optional argument, ARG_T_* */
-   int is_array:1;   /* this is an array of gpc/gpt */
-   int is_local:1;   /* this is local only and never learned */
+   unsigned int is_array:1;   /* this is an array of gpc/gpt */
+   unsigned int is_local:1;   /* this is local only and never learned */
 };
 
 /* stick table keyword type */
-- 
2.33.0




Re: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2020-01-21 Thread Willy Tarreau
On Sat, Jan 18, 2020 at 11:41:58AM +0100, Tim Düsterhus wrote:
> Fair enough. In the specific implementation of gcc it might be okay. But
> that doesn't say anything about clang (but I guess it's okay as well).

Clang tries hard to support whatever gcc does and when I mean gcc I
implicitly also mean clang (and very likely icc as well for those who
care).

> > For this reason I'd like to get the signed-vs-unsigned part merged.
> 
> Feel free to edit around in my patch to remove the bits that change from
> something to `int` and leave the adding of the `unsigned` in there. Or
> drop my patch, create your own one and add me as Co-authored-by or
> Reported-by or whatever.

OK so I simply edited your patch.

> While doing so please check on the `struct pat_time` I mentioned in my
> previous email.

Ah yes, good point. I've just checked, I added this in 2007 and never
implemented the time range parser. I we managed not to need if for the
last 13 years, I think we don't need it and the day we need it we might
do it differently, so I'm simply removing that definition.

thanks!
Willy



Re: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2020-01-18 Thread Tim Düsterhus
Willy,

Am 18.01.20 um 07:51 schrieb Willy Tarreau:
>> - Non-ints are not allowed by the C standard.
> 
> Hmmm that's not exactly what I'm reading in C99 #6.7.2.1 here, which
> explicitly permits implementation-defined types:
> 
>"A bit-field shall have a type that is a qualified or unqualified version 
> of
>_Bool, signed int, unsigned int, or some other implementation-defined 
> type."
> 
> And the implementation we rely on (gcc) says:
> 
>
> https://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit-fields-implementation.html
> Allowable bit-field types other than _Bool, signed int, and unsigned int
> (C99 and C11 6.7.2.1).  Other integer types, such as long int, and
> enumerated types are permitted even in strictly conforming mode.

Fair enough. In the specific implementation of gcc it might be okay. But
that doesn't say anything about clang (but I guess it's okay as well).

> And this is not surprizing for both tools, because I think that with the
> change, the unsigned int field is merged with the previous chars, which
> is particularly dirty. And if we place the field before the chars, it
> leaves a two-bytes hole between them.
> 
> Ideally I'd use flags there, though we'd have to place them in an unsigned
> char. If you're interested in having a look at such a change I'd prefer it,
> otherwise I'd prefer not to change what exists for this part because it does
> exactly what we need and the change makes it wrong at least debug-wise.

I'm not interested. The change to int from char was just a by-product of
the signedness changes I made. As you might imagine I was working off
the output of some static analyzer which complained that the size `1`
bitfield might not be what was meant. While I heard about the existence
of bitfields before I have no idea how they worked, read a bit about
them and then changed them all to be consistently `int`, because that's
what's guaranteed by the standard.

Long story short: If you prefer these to remain chars, then so be it.

> For this reason I'd like to get the signed-vs-unsigned part merged.

Feel free to edit around in my patch to remove the bits that change from
something to `int` and leave the adding of the `unsigned` in there. Or
drop my patch, create your own one and add me as Co-authored-by or
Reported-by or whatever.

While doing so please check on the `struct pat_time` I mentioned in my
previous email.

> Did you check whether this produced any output code change ? It would
> be a hint that we might possibly have latent bugs.

No, because this is way outside the area of my expertise :-)

Best regards
Tim Düsterhus



Re: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2020-01-17 Thread Willy Tarreau
Hi Tim,

On Sat, Jan 18, 2020 at 01:32:49AM +0100, Tim Duesterhus wrote:
> Willy,
> 
> I did not touch the `struct pat_time` in pattern.h which appears to be
> completely unused. Please check whether adjustments should be made there
> as well or whether it should simply be removed. Feel free to amend my
> patch if necessary.
> 
> Best regards
> Tim Düsterhus
> 
> Apply with `git am --scissors` to automatically cut the commit message.
> 
> -- >8 --
> Subject: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields
> 
> - Non-ints are not allowed by the C standard.

Hmmm that's not exactly what I'm reading in C99 #6.7.2.1 here, which
explicitly permits implementation-defined types:

   "A bit-field shall have a type that is a qualified or unqualified version of
   _Bool, signed int, unsigned int, or some other implementation-defined type."

And the implementation we rely on (gcc) says:

   
https://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit-fields-implementation.html
Allowable bit-field types other than _Bool, signed int, and unsigned int
(C99 and C11 6.7.2.1).  Other integer types, such as long int, and
enumerated types are permitted even in strictly conforming mode.

I tend to find it extremely confusing to place "unsigned int" just after a
char, because it makes one think we're leaving a 2-byte hole before and/or
that we can use up to 32 bits without causing misalignment while in practice
we can only use the few bits left from the missing bytes. That's what we
have in fdtab:

void *owner;
unsigned char state;   <-- 8-aligned
unsigned char ev;  <-- 8-aligned + 1
unsigned char linger_risk:1<-- 8-aligned + 2;
unsigned char cloned:1;
unsigned char initialized:1;

With the change it remains the same except that it looks quite non-obvious
as the hole will depend on the number of bits added:

void *owner;
unsigned char state;   <-- 8-aligned
unsigned char ev;  <-- 8-aligned + 1
unsigned int linger_risk:1 <-- 8-aligned + 2;
unsigned int cloned:1;
unsigned int initialized:1;

Interestingly, the change above confuses pahole:

   struct fdtab {
long unsigned int  lock; /* 0 8 */
long unsigned int  thread_mask;  /* 8 8 */
long unsigned int  update_mask;  /*16 8 */
struct fdlist_entryupdate;   /*24 8 */
void   (*iocb)(int); /*32 8 */
void * owner;/*40 8 */
unsigned char  state;/*48 1 */
unsigned char  ev;   /*49 1 */

/* Bitfield combined with previous fields */

unsigned int   linger_risk:1;/*48:15  4 */
unsigned int   cloned:1; /*48:14  4 */
unsigned int   initialized:1;/*48:13  4 */
 ^^^
Here it expects to reserve 4 bytes for the field

/* size: 56, cachelines: 1, members: 11 */
/* padding: 4 */
/* bit_padding: 29 bits */
/* last cacheline: 56 bytes */

/* BRAIN FART ALERT! 56 != 56 + 0(holes), diff = 0 */
   ^^

And this surprizing warning (certainly a bug). Without this change, the
output looks more consistent:

unsigned char  state;/*48 1 */
unsigned char  ev;   /*49 1 */
unsigned char  linger_risk:1;/*50: 7  1 */
unsigned char  cloned:1; /*50: 6  1 */
unsigned char  initialized:1;/*50: 5  1 */

More annoyingly it confuses gdb:

Before:
  (gdb) p [0].linger_risk
  $4 = (unsigned char *) 0x32

After:
  (gdb)  p [0].linger_risk
  $1 = (unsigned int *) 0x30

And this is not surprizing for both tools, because I think that with the
change, the unsigned int field is merged with the previous chars, which
is particularly dirty. And if we place the field before the chars, it
leaves a two-bytes hole between them.

Ideally I'd use flags there, though we'd have to place them in an unsigned
char. If you're interested in having a look at such a change I'd prefer it,
otherwise I'd prefer not to change what exists for this part because it does
exactly what we need and the change makes it wrong at least debug-wise.

> - Signed bitfields of size `1` hold the values `0` and `-1`, but are
>   usually assigned `1`, possibly leading to subtle bugs when the value

[PATCH] CLEANUP: Consistently `unsigned int` for bitfields

2020-01-17 Thread Tim Duesterhus
Willy,

I did not touch the `struct pat_time` in pattern.h which appears to be
completely unused. Please check whether adjustments should be made there
as well or whether it should simply be removed. Feel free to amend my
patch if necessary.

Best regards
Tim Düsterhus

Apply with `git am --scissors` to automatically cut the commit message.

-- >8 --
Subject: [PATCH] CLEANUP: Consistently `unsigned int` for bitfields

- Non-ints are not allowed by the C standard.
- Signed bitfields of size `1` hold the values `0` and `-1`, but are
  usually assigned `1`, possibly leading to subtle bugs when the value
  is explicitely compared against `1`.
---
 include/types/fd.h   | 6 +++---
 include/types/listener.h | 6 +++---
 include/types/pattern.h  | 4 ++--
 include/types/ssl_sock.h | 8 
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/types/fd.h b/include/types/fd.h
index dae1c90c9..61af8a523 100644
--- a/include/types/fd.h
+++ b/include/types/fd.h
@@ -129,9 +129,9 @@ struct fdtab {
void *owner; /* the connection or listener 
associated with this fd, NULL if closed */
unsigned char state; /* FD state for read and write 
directions (2*3 bits) */
unsigned char ev;/* event seen in return of poll() 
: FD_POLL_* */
-   unsigned char linger_risk:1; /* 1 if we must kill lingering 
before closing */
-   unsigned char cloned:1;  /* 1 if a cloned socket, requires 
EPOLL_CTL_DEL on close */
-   unsigned char initialized:1; /* 1 if init phase was done on 
this fd (e.g. set non-blocking) */
+   unsigned int linger_risk:1;  /* 1 if we must kill lingering 
before closing */
+   unsigned int cloned:1;   /* 1 if a cloned socket, requires 
EPOLL_CTL_DEL on close */
+   unsigned int initialized:1;  /* 1 if init phase was done on 
this fd (e.g. set non-blocking) */
 }
 #ifdef USE_THREAD
 /* only align on cache lines when using threads; 32-bit small archs
diff --git a/include/types/listener.h b/include/types/listener.h
index 1098b42ce..bcc57ae70 100644
--- a/include/types/listener.h
+++ b/include/types/listener.h
@@ -124,9 +124,9 @@ struct ssl_bind_conf {
char *alpn_str;/* ALPN protocol string */
int alpn_len;  /* ALPN protocol string length */
 #endif
-   int verify:3;  /* verify method (set of SSL_VERIFY_* flags) 
*/
-   int no_ca_names:1; /* do not send ca names to clients (ca_file 
related) */
-   int early_data:1;  /* early data allowed */
+   unsigned int verify:3; /* verify method (set of SSL_VERIFY_* flags) 
*/
+   unsigned int no_ca_names:1;/* do not send ca names to clients (ca_file 
related) */
+   unsigned int early_data:1; /* early data allowed */
char *ca_file; /* CAfile to use on verify */
char *crl_file;/* CRLfile to use on verify */
char *ciphers; /* cipher suite to use if non-null */
diff --git a/include/types/pattern.h b/include/types/pattern.h
index a0bb08e16..a2d609ba0 100644
--- a/include/types/pattern.h
+++ b/include/types/pattern.h
@@ -150,8 +150,8 @@ struct pattern {
int i;  /* integer value */
struct {
signed long long min, max;
-   int min_set :1;
-   int max_set :1;
+   unsigned int min_set:1;
+   unsigned int max_set:1;
} range; /* integer range */
struct {
struct in_addr addr;
diff --git a/include/types/ssl_sock.h b/include/types/ssl_sock.h
index ccc923508..172be6772 100644
--- a/include/types/ssl_sock.h
+++ b/include/types/ssl_sock.h
@@ -36,8 +36,8 @@ struct pkey_info {
 struct sni_ctx {
SSL_CTX *ctx; /* context associated to the certificate */
int order;/* load order for the certificate */
-   uint8_t neg:1;  /* reject if match */
-   uint8_t wild:1;/* wildcard sni */
+   unsigned int neg:1;  /* reject if match */
+   unsigned int wild:1;/* wildcard sni */
struct pkey_info kinfo;   /* pkey info */
struct ssl_bind_conf *conf; /* ssl "bind" conf for the certificate */
struct list by_ckch_inst; /* chained in ckch_inst's list of sni_ctx */
@@ -109,8 +109,8 @@ struct cert_key_and_chain {
  */
 struct ckch_store {
struct cert_key_and_chain *ckch;
-   int multi:1; /* is it a multi-cert bundle ? */
-   int filters:1; /* one of the instances is using filters, TODO:remove 
this flag once filters are supported */
+   unsigned int multi:1; /* is it a multi-cert bundle ? */
+   unsigned int filters:1; /* one of the instances is using filters, 
TODO:remove this flag once filters