Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-3-0]: src/sys Apply patch (requested by mlelstv in ticket #2004):
details: https://anonhg.NetBSD.org/src/rev/bd9f1e4ac512
branches: netbsd-3-0
changeset: 579525:bd9f1e4ac512
user: snj <snj%NetBSD.org@localhost>
date: Sat Apr 11 06:21:23 2009 +0000
description:
Apply patch (requested by mlelstv in ticket #2004):
Avoid deep recursion and file descriptor exhaustion.
1. unp_detach: go not call unp_gc directly for descriptors
that are unixdomain sockets themselves. Instead mark them
for cleanup during garbage collection.
2. unp_gc: handle detach of descriptors that were marked earlier.
3. prohibit transfer of descriptors within SCM_RIGHTS messages if
(num_files_in_transit > maxfiles / unp_rights_ratio)
diffstat:
sys/kern/uipc_usrreq.c | 38 ++++++++++++++++++++++++++++++++++++--
sys/sys/file.h | 5 +++--
2 files changed, 39 insertions(+), 4 deletions(-)
diffs (116 lines):
diff -r 4effea748c3e -r bd9f1e4ac512 sys/kern/uipc_usrreq.c
--- a/sys/kern/uipc_usrreq.c Fri Mar 27 10:45:16 2009 +0000
+++ b/sys/kern/uipc_usrreq.c Sat Apr 11 06:21:23 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uipc_usrreq.c,v 1.80.2.1.2.1 2007/08/26 20:27:40 bouyer Exp $ */
+/* $NetBSD: uipc_usrreq.c,v 1.80.2.1.2.2 2009/04/11 06:21:23 snj Exp $ */
/*-
* Copyright (c) 1998, 2000, 2004 The NetBSD Foundation, Inc.
@@ -103,7 +103,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.80.2.1.2.1 2007/08/26 20:27:40 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.80.2.1.2.2 2009/04/11 06:21:23 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -523,6 +523,7 @@
u_long unpdg_recvspace = 4*1024;
int unp_rights; /* file descriptors in flight */
+int unp_rights_ratio = 2; /* limit, fraction of maxfiles */
int
unp_attach(struct socket *so)
@@ -959,6 +960,7 @@
int i, fd, *fdp;
int nfds;
u_int neededspace;
+ u_int maxmsg;
/* Sanity check the control message header */
if (cm->cmsg_type != SCM_RIGHTS || cm->cmsg_level != SOL_SOCKET ||
@@ -967,6 +969,11 @@
/* Verify that the file descriptors are valid */
nfds = (cm->cmsg_len - CMSG_ALIGN(sizeof(*cm))) / sizeof(int);
+
+ maxmsg = maxfiles / unp_rights_ratio;
+ if (unp_rights + nfds > maxmsg)
+ return (EAGAIN);
+
fdp = (int *)CMSG_DATA(cm);
for (i = 0; i < nfds; i++) {
fd = *fdp++;
@@ -1150,6 +1157,8 @@
if (fp->f_count == fp->f_msgcount)
continue;
}
+ if (fp->f_iflags & FIF_DISCARDED)
+ continue;
fp->f_flag |= FMARK;
if (fp->f_type != DTYPE_SOCKET ||
@@ -1255,6 +1264,14 @@
for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
fp = *fpp;
simple_lock(&fp->f_slock);
+ if (fp->f_iflags & FIF_DISCARDED) {
+ fp->f_usecount++;
+ fp->f_msgcount--;
+ simple_unlock(&fp->f_slock);
+ unp_rights--;
+ (void) closef(fp, (struct lwp *)0);
+ simple_lock(&fp->f_slock);
+ }
FILE_USE(fp);
(void) closef(fp, (struct proc *)0);
}
@@ -1339,7 +1356,24 @@
{
if (fp == NULL)
return;
+
simple_lock(&fp->f_slock);
+ /*
+ * closing unix domain sockets may cause a deep
+ * recursion, so leave them open and mark them
+ * for the garbage collector to discard them safely.
+ */
+ if (fp->f_type == DTYPE_SOCKET && fp->f_count == 1) {
+ struct socket *so;
+
+ so = (struct socket *)fp->f_data;
+ if (so && so->so_proto->pr_domain == &unixdomain &&
+ (so->so_proto->pr_flags&PR_RIGHTS) != 0) {
+ fp->f_iflags |= FIF_DISCARDED;
+ simple_unlock(&fp->f_slock);
+ return;
+ }
+ }
fp->f_usecount++; /* i.e. FILE_USE(fp) sans locking */
fp->f_msgcount--;
simple_unlock(&fp->f_slock);
diff -r 4effea748c3e -r bd9f1e4ac512 sys/sys/file.h
--- a/sys/sys/file.h Fri Mar 27 10:45:16 2009 +0000
+++ b/sys/sys/file.h Sat Apr 11 06:21:23 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: file.h,v 1.53 2005/02/12 23:14:03 christos Exp $ */
+/* $NetBSD: file.h,v 1.53.14.1 2009/04/11 06:21:23 snj Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -94,9 +94,10 @@
#define FIF_WANTCLOSE 0x01 /* a close is waiting for usecount */
#define FIF_LARVAL 0x02 /* not fully constructed; don't use */
+#define FIF_DISCARDED 0x04 /* file is discarded, pending close */
#define FILE_IS_USABLE(fp) (((fp)->f_iflags & \
- (FIF_WANTCLOSE|FIF_LARVAL)) == 0)
+ (FIF_WANTCLOSE|FIF_LARVAL|FIF_DISCARDED)) == 0)
#define FILE_SET_MATURE(fp) \
do { \
Home |
Main Index |
Thread Index |
Old Index