name field of struct shmdir_name

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Thu Sep 4 18:21:04 GMT 2025



On 03/09/25 18:33, Prasanna Paithankar via Libc-help wrote:
> (Let me know if this should go in the libc-alpha thread, wanted to
> know opinions before commiting)
> 
> Greetings,
> In struct shmdir_name (defined in include/shm-directory.h), the name
> field is defined to be of length = 269  (10 + 4 + 255).
> 
> ----- code for reference (include/shm-directory.h)
> 
> /* The directory that contains shared POSIX objects. */
> #define SHMDIR _PATH_DEV "shm/"
> 
> struct shmdir_name
> {
>  /* The combined prefix/name. The sizeof includes the terminating
>  NUL byte. 4 bytes are needed for the optional "sem." prefix. */
>  char name[sizeof (SHMDIR) + 4 + NAME_MAX];
> };
> -----
> 
> This struct is used by shm_open and sem_open, which use openat syscall
> to create a file.
> 
> The openat will throw an error ENAMETOOLONG if the length of the file
> name is greater than NAME_MAX (=255 mostly).
> 
> Consider the implementation snippet of __shm_get_name where it tries
> to validate and form a valid file path in /dev/shm
> 
> ----- code for reference (posix/shm-directory.c)
> 
> while (name[0] == '/')
>  ++name;
> namelen = strlen (name);
> if (sem_prefix)
>  alloc_buffer_copy_bytes (&buffer, "sem.", strlen ("sem."));
> alloc_buffer_copy_bytes (&buffer, name, namelen + 1);
> if (namelen == 0 || memchr (name, '/', namelen) != NULL)
>  return EINVAL;
> if (alloc_buffer_has_failed (&buffer))
> {
>  if (namelen > NAME_MAX)
>   return ENAMETOOLONG;
>  return EINVAL;
> }
> -----
> 
> Proposition:
> Can the "+ 4" be removed from the struct definition?
> 
> Reasoning:
> For semaphore, if the input name length lies between 252-255 both
> inclusive, the function __shm_get_name returns successfully (as
> namelen < NAME_MAX and buffer has + 4 to contain sem.)
> but then eventually fails at openat (as appending sem. overflows NAME_MAX)
> Therefore, we can remove the + 4 and perform checks on length in
> if (sem_prefix)
> {
>  if (namelen + strlen("sem.") > NAME_MAX) return ENAMETOOLONG;
>  alloc_buffer_copy_bytes (&buffer, "sem.", strlen ("sem."));
> }
> 
> Similarly, for shm_open call, the __shm_get_name is successful even
> when the name length is lets say 256 (as alloc_buffer_has_failed
> (&buffer) is false) but then will eventually fail at  openat.
> So ,we also put a namelen check in a new else statement as > NAME_MAX.
> 
> This removes the + 4 in the name field of the struct.

Indeed the plus '+4' is superfluous in the struct definition.  I think you will
need to adjust to proper return ENAMETOOLONG instead of EINVAL for long names.



More information about the Libc-help mailing list