Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/uipc_shm.c
Show First 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/mman.h> | #include <sys/mman.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/priv.h> | #include <sys/priv.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/refcount.h> | #include <sys/refcount.h> | ||||
#include <sys/resourcevar.h> | #include <sys/resourcevar.h> | ||||
#include <sys/rwlock.h> | #include <sys/rwlock.h> | ||||
#include <sys/sbuf.h> | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/syscallsubr.h> | #include <sys/syscallsubr.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/sysproto.h> | #include <sys/sysproto.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/sx.h> | #include <sys/sx.h> | ||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
▲ Show 20 Lines • Show All 327 Lines • ▼ Show 20 Lines | #endif | ||||
sb->st_mtim = shmfd->shm_mtime; | sb->st_mtim = shmfd->shm_mtime; | ||||
sb->st_birthtim = shmfd->shm_birthtime; | sb->st_birthtim = shmfd->shm_birthtime; | ||||
sb->st_mode = S_IFREG | shmfd->shm_mode; /* XXX */ | sb->st_mode = S_IFREG | shmfd->shm_mode; /* XXX */ | ||||
sb->st_uid = shmfd->shm_uid; | sb->st_uid = shmfd->shm_uid; | ||||
sb->st_gid = shmfd->shm_gid; | sb->st_gid = shmfd->shm_gid; | ||||
mtx_unlock(&shm_timestamp_lock); | mtx_unlock(&shm_timestamp_lock); | ||||
sb->st_dev = shm_dev_ino; | sb->st_dev = shm_dev_ino; | ||||
sb->st_ino = shmfd->shm_ino; | sb->st_ino = shmfd->shm_ino; | ||||
sb->st_nlink = shmfd->shm_object->ref_count; | |||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
shm_close(struct file *fp, struct thread *td) | shm_close(struct file *fp, struct thread *td) | ||||
{ | { | ||||
struct shmfd *shmfd; | struct shmfd *shmfd; | ||||
▲ Show 20 Lines • Show All 665 Lines • ▼ Show 20 Lines | shm_unmap(struct file *fp, void *mem, size_t size) | ||||
VM_OBJECT_WLOCK(obj); | VM_OBJECT_WLOCK(obj); | ||||
KASSERT(shmfd->shm_kmappings > 0, ("shm_unmap: object not mapped")); | KASSERT(shmfd->shm_kmappings > 0, ("shm_unmap: object not mapped")); | ||||
shmfd->shm_kmappings--; | shmfd->shm_kmappings--; | ||||
VM_OBJECT_WUNLOCK(obj); | VM_OBJECT_WUNLOCK(obj); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
shm_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) | shm_fill_kinfo_locked(struct shmfd *shmfd, struct kinfo_file *kif, bool list) | ||||
{ | { | ||||
const char *path, *pr_path; | const char *path, *pr_path; | ||||
struct shmfd *shmfd; | |||||
size_t pr_pathlen; | size_t pr_pathlen; | ||||
bool visible; | |||||
sx_assert(&shm_dict_lock, SA_LOCKED); | |||||
kif->kf_type = KF_TYPE_SHM; | kif->kf_type = KF_TYPE_SHM; | ||||
shmfd = fp->f_data; | kif->kf_un.kf_file.kf_file_mode = S_IFREG | shmfd->shm_mode; | ||||
mtx_lock(&shm_timestamp_lock); | |||||
kif->kf_un.kf_file.kf_file_mode = S_IFREG | shmfd->shm_mode; /* XXX */ | |||||
mtx_unlock(&shm_timestamp_lock); | |||||
kif->kf_un.kf_file.kf_file_size = shmfd->shm_size; | kif->kf_un.kf_file.kf_file_size = shmfd->shm_size; | ||||
if (shmfd->shm_path != NULL) { | if (shmfd->shm_path != NULL) { | ||||
sx_slock(&shm_dict_lock); | |||||
if (shmfd->shm_path != NULL) { | if (shmfd->shm_path != NULL) { | ||||
path = shmfd->shm_path; | path = shmfd->shm_path; | ||||
pr_path = curthread->td_ucred->cr_prison->pr_path; | pr_path = curthread->td_ucred->cr_prison->pr_path; | ||||
if (strcmp(pr_path, "/") != 0) { | if (strcmp(pr_path, "/") != 0) { | ||||
/* Return the jail-rooted pathname. */ | /* Return the jail-rooted pathname. */ | ||||
pr_pathlen = strlen(pr_path); | pr_pathlen = strlen(pr_path); | ||||
if (strncmp(path, pr_path, pr_pathlen) == 0 && | visible = strncmp(path, pr_path, pr_pathlen) | ||||
path[pr_pathlen] == '/') | == 0 && path[pr_pathlen] == '/'; | ||||
if (list && !visible) | |||||
return (EPERM); | |||||
if (visible) | |||||
path += pr_pathlen; | path += pr_pathlen; | ||||
} | } | ||||
strlcpy(kif->kf_path, path, sizeof(kif->kf_path)); | strlcpy(kif->kf_path, path, sizeof(kif->kf_path)); | ||||
} | } | ||||
sx_sunlock(&shm_dict_lock); | |||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | |||||
shm_fill_kinfo(struct file *fp, struct kinfo_file *kif, | |||||
struct filedesc *fdp __unused) | |||||
{ | |||||
int res; | |||||
sx_slock(&shm_dict_lock); | |||||
res = shm_fill_kinfo_locked(fp->f_data, kif, false); | |||||
sx_sunlock(&shm_dict_lock); | |||||
return (res); | |||||
} | |||||
static int | |||||
sysctl_posix_shm_list(SYSCTL_HANDLER_ARGS) | |||||
{ | |||||
struct shm_mapping *shmm; | |||||
struct sbuf sb; | |||||
struct kinfo_file kif; | |||||
u_long i; | |||||
ssize_t curlen; | |||||
int error, error2; | |||||
sbuf_new_for_sysctl(&sb, NULL, sizeof(struct kinfo_file) * 5, req); | |||||
sbuf_clear_flags(&sb, SBUF_INCLUDENUL); | |||||
curlen = 0; | |||||
error = 0; | |||||
sx_slock(&shm_dict_lock); | |||||
for (i = 0; i < shm_hash + 1; i++) { | |||||
LIST_FOREACH(shmm, &shm_dictionary[i], sm_link) { | |||||
error = shm_fill_kinfo_locked(shmm->sm_shmfd, | |||||
&kif, true); | |||||
if (error == EPERM) | |||||
continue; | |||||
if (error != 0) | |||||
break; | |||||
pack_kinfo(&kif); | |||||
if (req->oldptr != NULL && | |||||
kif.kf_structsize + curlen > req->oldlen) | |||||
break; | |||||
error = sbuf_bcat(&sb, &kif, kif.kf_structsize) == 0 ? | |||||
0 : ENOMEM; | |||||
if (error != 0) | |||||
break; | |||||
curlen += kif.kf_structsize; | |||||
} | |||||
} | |||||
sx_sunlock(&shm_dict_lock); | |||||
error2 = sbuf_finish(&sb); | |||||
sbuf_delete(&sb); | |||||
return (error != 0 ? error : error2); | |||||
} | |||||
SYSCTL_PROC(_kern_ipc, OID_AUTO, posix_shm_list, | |||||
CTLFLAG_RD | CTLFLAG_MPSAFE | CTLTYPE_OPAQUE, | |||||
NULL, 0, sysctl_posix_shm_list, "", | |||||
"POSIX SHM list"); |