Re: [PATCH nft 5/5] datatype: check against negative "type" argument in datatype_lookup()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2023-08-30 at 09:46 +0200, Pablo Neira Ayuso wrote:
> On Tue, Aug 29, 2023 at 09:58:53PM +0200, Thomas Haller wrote:
> > On Tue, 2023-08-29 at 21:14 +0200, Pablo Neira Ayuso wrote:
> > > On Tue, Aug 29, 2023 at 09:10:26PM +0200, Pablo Neira Ayuso
> > > wrote:
> > > > On Tue, Aug 29, 2023 at 08:54:11PM +0200, Thomas Haller wrote:
> > > > > An enum can be either signed or unsigned (implementation
> > > > > defined).
> > > > > 
> > > > > datatype_lookup() checks for invalid type arguments. Also
> > > > > check,
> > > > > whether
> > > > > the argument is not negative (which, depending on the
> > > > > compiler it
> > > > > may
> > > > > never be).
> > > > > 
> > > > > Signed-off-by: Thomas Haller <thaller@xxxxxxxxxx>
> > > > > ---
> > > > >  src/datatype.c | 2 +-
> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/src/datatype.c b/src/datatype.c
> > > > > index ba1192c83595..91735ff8b360 100644
> > > > > --- a/src/datatype.c
> > > > > +++ b/src/datatype.c
> > > > > @@ -87,7 +87,7 @@ const struct datatype *datatype_lookup(enum
> > > > > datatypes type)
> > > > >  {
> > > > >         BUILD_BUG_ON(TYPE_MAX & ~TYPE_MASK);
> > > > >  
> > > > > -       if (type > TYPE_MAX)
> > > > > +       if ((uintmax_t) type > TYPE_MAX)
> > > > 
> > > >             uint32_t ?
> > 
> > The more straight forward way would be
> > 
> >     if (type < 0 || type > TYPE_MAX)
> > 
> > However, if the enum is unsigned, then the compiler might see that
> > the
> > condition is never true and warn against that. It does warn, if
> > "type"
> > were just an "unsigned int". I cannot actually reproduce a compiler
> > warning with the enum (for now).
> 
> Then, better keep it back?
> 
> > The size of the enum is most likely int/unsigned (or smaller, with
> > "-
> > fshort-enums" or packed). Is it on POSIX/Linux always guaranteed
> > that
> > an int is 32bit? I think not, but I cannot find an architecture
> > where
> > int is larger either. Also, if someone would add an enum value
> > larger
> > than the 32 bit range, then the behavior is compiler dependent, but
> > most likely the enum type would be a 64 bit integer and
> > "uint"/"uint32_t" would not be the right check.
> 
> I don't expect to ever have such a large number of types.
> Specifically
> because there are API restrictions that apply in this case.
> 
> > All of this is highly theoretical. But "uintmax_t" avoids all those
> > problems and makes fewer assumptions on what the enum actually is.
> > Is
> > there a hypothetical scenario where it wouldn't work correctly?
> 
> I was trying to figure out what this is fixing.
> 
> > > Another question: What warning does clang print on this one?
> > > Description does not specify.
> > 
> > this one isn't about a compiler warning. Sorry, I should not have
> > included it in this set.
> 
> This TYPE_MAX will not ever become very large to require 64-bits.

TYPE_MAX is not relevant.

> With an implementation where enum is taken as signed, then this
> should
> be sufficient too:
> 
>      if (type > TYPE_MAX)
> 
> If this is not fixing up anything right now, I would prefer to keep
> this back.

I don't think it suffices. The following fail the assertion (or would
access out of bounds).


diff --git c/include/datatype.h i/include/datatype.h
index 9ce7359cd340..7d3b6b20d27c 100644
--- c/include/datatype.h
+++ i/include/datatype.h
@@ -98,7 +98,8 @@ enum datatypes {
     TYPE_TIME_HOUR,
     TYPE_TIME_DAY,
     TYPE_CGROUPV2,
-    __TYPE_MAX
+    __TYPE_MAX,
+    __TYPE_FORCE_SIGNED = -1,
 };
 #define TYPE_MAX        (__TYPE_MAX - 1)
 
diff --git c/src/datatype.c i/src/datatype.c
index ba1192c83595..1ff8a4a08551 100644
--- c/src/datatype.c
+++ i/src/datatype.c
@@ -89,6 +89,7 @@ const struct datatype *datatype_lookup(enum datatypes
type)
 
     if (type > TYPE_MAX)
          return NULL;
+    assert(type != (enum datatypes) -1);
     return datatypes[type];
 }
 
diff --git c/src/libnftables.c i/src/libnftables.c
index 9c802ec95f27..7e60d1a18d39 100644
--- c/src/libnftables.c
+++ i/src/libnftables.c
@@ -203,6 +203,8 @@ struct nft_ctx *nft_ctx_new(uint32_t flags)
 #endif
     }
 
+    datatype_lookup(-1);
+
     ctx = xzalloc(sizeof(struct nft_ctx));
     nft_init(ctx);
 



If you expect that "type" is always valid, then there is no need to
check against >TYPE_MAX. If you expect that it might be invalid, it
seems prudent to also check against negative values.



Thomas





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux