This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix readdir_r with long file names


+#ifdef NAME_MAX
+      if (reclen > offsetof (DIRENT_TYPE, d_name) + NAME_MAX + 1)
+ {
+  /* The record is very long.  It could still fit into the
+     caller-supplied buffer if we can skip padding at the
+     end.  */
+  size_t namelen = strlen(dp->d_name);
+  if (namelen <= NAME_MAX)
+    reclen = offsetof (DIRENT_TYPE, d_name) + namelen + 1;
+  else
+    {
+      /* The name is too long.  Ignore this file.  */
+      dirp->errcode = ENAMETOOLONG;
+      dp->d_ino = 0;
+      continue;
+    }
+ }
+#endif

Hmm...
Linux man pages say:

>Since POSIX.1 does not specify the size of the d_name field, and other
>nonstandard fields may precede that field within the dirent structure, portable
>applications that use readdir_r() should allocate the buffer whose address is
>passed in entry as follows:
>
> name_max = pathconf(dirpath, _PC_NAME_MAX);
> if (name_max == -1)         /* Limit not defined, or error */
>    name_max = 255;         /* Take a guess */
> len = offsetof(struct dirent, d_name) + name_max + 1;
> entryp = malloc(len);
> (POSIX.1 requires that d_name is the last field in a struct dirent.)

So, only broken applications may hit this? If so, do you really think such
broken application checks return code correctly?

If a fuse filesystem which allow >256 file names is legal, this patch breaks
right applications. In the other hands, if it is illegal, I'd suggest
to fix such
broken filesystems instead.

I mean, portable applications should use readdir_r correctly and Linux specific
one should use readdir instead.

Side note: the above man page is not a theoretical issue. At least, Solaris
requires it.

Am I missing something?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]