From netch@nn.kiev.ua  Sun Jun 18 04:34:44 2000
Return-Path: <netch@nn.kiev.ua>
Received: from segfault.kiev.ua (segfault.kiev.ua [193.193.193.4])
	by hub.freebsd.org (Postfix) with ESMTP id DAF6337B9B7
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 18 Jun 2000 04:34:34 -0700 (PDT)
	(envelope-from netch@nn.kiev.ua)
Received: from nn.kiev.ua (nn.kiev.ua [193.193.193.203])
	by segfault.kiev.ua (8) with ESMTP id ONG90624
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 18 Jun 2000 14:34:26 +0300 (EEST)
	(envelope-from netch@nn.kiev.ua)
Received: (from netch@localhost)
	by nn.kiev.ua (8.9.3/8.9.3) id OAA02185;
	Sun, 18 Jun 2000 14:34:27 +0300 (EEST)
	(envelope-from netch)
Message-Id: <200006181134.OAA02185@nn.kiev.ua>
Date: Sun, 18 Jun 2000 14:34:27 +0300 (EEST)
From: netch@segfault.kiev.ua (Valentin Nechayev)
Sender: netch@nn.kiev.ua
Reply-To: netch@segfault.kiev.ua
To: FreeBSD-gnats-submit@freebsd.org
Subject: Do allow processes know about their file descriptors, reliably & efficiently
X-Send-Pr-Version: 3.2

>Number:         19363
>Category:       kern
>Synopsis:       [kernel] [patch] allow processes know about their file descriptors, reliably & efficiently
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jun 18 04:40:01 PDT 2000
>Closed-Date:    Tue Jun 16 13:29:25 UTC 2009
>Last-Modified:  Tue Jun 16 13:29:25 UTC 2009
>Originator:     netch@netch.kiev.ua (Valentin Nechayev)
>Release:        FreeBSD
>Organization:
Kiev
>Environment:

FreeBSD

>Description:

The goal is described in synopsis field. I suppose it is really useful now.
Reasons (mostly in field of security):

1) On exec(), caller can pass any descriptor to called program. This can
be used for DoS attacks: i.e., sendmail slowly sends a letter and locks
some file system from unmounting. (The situation is semi phantastic,
but only "semi".)

2)

==={
root@nn:~##sysctl -a | grep chroot
kern.chroot_allow_open_directories: 1
root@nn:~##
===}

This is, of course, good idea ;|, but it is correct to provide more
flexibility for programs, isn't it? :)

3) Some programs (sendmail, uucico) try to close all extra files, but
they do it ugly and non-reliably (getdtablesize() does not report possible
descriptors which are more that soft rlimit). This ugly method should be
changed to something similar to
==={
	while ((o = getfd(GETFD_NEXT, 2)) != -1)
		close(o);
===}
and at least added to most setuid/setgid programs, for safety sake.

>How-To-Repeat:

;)

>Fix:

Add syscall with following implementation.

=== cut here ===
--- src/include/unistd.h.orig	Sat Jun 17 22:56:11 2000
+++ src/include/unistd.h	Sat Jun 17 22:57:39 2000
@@ -134,6 +134,7 @@
 #endif
 int	 getdomainname __P((char *, int));
 int	 getdtablesize __P((void));
+int	 getfd __P((int, int));
 int	 getgrouplist __P((const char *, int, int *, int *));
 long	 gethostid __P((void));
 int	 gethostname __P((char *, int));
--- kern_descrip.c.orig	Fri Jun 16 00:05:49 2000
+++ kern_descrip.c	Sat Jun 17 23:18:40 2000
@@ -124,6 +124,49 @@
 }
 
 /*
+ * Query used descriptors
+ */
+#ifndef _SYS_SYSPROTO_H_
+struct getfd_args {
+	int query;
+	int param;
+};
+#endif
+int
+getfd(p, uap)
+	struct proc *p;
+	struct getfd_args *uap;
+{
+	register struct filedesc *fdp = p->p_fd;
+	register int i;
+	if (uap->query == GETFD_NEXT) {
+		i = uap->param + 1;
+		if (i < 0)
+			i = 0;
+		for (; i < fdp->fd_nfiles; i++) {
+			if (fdp->fd_ofiles[i] != NULL) {
+				p->p_retval[0] = i;
+				return (0);
+			}
+		}
+		return (EBADF);
+	}
+	if (uap->query == GETFD_PREV) {
+		i = uap->param - 1;
+		if (i < 0 || i >= fdp->fd_nfiles)
+			i = fdp->fd_nfiles - 1;
+		for (; i >= 0; i--) {
+			if (fdp->fd_ofiles[i] != NULL) {
+				p->p_retval[0] = i;
+				return (0);
+			}
+		}
+		return (EBADF);
+	}
+	return (EINVAL);
+}
+
+/*
  * Duplicate a file descriptor to a particular value.
  */
 #ifndef _SYS_SYSPROTO_H_
--- src/sys/kern/syscalls.master.orig	Sun Jun 18 14:16:27 2000
+++ src/sys/kern/syscalls.master	Sun Jun 18 14:17:07 2000
@@ -520,3 +520,4 @@
 			    int nchanges, struct kevent **changelist, \
 			    int nevents, struct kevent *eventlist, \
 			    struct timespec *timeout); }
+364	STD	BSD	{ int getfd( int query, int param); }
--- src/sys/sys/unistd.h.orig	Wed May 10 08:16:11 2000
+++ src/sys/sys/unistd.h	Sat Jun 17 23:00:49 2000
@@ -219,6 +219,12 @@
 #define RFLINUXTHPN     (1<<16) /* do linux clone exit parent notification */
 #define RFPPWAIT	(1<<31) /* parent sleeps until child exits (vfork) */
 
+/*
+ * getfd() queries
+ */
+#define GETFD_NEXT	0
+#define GETFD_PREV	1
+
 #endif /* !_POSIX_SOURCE */
 
 #endif /* !_SYS_UNISTD_H_ */
=== end cut ===

Selected syscall number, of course, does not matter.;) Iteration in both
upper and lower should be sufficient for first time. Possible progress
for next extension may be adding filter on f_type field value of struct file.

PS. Possibly, MPSAFE can be added to getfd() syscall description.

--
NVA

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->suspended 
State-Changed-By: linimon 
State-Changed-When: Mon Oct 24 02:14:21 GMT 2005 
State-Changed-Why:  
Mark as 'suspended' since this does not seem as though it is being 
actively worked on. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=19363 

From: Valentin Nechayev <netch@netch.kiev.ua>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/19363: [kernel] [patch] allow processes know about their
 file descriptors, reliably 
Date: Wed, 05 Jul 2006 17:18:55 +0300

 1. Another bad behaved program is erlang:( Closing all descriptors up to 
 rlimit (7264 now at my system)
 2. Now I think this shall be not separate syscall, but fcntl() 
 subcommand; changes are trivial
 
 
 -netch-
 
State-Changed-From-To: suspended->closed 
State-Changed-By: jhb 
State-Changed-When: Tue Jun 16 13:29:01 UTC 2009 
State-Changed-Why:  
This functionality has been implemented as a new closefrom(2) system call. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=19363 
>Unformatted:
