Applied, thanks!

Milos Nikic, le ven. 27 mars 2026 20:54:58 -0700, a ecrit:
> In diskfs_lookup (and its variants), the enum lookup_type is passed in and
> expected. However, this base type is sometimes OR'd with SPEC_DOTDOT,
> creating a bitwise value (e.g., 268435459 on 64-bit architectures) that
> falls outside the valid range of the lookup_type enum. In modern C, this
> results in Undefined Behavior (UB) and triggers static analyzer warnings.
> 
> Replace the use of the raw enum in these function signatures with a
> dedicated typedef (lookup_flags_t). This avoids the UB, modernizes the
> API, and safely signals that bitwise math is expected, improving overall
> type safety.
> 
> This patch also adds include diskfs.h in places where its needed, and removes
> one priv.h from where it isn't needed.
> ---
>  ext2fs/dir.c       | 12 +++++++-----
>  fatfs/dir.c        | 12 +++++++-----
>  isofs/lookup.c     | 10 ++++++----
>  libdiskfs/diskfs.h | 11 +++++++++--
>  libdiskfs/lookup.c | 20 ++++++++++----------
>  tmpfs/dir.c        | 11 ++++++-----
>  6 files changed, 45 insertions(+), 31 deletions(-)
> 
> diff --git a/ext2fs/dir.c b/ext2fs/dir.c
> index 932340a4..55f26579 100644
> --- a/ext2fs/dir.c
> +++ b/ext2fs/dir.c
> @@ -20,6 +20,7 @@
>     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
>  
>  #include "ext2fs.h"
> +#include <libdiskfs/diskfs.h>
>  
>  #include <string.h>
>  #include <stdio.h>
> @@ -135,7 +136,7 @@ static const unsigned char file_type_ext2[] =
>  /* Implement the diskfs_lookup from the diskfs library.  See
>     <hurd/diskfs.h> for the interface specification.  */
>  error_t
> -diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type,
> +diskfs_lookup_hard (struct node *dp, const char *name, lookup_flags_t 
> l_flags,
>                   struct node **npp, struct dirstat *ds, struct protid *cred)
>  {
>    error_t err;
> @@ -145,22 +146,23 @@ diskfs_lookup_hard (struct node *dp, const char *name, 
> enum lookup_type type,
>    struct node *np = 0;
>    ino_t retry_dotdot = 0;
>    vm_prot_t prot =
> -    (type == LOOKUP) ? VM_PROT_READ : (VM_PROT_READ | VM_PROT_WRITE);
> +    (l_flags == LOOKUP) ? VM_PROT_READ : (VM_PROT_READ | VM_PROT_WRITE);
>    memory_object_t memobj;
>    vm_address_t buf = 0;
>    vm_size_t buflen = 0;
>    vm_address_t blockaddr;
>    int idx, lastidx;
>    int looped;
> +  enum lookup_type type;
>  
> -  if ((type == REMOVE) || (type == RENAME))
> +  if ((l_flags == REMOVE) || (l_flags == RENAME))
>      assert_backtrace (npp);
>  
>    if (npp)
>      *npp = 0;
>  
> -  spec_dotdot = type & SPEC_DOTDOT;
> -  type &= ~SPEC_DOTDOT;
> +  spec_dotdot = l_flags & SPEC_DOTDOT;
> +  type = l_flags & ~SPEC_DOTDOT;
>  
>    namelen = strlen (name);
>  
> diff --git a/fatfs/dir.c b/fatfs/dir.c
> index 1c71d68d..dbe243c6 100644
> --- a/fatfs/dir.c
> +++ b/fatfs/dir.c
> @@ -27,6 +27,7 @@
>  #include <hurd/fsys.h>
>  
>  #include "fatfs.h"
> +#include <libdiskfs/diskfs.h>
>  
>  /* The size of a directory block is usually just the cluster size.
>     However, the root directory of FAT12/16 file systems is stored in
> @@ -172,7 +173,7 @@ fatnamematch (const char *dirname, const char *username, 
> size_t unamelen)
>  /* Implement the diskfs_lookup callback from the diskfs library.  See
>     <hurd/diskfs.h> for the interface specification.  */
>  error_t
> -diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type,
> +diskfs_lookup_hard (struct node *dp, const char *name, lookup_flags_t 
> l_flags,
>                   struct node **npp, struct dirstat *ds, struct protid *cred)
>  {
>    error_t err;
> @@ -182,22 +183,23 @@ diskfs_lookup_hard (struct node *dp, const char *name, 
> enum lookup_type type,
>    struct node *np = 0;
>    int retry_dotdot = 0;
>    vm_prot_t prot =
> -    (type == LOOKUP) ? VM_PROT_READ : (VM_PROT_READ | VM_PROT_WRITE);
> +    (l_flags == LOOKUP) ? VM_PROT_READ : (VM_PROT_READ | VM_PROT_WRITE);
>    memory_object_t memobj;
>    vm_address_t buf = 0;
>    vm_size_t buflen = 0;
>    int blockaddr;
>    int idx, lastidx;
>    int looped;
> +  enum lookup_type type;
>  
> -  if ((type == REMOVE) || (type == RENAME))
> +  if ((l_flags == REMOVE) || (l_flags == RENAME))
>      assert_backtrace (npp);
>  
>    if (npp)
>      *npp = 0;
>  
> -  spec_dotdot = type & SPEC_DOTDOT;
> -  type &= ~SPEC_DOTDOT;
> +  spec_dotdot = l_flags & SPEC_DOTDOT;
> +  type = l_flags & ~SPEC_DOTDOT;
>  
>    namelen = strlen (name);
>  
> diff --git a/isofs/lookup.c b/isofs/lookup.c
> index b55aef96..d9322fac 100644
> --- a/isofs/lookup.c
> +++ b/isofs/lookup.c
> @@ -21,6 +21,7 @@
>  #include <string.h>
>  #include <stdlib.h>
>  #include <dirent.h>
> +#include <libdiskfs/diskfs.h>
>  #include "isofs.h"
>  
>  /* From inode.c */
> @@ -66,7 +67,7 @@ isonamematch (const char *dirname, size_t dnamelen,
>  /* Implement the diskfs_lookup callback from the diskfs library.  See
>     <hurd/diskfs.h> for the interface specification. */
>  error_t
> -diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type,
> +diskfs_lookup_hard (struct node *dp, const char *name, lookup_flags_t 
> l_flags,
>                   struct node **npp, struct dirstat *ds, struct protid *cred)
>  {
>    error_t err = ENOENT;
> @@ -76,15 +77,16 @@ diskfs_lookup_hard (struct node *dp, const char *name, 
> enum lookup_type type,
>    void *buf;
>    void *blockaddr;
>    ino_t id;
> +  enum lookup_type type;
>  
> -  if ((type == REMOVE) || (type == RENAME))
> +  if ((l_flags == REMOVE) || (l_flags == RENAME))
>      assert_backtrace (npp);
>  
>    if (npp)
>      *npp = 0;
>  
> -  spec_dotdot = type & SPEC_DOTDOT;
> -  type &= ~SPEC_DOTDOT;
> +  spec_dotdot = l_flags & SPEC_DOTDOT;
> +  type = l_flags & ~SPEC_DOTDOT;
>  
>    namelen = strlen (name);
>  
> diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
> index 5f832dd7..8f5db533 100644
> --- a/libdiskfs/diskfs.h
> +++ b/libdiskfs/diskfs.h
> @@ -146,6 +146,13 @@ enum lookup_type
>    RENAME,
>  };
>  
> +/**
> + * Represents a lookup_type optionally OR'd with lookup flags (SPEC_DOTDOT)
> + * We use a typedef rather than the raw enum to safely allow bitwise math
> + * without triggering undefined behavior or static analyzer warnings.
> + */
> +typedef int lookup_flags_t;
> +
>  /* Pending directory and file modification request */
>  struct modreq
>  {
> @@ -352,7 +359,7 @@ error_t diskfs_set_statfs (fsys_statfsbuf_t *statfsbuf);
>     Return EIO if appropriate.
>  */
>  error_t diskfs_lookup_hard (struct node *dp,
> -                         const char *name, enum lookup_type type,
> +                         const char *name, lookup_flags_t l_flags,
>                           struct node **np, struct dirstat *ds,
>                           struct protid *cred);
>  
> @@ -815,7 +822,7 @@ diskfs_disknode_node (struct disknode *disknode)
>     This function is a wrapper for diskfs_lookup_hard.
>  */
>  error_t diskfs_lookup (struct node *dp,
> -                    char *name, enum lookup_type type,
> +                    char *name, lookup_flags_t l_flags,
>                      struct node **np, struct dirstat *ds,
>                      struct protid *cred);
>  
> diff --git a/libdiskfs/lookup.c b/libdiskfs/lookup.c
> index 201613c3..87b54c01 100644
> --- a/libdiskfs/lookup.c
> +++ b/libdiskfs/lookup.c
> @@ -18,7 +18,7 @@
>     along with this program; if not, write to the Free Software
>     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
>  
> -#include "priv.h"
> +#include <libdiskfs/diskfs.h>
>  #include <string.h>
>  
>  /* Lookup in directory DP (which is locked) the name NAME.  TYPE will
> @@ -71,13 +71,13 @@
>  
>     This function is a wrapper for diskfs_lookup_hard.  */
>  error_t
> -diskfs_lookup (struct node *dp, char *name, enum lookup_type type,
> +diskfs_lookup (struct node *dp, char *name, lookup_flags_t l_flags,
>              struct node **np, struct dirstat *ds, struct protid *cred)
>  {
>    error_t err;
>    struct node *cached;
>  
> -  if (type == REMOVE || type == RENAME)
> +  if (l_flags == REMOVE || l_flags == RENAME)
>      assert_backtrace (np);
>  
>    if (!S_ISDIR (dp->dn_stat.st_mode))
> @@ -133,7 +133,7 @@ diskfs_lookup (struct node *dp, char *name, enum 
> lookup_type type,
>        return EAGAIN;
>      }
>  
> -  if (type == LOOKUP)
> +  if (l_flags == LOOKUP)
>      /* Check the cache first */
>      cached = diskfs_check_lookup_cache (dp, name);
>    else
> @@ -163,13 +163,13 @@ diskfs_lookup (struct node *dp, char *name, enum 
> lookup_type type,
>      }
>    else
>      {
> -      err = diskfs_lookup_hard (dp, name, type, np, ds, cred);
> +      err = diskfs_lookup_hard (dp, name, l_flags , np, ds, cred);
>        if (err && err != ENOENT)
>       return err;
>  
> -      if (type == RENAME
> -       || (type == CREATE && err == ENOENT)
> -       || (type == REMOVE && err != ENOENT))
> +      if (l_flags == RENAME
> +       || (l_flags == CREATE && err == ENOENT)
> +       || (l_flags == REMOVE && err != ENOENT))
>       {
>         error_t err2;
>  
> @@ -193,9 +193,9 @@ diskfs_lookup (struct node *dp, char *name, enum 
> lookup_type type,
>           }
>       }
>  
> -      if ((type == LOOKUP || type == CREATE) && !err && np)
> +      if ((l_flags == LOOKUP || l_flags == CREATE) && !err && np)
>       diskfs_enter_lookup_cache (dp, *np, name);
> -      else if (type == LOOKUP && err == ENOENT)
> +      else if (l_flags == LOOKUP && err == ENOENT)
>       diskfs_enter_lookup_cache (dp, 0, name);
>      }
>  
> diff --git a/tmpfs/dir.c b/tmpfs/dir.c
> index 8af2d070..75242b52 100644
> --- a/tmpfs/dir.c
> +++ b/tmpfs/dir.c
> @@ -21,6 +21,7 @@
>  #include <unistd.h>
>  #include <sys/mman.h>
>  
> +#include <libdiskfs/diskfs.h>
>  #include "tmpfs.h"
>  #include <stdlib.h>
>  
> @@ -169,18 +170,18 @@ diskfs_drop_dirstat (struct node *dp, struct dirstat 
> *ds)
>  
>  error_t
>  diskfs_lookup_hard (struct node *dp,
> -                 const char *name, enum lookup_type type,
> +                 const char *name, lookup_flags_t l_flags,
>                   struct node **np, struct dirstat *ds,
>                   struct protid *cred)
>  {
>    const size_t namelen = strlen (name);
>    struct tmpfs_dirent *d, **prevp;
>  
> -  if (type == REMOVE || type == RENAME)
> +  if (l_flags == REMOVE || l_flags == RENAME)
>      assert_backtrace (np);
>  
>    if (ds)
> -    ds->dotdot = type & SPEC_DOTDOT;
> +    ds->dotdot = l_flags & SPEC_DOTDOT;
>  
>    if (namelen == 1 && name[0] == '.')
>      {
> @@ -200,7 +201,7 @@ diskfs_lookup_hard (struct node *dp,
>        if (dddn == 0)         /* root directory */
>       return EAGAIN;
>  
> -      if (type == (REMOVE|SPEC_DOTDOT) || type == (RENAME|SPEC_DOTDOT))
> +      if (l_flags == (REMOVE|SPEC_DOTDOT) || l_flags == (RENAME|SPEC_DOTDOT))
>          {
>         *np = *dddn->hprevp;
>         assert_backtrace (*np);
> @@ -213,7 +214,7 @@ diskfs_lookup_hard (struct node *dp,
>         pthread_mutex_unlock (&dp->lock);
>            err = diskfs_cached_lookup ((ino_t) (intptr_t) dddn, np);
>  
> -       if (type == (LOOKUP|SPEC_DOTDOT))
> +       if (l_flags == (LOOKUP|SPEC_DOTDOT))
>           diskfs_nrele (dp);
>         else
>           pthread_mutex_lock (&dp->lock);
> -- 
> 2.53.0
> 
> 

-- 
Samuel
<A>  mr  -  remove the home of correct users who accidentally enter mr
<A>        instead of rm

Reply via email to