24 #include <linux/slab.h>
27 #include <linux/shm.h>
30 #include <linux/mman.h>
34 #include <linux/audit.h>
35 #include <linux/capability.h>
36 #include <linux/ptrace.h>
43 #include <asm/uaccess.h>
51 const struct vm_operations_struct *
vm_ops;
54 #define shm_file_data(file) (*((struct shm_file_data **)&(file)->private_data))
57 static const struct vm_operations_struct shm_vm_ops;
59 #define shm_ids(ns) ((ns)->ids[IPC_SHM_IDS])
61 #define shm_unlock(shp) \
62 ipc_unlock(&(shp)->shm_perm)
69 static int sysvipc_shm_proc_show(
struct seq_file *
s,
void *it);
108 static int __init ipc_ns_init(
void)
120 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n",
122 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n",
141 static inline void shm_lock_by_ptr(
struct shmid_kernel *ipcp)
171 shp = shm_lock(sfd->
ns, sfd->
id);
228 struct file * file = vma->
vm_file;
235 shp = shm_lock(ns, sfd->
id);
240 if (shm_may_destroy(ns, shp))
241 shm_destroy(ns, shp);
248 static int shm_try_destroy_current(
int id,
void *
p,
void *
data)
271 if (shm_may_destroy(ns, shp)) {
272 shm_lock_by_ptr(shp);
273 shm_destroy(ns, shp);
279 static int shm_try_destroy_orphaned(
int id,
void *p,
void *data)
294 if (shm_may_destroy(ns, shp)) {
295 shm_lock_by_ptr(shp);
296 shm_destroy(ns, shp);
324 static int shm_fault(
struct vm_area_struct *vma,
struct vm_fault *vmf)
326 struct file *file = vma->
vm_file;
329 return sfd->
vm_ops->fault(vma, vmf);
335 struct file *file = vma->
vm_file;
338 if (sfd->
vm_ops->set_policy)
339 err = sfd->
vm_ops->set_policy(vma,
new);
346 struct file *file = vma->
vm_file;
350 if (sfd->
vm_ops->get_policy)
351 pol = sfd->
vm_ops->get_policy(vma, addr);
352 else if (vma->vm_policy)
353 pol = vma->vm_policy;
359 static int shm_mmap(
struct file * file,
struct vm_area_struct * vma)
364 ret = sfd->
file->f_op->mmap(sfd->
file, vma);
371 vma->
vm_ops = &shm_vm_ops;
377 static int shm_release(
struct inode *
ino,
struct file *file)
387 static int shm_fsync(
struct file *file, loff_t
start, loff_t
end,
int datasync)
391 if (!sfd->
file->f_op->fsync)
393 return sfd->
file->f_op->fsync(sfd->
file, start, end, datasync);
396 static long shm_fallocate(
struct file *file,
int mode, loff_t
offset,
401 if (!sfd->
file->f_op->fallocate)
403 return sfd->
file->f_op->fallocate(file, mode, offset, len);
406 static unsigned long shm_get_unmapped_area(
struct file *file,
407 unsigned long addr,
unsigned long len,
unsigned long pgoff,
411 return sfd->
file->f_op->get_unmapped_area(sfd->
file, addr, len,
418 .release = shm_release,
420 .get_unmapped_area = shm_get_unmapped_area,
423 .fallocate = shm_fallocate,
429 .release = shm_release,
430 .get_unmapped_area = shm_get_unmapped_area,
432 .fallocate = shm_fallocate,
437 return file->
f_op == &shm_file_operations_huge;
440 static const struct vm_operations_struct shm_vm_ops = {
444 #if defined(CONFIG_NUMA)
445 .set_policy = shm_set_policy,
446 .get_policy = shm_get_policy,
461 int shmflg = params->
flg;
492 sprintf (name,
"SYSV%08x", key);
496 acctflag = VM_NORESERVE;
506 acctflag = VM_NORESERVE;
509 error = PTR_ERR(file);
531 file->f_dentry->d_inode->i_ino = shp->
shm_perm.id;
551 static inline int shm_security(
struct kern_ipc_perm *ipcp,
int shmflg)
562 static inline int shm_more_checks(
struct kern_ipc_perm *ipcp,
587 shm_params.
flg = shmflg;
619 static inline unsigned long
620 copy_shmid_from_user(
struct shmid64_ds *
out,
void __user *buf,
int version)
634 out->
shm_perm.uid = tbuf_old.shm_perm.uid;
635 out->
shm_perm.gid = tbuf_old.shm_perm.gid;
636 out->
shm_perm.mode = tbuf_old.shm_perm.mode;
645 static inline unsigned long copy_shminfo_to_user(
void __user *buf,
struct shminfo64 *in,
int version)
676 unsigned long *rss_add,
unsigned long *swp_add)
680 inode = shp->
shm_file->f_path.dentry->d_inode;
685 *rss_add += pages_per_huge_page(h) * mapping->
nrpages;
689 spin_lock(&info->
lock);
692 spin_unlock(&info->
lock);
702 static void shm_get_stat(
struct ipc_namespace *ns,
unsigned long *rss,
713 for (total = 0, next_id = 0; total <
in_use; next_id++) {
722 shm_add_rss_swap(shp, rss, swp);
734 struct shmid_ds __user *buf,
int version)
742 if (copy_shmid_from_user(&shmid64, buf, version))
747 &shmid64.shm_perm, 0);
749 return PTR_ERR(ipcp);
758 do_shm_rmid(ns, ipcp);
782 if (cmd < 0 || shmid < 0) {
799 memset(&shminfo, 0,
sizeof(shminfo));
805 if(copy_shminfo_to_user (buf, &shminfo, version))
824 memset(&shm_info, 0,
sizeof(shm_info));
838 err = err < 0 ? 0 :
err;
848 shp = shm_lock(ns, shmid);
855 shp = shm_lock_check(ns, shmid);
868 memset(&tbuf, 0,
sizeof(tbuf));
878 if(copy_shmid_to_user (buf, &tbuf, version))
887 struct file *shm_file;
889 shp = shm_lock_check(ns, shmid);
900 if (!uid_eq(euid, shp->
shm_perm.uid) &&
939 err = shmctl_down(ns, shmid, cmd, buf, version);
959 unsigned long shmlba)
969 unsigned long user_addr;
978 else if ((addr = (
ulong)shmaddr)) {
979 if (addr & (shmlba - 1)) {
981 addr &= ~(shmlba - 1);
983 #ifndef __ARCH_FORCE_SHMLBA
1014 ns =
current->nsproxy->ipc_ns;
1015 shp = shm_lock_check(ns, shmid);
1032 size = i_size_read(path.
dentry->d_inode);
1038 goto out_put_dentry;
1042 &shm_file_operations_huge :
1043 &shm_file_operations);
1050 sfd->
ns = get_ipc_ns(ns);
1061 if (find_vma_intersection(
current->mm, addr, addr + size))
1067 if (addr < current->mm->start_stack &&
1072 user_addr =
do_mmap_pgoff(file, addr, size, prot, flags, 0);
1076 err = (
long)user_addr;
1085 shp = shm_lock(ns, shmid);
1088 if (shm_may_destroy(ns, shp))
1089 shm_destroy(ns, shp);
1128 unsigned long addr = (
unsigned long)shmaddr;
1171 if ((vma->
vm_ops == &shm_vm_ops) &&
1175 size = vma->
vm_file->f_path.dentry->d_inode->i_size;
1196 while (vma && (loff_t)(vma->
vm_end - addr) <= size) {
1200 if ((vma->
vm_ops == &shm_vm_ops) &&
1222 #ifdef CONFIG_PROC_FS
1223 static int sysvipc_shm_proc_show(
struct seq_file *s,
void *it)
1227 unsigned long rss = 0, swp = 0;
1229 shm_add_rss_swap(shp, &rss, &swp);
1231 #if BITS_PER_LONG <= 32
1232 #define SIZE_SPEC "%10lu"
1234 #define SIZE_SPEC "%21lu"
1238 "%10d %10d %4o " SIZE_SPEC
" %5u %5u "
1239 "%5lu %5u %5u %5u %5u %10lu %10lu %10lu "
1240 SIZE_SPEC
" " SIZE_SPEC
"\n",