svn commit: r226407 - stable/9/sys/kern

Robert Watson rwatson at FreeBSD.org
Sat Oct 15 22:27:59 UTC 2011


Author: rwatson
Date: Sat Oct 15 22:27:59 2011
New Revision: 226407
URL: http://svn.freebsd.org/changeset/base/226407

Log:
  Merge r226301 from head to stable/9:
  
    Correct a bug in export of capability-related information from the sysctls
    supporting procstat -f: properly provide capability rights information to
    userspace.  The bug resulted from a merge-o during upstreaming (or rather,
    a failure to properly merge FreeBSD-side changed downstream).
  
    Spotted by:     des, kibab
  
  Approved by:	re (kib)

Modified:
  stable/9/sys/kern/kern_descrip.c

Modified: stable/9/sys/kern/kern_descrip.c
==============================================================================
--- stable/9/sys/kern/kern_descrip.c	Sat Oct 15 22:27:35 2011	(r226406)
+++ stable/9/sys/kern/kern_descrip.c	Sat Oct 15 22:27:59 2011	(r226407)
@@ -3182,7 +3182,8 @@ CTASSERT(sizeof(struct kinfo_file) == KI
 
 static int
 export_fd_for_sysctl(void *data, int type, int fd, int fflags, int refcnt,
-    int64_t offset, struct kinfo_file *kif, struct sysctl_req *req)
+    int64_t offset, int fd_is_cap, cap_rights_t fd_cap_rights,
+    struct kinfo_file *kif, struct sysctl_req *req)
 {
 	struct {
 		int	fflag;
@@ -3243,6 +3244,10 @@ export_fd_for_sysctl(void *data, int typ
 	for (i = 0; i < NFFLAGS; i++)
 		if (fflags & fflags_table[i].fflag)
 			kif->kf_flags |=  fflags_table[i].kf_fflag;
+	if (fd_is_cap)
+		kif->kf_flags |= KF_FLAG_CAPABILITY;
+	if (fd_is_cap)
+		kif->kf_cap_rights = fd_cap_rights;
 	kif->kf_fd = fd;
 	kif->kf_type = type;
 	kif->kf_ref_count = refcnt;
@@ -3270,7 +3275,8 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 	int64_t offset;
 	void *data;
 	int error, i, *name;
-	int type, refcnt, fflags;
+	int fd_is_cap, type, refcnt, fflags;
+	cap_rights_t fd_cap_rights;
 
 	name = (int *)arg1;
 	if ((p = pfind((pid_t)name[0])) == NULL)
@@ -3299,13 +3305,13 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 	kif = malloc(sizeof(*kif), M_TEMP, M_WAITOK);
 	if (tracevp != NULL)
 		export_fd_for_sysctl(tracevp, KF_TYPE_VNODE, KF_FD_TYPE_TRACE,
-		    FREAD | FWRITE, -1, -1, kif, req);
+		    FREAD | FWRITE, -1, -1, 0, 0, kif, req);
 	if (textvp != NULL)
 		export_fd_for_sysctl(textvp, KF_TYPE_VNODE, KF_FD_TYPE_TEXT,
-		    FREAD, -1, -1, kif, req);
+		    FREAD, -1, -1, 0, 0, kif, req);
 	if (cttyvp != NULL)
 		export_fd_for_sysctl(cttyvp, KF_TYPE_VNODE, KF_FD_TYPE_CTTY,
-		    FREAD | FWRITE, -1, -1, kif, req);
+		    FREAD | FWRITE, -1, -1, 0, 0, kif, req);
 	if (fdp == NULL)
 		goto fail;
 	FILEDESC_SLOCK(fdp);
@@ -3315,7 +3321,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 		data = fdp->fd_cdir;
 		FILEDESC_SUNLOCK(fdp);
 		export_fd_for_sysctl(data, KF_TYPE_VNODE, KF_FD_TYPE_CWD,
-		    FREAD, -1, -1, kif, req);
+		    FREAD, -1, -1, 0, 0, kif, req);
 		FILEDESC_SLOCK(fdp);
 	}
 	/* root directory */
@@ -3324,7 +3330,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 		data = fdp->fd_rdir;
 		FILEDESC_SUNLOCK(fdp);
 		export_fd_for_sysctl(data, KF_TYPE_VNODE, KF_FD_TYPE_ROOT,
-		    FREAD, -1, -1, kif, req);
+		    FREAD, -1, -1, 0, 0, kif, req);
 		FILEDESC_SLOCK(fdp);
 	}
 	/* jail directory */
@@ -3333,13 +3339,15 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 		data = fdp->fd_jdir;
 		FILEDESC_SUNLOCK(fdp);
 		export_fd_for_sysctl(data, KF_TYPE_VNODE, KF_FD_TYPE_JAIL,
-		    FREAD, -1, -1, kif, req);
+		    FREAD, -1, -1, 0, 0, kif, req);
 		FILEDESC_SLOCK(fdp);
 	}
 	for (i = 0; i < fdp->fd_nfiles; i++) {
 		if ((fp = fdp->fd_ofiles[i]) == NULL)
 			continue;
 		data = NULL;
+		fd_is_cap = 0;
+		fd_cap_rights = 0;
 
 #ifdef CAPABILITIES
 		/*
@@ -3348,8 +3356,8 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 		 * the capability rights mask.
 		 */
 		if (fp->f_type == DTYPE_CAPABILITY) {
-			kif->kf_flags |= KF_FLAG_CAPABILITY;
-			kif->kf_cap_rights = cap_rights(fp);
+			fd_is_cap = 1;
+			fd_cap_rights = cap_rights(fp);
 			(void)cap_funwrap(fp, 0, &fp);
 		}
 #else /* !CAPABILITIES */
@@ -3428,8 +3436,8 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 		oldidx = req->oldidx;
 		if (type == KF_TYPE_VNODE || type == KF_TYPE_FIFO)
 			FILEDESC_SUNLOCK(fdp);
-		error = export_fd_for_sysctl(data, type, i,
-		    fflags, refcnt, offset, kif, req);
+		error = export_fd_for_sysctl(data, type, i, fflags, refcnt,
+		    offset, fd_is_cap, fd_cap_rights, kif, req);
 		if (type == KF_TYPE_VNODE || type == KF_TYPE_FIFO)
 			FILEDESC_SLOCK(fdp);
 		if (error) {


More information about the svn-src-stable-9 mailing list