netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Thomas Haller <thaller@redhat.com>
Cc: NetFilter <netfilter-devel@vger.kernel.org>
Subject: Re: [PATCH nft 5/8] src: rework SNPRINTF_BUFFER_SIZE() and avoid "-Wunused-but-set-variable"
Date: Mon, 28 Aug 2023 18:04:18 +0200	[thread overview]
Message-ID: <ZOzFgtwJI6AasAYZ@calendula> (raw)
In-Reply-To: <aa481d83b0320078a17bebf215378992a4f7cb21.camel@redhat.com>

On Mon, Aug 28, 2023 at 05:49:53PM +0200, Thomas Haller wrote:
> On Mon, 2023-08-28 at 17:13 +0200, Pablo Neira Ayuso wrote:
[...]
> > > diff --git a/include/utils.h b/include/utils.h
> > > index cee1e5c1e8ae..873147fb54ec 100644
> > > --- a/include/utils.h
> > > +++ b/include/utils.h
> > > @@ -72,15 +72,29 @@
> > >  #define max(_x, _y) ({                         \
> > >         _x > _y ? _x : _y; })
> > >  
> > > -#define SNPRINTF_BUFFER_SIZE(ret, size, len, offset)   \
> > > -       if (ret < 0)                                    \
> > > -               abort();                                \
> > > -       offset += ret;                                  \
> > > -       assert(ret < len);                              \
> > > -       if (ret > len)                                  \
> > > -               ret = len;                              \
> > > -       size += ret;                                    \
> > > -       len -= ret;
> > > +#define SNPRINTF_BUFFER_SIZE(ret, len, offset)                 \
> > > +       do { \
> > > +               const int _ret = (ret);                         \
> > > +               size_t *const _len = (len);                     \
> > > +               size_t *const _offset = (offset);               \
> > > +               size_t _ret2;                                   \
> > > +                                                               \
> > > +               assert(_ret >= 0);                              \
> > > +                                                               \
> > > +               if ((size_t) _ret >= *_len) {                   \
> > > +                       /* Fail an assertion on truncation.
> > > +                        *
> > > +                        * Anyway, we would set "len" to zero and
> > > "offset" one
> > > +                        * after the buffer size (past the
> > > terminating NUL
> > > +                        * byte). */                            \
> > > +                       assert((size_t) _ret < *_len);          \
> > > +                       _ret2 = *_len;                          \
> > > +               } else                                          \
> > > +                       _ret2 = (size_t) _ret;                  \
> > > +                                                               \
> > > +               *_offset += _ret2;                              \
> > > +               *_len -= _ret2;                                 \
> > > +       } while (0)
> > 
> > This macro is something I made myself, which I am particularly not
> > proud of it, but it getting slightly more complicated.
> 
> IMO it just got simpler. E.g. it is now function-like; you can easier
> see which arguments are modified (we take a pointer to them); one
> argument got dropped.
>
> The remaining relevant parts (assertions and truncation check aside) is
> literally
> 
>    offset += ret;
>    len -= ret;
> 
> > 
> > Probably it time to turn this into a real function?
> 
> as it now behaves function-like, it can be easily converted to an
> inline function. Only difference is that upon assertion failure, we no
> longer see the location of the caller. It does not seem an improvement.

No need for inline in this case, this is not performance critical, it
will increase size of binary, better let the compiler decide. What is
left to turn this into a real function? It looks like a candidate for
the new nftutils.c file to me.

