Hello. I noticed that /proc/self/fd/ returns wrong information to lstat() when files are open()ed after already opened files have been close()d in accordance with entries returned from opendir("/proc/self/fd"). Bisection reached to below commit added between 2.6.18 and 2.6.19-rc1. git bisect start '3f2e05e90e0846c42626e3d272454f26be34a1bc' 'e9ff3990f08e9a0c2839cc22808b01732ea5b3e4' '1651e14e28a2d9f446018ef522882e0709a2ce4f' '43fa1adb9334bf4585cd53144eb5911488f85bc7' '609d7fa9565c754428d2520cac2accc9052e1245' 'ee0b3e671baff681d69fbf0db33b47603c0a8280' 'cf342e52e3117391868fb4bd900ce772a27a5a1a' 'v2.6.18' 'v2.6.17' 'v2.6.16' 'v2.6.15' 'v2.6.14' 'v2.6.13' 'v2.6.12' git bisect good 5f4c6bc1f369f20807a8e753c2308d1629478c61 git bisect bad 5e6b3f42edc20e988b186fbfb9eec174294222ea git bisect good 801199ce805a2412bbcd9bfe213092ec656013dd git bisect bad 61a28784028e6d55755e4d0f39bee8d9bf2ee8d9 git bisect good 444ceed8d186631fdded5e3f24dc20b93d0d3fda Below commit replaced filldir() with proc_pident_fill_cache(). Eric, would you check (though no need to be urgent)? commit 61a28784028e6d55755e4d0f39bee8d9bf2ee8d9 Author: Eric W. Biederman <ebiederm@xxxxxxxxxxxx> Date: Mon Oct 2 02:18:49 2006 -0700 [PATCH] proc: Remove the hard coded inode numbers The hard coded inode numbers in proc currently limit its maintainability, its flexibility, and what can be done with the rest of system. /proc limits pid-max to 32768 on 32 bit systems it limits fd-max to 32768 on all systems, and placing the pid in the inode number really gets in the way of implementing subdirectories of per process information. Ever since people started adding to the middle of the file type enumeration we haven't been maintaing the historical inode numbers, all we have really succeeded in doing is keeping the pid in the proc inode number. The pid is already available in the directory name so no information is lost removing it from the inode number. So if something in user space cares if we remove the inode number from the /proc inode it is almost certainly broken. Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> Signed-off-by: Linus Torvalds <torvalds@xxxxxxxx> :040000 040000 1bf9577e5bab5f938e780de96ab79003523688ec 46f890c72c75bfb6ecaee8c985f5127bcf82eef3 M fs Tetsuo Handa wrote: > It turned out that /usr/bin/sudo is using /proc/self/fd/ for closing already > opened files. I made a simple demo program that can reproduce this regression. > > ---------- test.c start ---------- > #include <stdio.h> > #include <sys/types.h> > #include <sys/stat.h> > #include <fcntl.h> > #include <unistd.h> > #include <stdlib.h> > #include <dirent.h> > #include <string.h> > > static void opentest(void) > { > FILE *fp = fopen("/dev/tty", "a"); > int i; > char buffer[1024]; > memset(buffer, 0, sizeof(buffer)); > for (i = 0; i < 5; i++) { > struct stat buf; > int fd = open("/proc/self/exe", O_RDONLY); > if (fd == EOF) > break; > snprintf(buffer, sizeof(buffer) - 1, "/proc/self/fd/%u", fd); > if (lstat(buffer, &buf)) > continue; > if ((buf.st_mode & 0700) == 0700) { > char buffer2[1024]; > memset(buffer2, 0, sizeof(buffer2)); > readlink(buffer, buffer2, sizeof(buffer2) - 1); > fprintf(fp, "%s -> %s \n", buffer, buffer2); > } > } > } > > int main(int argc, char *argv[]) > { > DIR *dirp = (argc > 1) ? opendir("/proc/self/fd") : NULL; > if (dirp) { > struct dirent *dent; > fprintf(stderr, "closefrom with /proc/self/fd/\n"); > while ((dent = readdir(dirp)) != NULL) { > int fd; > if (sscanf(dent->d_name, "%u", &fd) == 1 && > fd != dirfd(dirp)) > close(fd); > } > closedir(dirp); > } else { > int fd; > fprintf(stderr, "closefrom without /proc/self/fd/\n"); > for (fd = 0; fd < 1024; fd++) > close(fd); > } > opentest(); > return 0; > } > ---------- test.c end ---------- > > [root@ccsecurity tmp]# ./a.out 1 > closefrom with /proc/self/fd/ > /proc/self/fd/1 -> /tmp/a.out > /proc/self/fd/2 -> /tmp/a.out > [root@ccsecurity tmp]# ./a.out > closefrom without /proc/self/fd/ > [root@ccsecurity tmp]# > > I tried on three kernels. > > 2.6.18-308.4.1.el5 : OK > 2.6.26-2-686 (2.6.26-26lenny4) : NG > 2.6.32-220.17.1.el6 : NG > > This regression seems to be introduced between 2.6.19 and 2.6.26. > This regression seems to involve opendir()/closedir() usage. > > Regards. > -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html