svn commit: r192144 - head/sys/kern

Konstantin Belousov kib at FreeBSD.org
Fri May 15 14:41:46 UTC 2009


Author: kib
Date: Fri May 15 14:41:44 2009
New Revision: 192144
URL: http://svn.freebsd.org/changeset/base/192144

Log:
  Revert r192094. The revision caused problems for sysctl(3) consumers
  that expect that oldlen is filled with required buffer length even when
  supplied buffer is too short and returned error is ENOMEM.
  
  Redo the fix for kern.proc.filedesc, by reverting the req->oldidx when
  remaining buffer space is too short for the current kinfo_file structure.
  Also, only ignore ENOMEM. We have to convert ENOMEM to no error condition
  to keep existing interface for the sysctl, though.
  
  Reported by:	ed, Florian Smeets <flo kasimir com>
  Tested by:	pho

Modified:
  head/sys/kern/kern_descrip.c
  head/sys/kern/kern_sysctl.c

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Fri May 15 14:30:37 2009	(r192143)
+++ head/sys/kern/kern_descrip.c	Fri May 15 14:41:44 2009	(r192144)
@@ -2883,6 +2883,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 	struct proc *p;
 	struct tty *tp;
 	int vfslocked;
+	size_t oldidx;
 
 	name = (int *)arg1;
 	if ((p = pfind((pid_t)name[0])) == NULL)
@@ -3061,14 +3062,26 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 		    strlen(kif->kf_path) + 1;
 		kif->kf_structsize = roundup(kif->kf_structsize,
 		    sizeof(uint64_t));
+		oldidx = req->oldidx;
 		error = SYSCTL_OUT(req, kif, kif->kf_structsize);
-		if (error)
+		if (error) {
+			if (error == ENOMEM) {
+				/*
+				 * The hack to keep the ABI of sysctl
+				 * kern.proc.filedesc intact, but not
+				 * to account a partially copied
+				 * kinfo_file into the oldidx.
+				 */
+				req->oldidx = oldidx;
+				error = 0;
+			}
 			break;
+		}
 	}
 	FILEDESC_SUNLOCK(fdp);
 	fddrop(fdp);
 	free(kif, M_TEMP);
-	return (0);
+	return (error);
 }
 
 static SYSCTL_NODE(_kern_proc, KERN_PROC_FILEDESC, filedesc, CTLFLAG_RD,

Modified: head/sys/kern/kern_sysctl.c
==============================================================================
--- head/sys/kern/kern_sysctl.c	Fri May 15 14:30:37 2009	(r192143)
+++ head/sys/kern/kern_sysctl.c	Fri May 15 14:41:44 2009	(r192144)
@@ -1223,9 +1223,9 @@ sysctl_old_kernel(struct sysctl_req *req
 		if (i > 0)
 			bcopy(p, (char *)req->oldptr + req->oldidx, i);
 	}
+	req->oldidx += l;
 	if (req->oldptr && i != l)
 		return (ENOMEM);
-	req->oldidx += l;
 	return (0);
 }
 
@@ -1322,10 +1322,9 @@ sysctl_old_user(struct sysctl_req *req, 
 	size_t i, len, origidx;
 
 	origidx = req->oldidx;
-	if (req->oldptr == NULL) {
-		req->oldidx += l;
+	req->oldidx += l;
+	if (req->oldptr == NULL)
 		return (0);
-	}
 	/*
 	 * If we have not wired the user supplied buffer and we are currently
 	 * holding locks, drop a witness warning, as it's possible that
@@ -1347,7 +1346,6 @@ sysctl_old_user(struct sysctl_req *req, 
 		return (error);
 	if (i < l)
 		return (ENOMEM);
-	req->oldidx += l;
 	return (0);
 }
 


More information about the svn-src-head mailing list