Re: /proc/pid/fd/ shows strange mode when executed via sudo.

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

 



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


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux