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 MFC after: 3 days
This commit is contained in:
parent
eb29e5f70d
commit
b160c14194
@ -3182,7 +3182,8 @@ CTASSERT(sizeof(struct kinfo_file) == KINFO_FILE_SIZE);
|
||||
|
||||
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 type, int fd, int fflags, int refcnt,
|
||||
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_ARGS)
|
||||
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_ARGS)
|
||||
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_ARGS)
|
||||
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_ARGS)
|
||||
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_ARGS)
|
||||
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_ARGS)
|
||||
* 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_ARGS)
|
||||
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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user