> > >  #define MSEC_PER_SEC   1000L
> > >  
> > > diff --git a/src/evaluate.c b/src/evaluate.c
> > > index 1ae2ef0de10c..f8cd7b7afda3 100644
> > > --- a/src/evaluate.c
> > > +++ b/src/evaluate.c
> > > @@ -4129,14 +4129,16 @@ static int stmt_evaluate_queue(struct
> > > eval_ctx *ctx, struct stmt *stmt)
> > >  static int stmt_evaluate_log_prefix(struct eval_ctx *ctx, struct
> > > stmt *stmt)
> > >  {
> > >         char prefix[NF_LOG_PREFIXLEN] = {}, tmp[NF_LOG_PREFIXLEN] =
> > > {};
> > > -       int len = sizeof(prefix), offset = 0, ret;
> > > +       size_t len = sizeof(prefix);
> > > +       size_t offset = 0;
> > >         struct expr *expr;
> > > -       size_t size = 0;
> > >  
> > >         if (stmt->log.prefix->etype != EXPR_LIST)
> > >                 return 0;
> > >  
> > >         list_for_each_entry(expr, &stmt->log.prefix->expressions,
> > > list) {
> > > +               int ret;
> > > +
> > >                 switch (expr->etype) {
> > >                 case EXPR_VALUE:
> > >                         expr_to_string(expr, tmp);
> > > @@ -4150,12 +4152,9 @@ static int stmt_evaluate_log_prefix(struct
> > > eval_ctx *ctx, struct stmt *stmt)
> > >                         BUG("unknown expression type %s\n",
> > > expr_name(expr));
> > >                         break;
> > >                 }
> > > -               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
> > > +               SNPRINTF_BUFFER_SIZE(ret, &len, &offset);
> > >         }
> > >  
> > > -       if (len == NF_LOG_PREFIXLEN)
> > > -               return stmt_error(ctx, stmt, "log prefix is too
> > > long");
> > 
> > No error anymore?
> > 
> > Not directly related, but are you sure tests we have are sufficient
> > to
> > cover for all these updates 
> 
> No. I am not aware of test coverage.

There is:

        tests/py

which are unitary tests, there is a README file, it tests control
plane only: it dump the output from the kernel to test listing path.
They also cover json support.

        tests/shell

are tests coverage in the form of shell scripts, some validates that
the output is correct via dump file, some others do not. They are more
flexible that tests/py.

There are also selftests in the netfilter folders, see:

        tools/testing/selftests/netfilter/

For libnftnl, there is a number of library API tests.

This is what we have by now.

> SNPRINTF_BUFFER_SIZE() rejects truncation of the string by asserting
> against it. That behavior is part of the API of that function. Error
> checking after an assert seems unnecessary.
> 
> The check "if (len == NF_LOG_PREFIXLEN)" seems wrong anyway. After
> truncation, "len" would be zero. The code previously checked whether
> nothing was appended, but the error string didn't match that situation.
> 
> Maybe SNPRINTF_BUFFER_SIZE() should not assert against truncation?

IIRC, the goal for this function was to handle snprintf() and all its
corner cases. If there is no need for it or a better way to do this,
this is welcome.

  reply	other threads:[~2023-08-28 16:05 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-28 14:43 [PATCH nft 0/8] fix compiler warnings with clang Thomas Haller
2023-08-28 14:43 ` [PATCH nft 1/8] netlink: avoid "-Wenum-conversion" warning in dtype_map_from_kernel() Thomas Haller
2023-08-28 14:43 ` [PATCH nft 2/8] netlink: avoid "-Wenum-conversion" warning in parser_bison.y Thomas Haller
2023-08-28 14:43 ` [PATCH nft 3/8] src: use "%zx" format instead of "%Zx" Thomas Haller
2023-08-28 14:43 ` [PATCH nft 4/8] datatype: avoid cast-align warning with struct sockaddr result from getaddrinfo() Thomas Haller
2023-08-28 14:43 ` [PATCH nft 5/8] src: rework SNPRINTF_BUFFER_SIZE() and avoid "-Wunused-but-set-variable" Thomas Haller
2023-08-28 15:13   ` Pablo Neira Ayuso
2023-08-28 15:49     ` Thomas Haller
2023-08-28 16:04       ` Pablo Neira Ayuso [this message]
2023-08-28 16:45         ` Thomas Haller
2023-08-28 19:53           ` Pablo Neira Ayuso
2023-08-29 13:01             ` Thomas Haller
2023-08-28 14:43 ` [PATCH nft 6/8] src: suppress "-Wunused-but-set-variable" warning with "parser_bison.c" Thomas Haller
2023-08-28 14:43 ` [PATCH nft 7/8] utils: add _NFT_PRAGMA_WARNING_DISABLE()/_NFT_PRAGMA_WARNING_REENABLE helpers Thomas Haller
2023-08-28 14:43 ` [PATCH nft 8/8] datatype: suppress "-Wformat-nonliteral" warning in integer_type_print() Thomas Haller
2023-08-28 15:08   ` Pablo Neira Ayuso
2023-08-28 15:33     ` Thomas Haller
2023-08-28 15:54       ` Pablo Neira Ayuso
2023-08-28 16:24         ` Thomas Haller

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=ZOzFgtwJI6AasAYZ@calendula \
    --to=pablo@netfilter.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=thaller@redhat.com \
    /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 NNTP newsgroup(s).