diff options
Diffstat (limited to 'ipc/shm.c')
-rw-r--r-- | ipc/shm.c | 46 |
1 files changed, 25 insertions, 21 deletions
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/nsproxy.h> | 39 | #include <linux/nsproxy.h> |
40 | #include <linux/mount.h> | 40 | #include <linux/mount.h> |
41 | #include <linux/ipc_namespace.h> | 41 | #include <linux/ipc_namespace.h> |
42 | #include <linux/ima.h> | ||
43 | 42 | ||
44 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
45 | 44 | ||
@@ -101,6 +100,7 @@ static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) | |||
101 | void shm_exit_ns(struct ipc_namespace *ns) | 100 | void shm_exit_ns(struct ipc_namespace *ns) |
102 | { | 101 | { |
103 | free_ipcs(ns, &shm_ids(ns), do_shm_rmid); | 102 | free_ipcs(ns, &shm_ids(ns), do_shm_rmid); |
103 | idr_destroy(&ns->ids[IPC_SHM_IDS].ipcs_idr); | ||
104 | } | 104 | } |
105 | #endif | 105 | #endif |
106 | 106 | ||
@@ -290,28 +290,31 @@ static unsigned long shm_get_unmapped_area(struct file *file, | |||
290 | unsigned long flags) | 290 | unsigned long flags) |
291 | { | 291 | { |
292 | struct shm_file_data *sfd = shm_file_data(file); | 292 | struct shm_file_data *sfd = shm_file_data(file); |
293 | return get_unmapped_area(sfd->file, addr, len, pgoff, flags); | 293 | return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len, |
294 | } | 294 | pgoff, flags); |
295 | |||
296 | int is_file_shm_hugepages(struct file *file) | ||
297 | { | ||
298 | int ret = 0; | ||
299 | |||
300 | if (file->f_op == &shm_file_operations) { | ||
301 | struct shm_file_data *sfd; | ||
302 | sfd = shm_file_data(file); | ||
303 | ret = is_file_hugepages(sfd->file); | ||
304 | } | ||
305 | return ret; | ||
306 | } | 295 | } |
307 | 296 | ||
308 | static const struct file_operations shm_file_operations = { | 297 | static const struct file_operations shm_file_operations = { |
309 | .mmap = shm_mmap, | 298 | .mmap = shm_mmap, |
310 | .fsync = shm_fsync, | 299 | .fsync = shm_fsync, |
311 | .release = shm_release, | 300 | .release = shm_release, |
301 | #ifndef CONFIG_MMU | ||
302 | .get_unmapped_area = shm_get_unmapped_area, | ||
303 | #endif | ||
304 | }; | ||
305 | |||
306 | static const struct file_operations shm_file_operations_huge = { | ||
307 | .mmap = shm_mmap, | ||
308 | .fsync = shm_fsync, | ||
309 | .release = shm_release, | ||
312 | .get_unmapped_area = shm_get_unmapped_area, | 310 | .get_unmapped_area = shm_get_unmapped_area, |
313 | }; | 311 | }; |
314 | 312 | ||
313 | int is_file_shm_hugepages(struct file *file) | ||
314 | { | ||
315 | return file->f_op == &shm_file_operations_huge; | ||
316 | } | ||
317 | |||
315 | static const struct vm_operations_struct shm_vm_ops = { | 318 | static const struct vm_operations_struct shm_vm_ops = { |
316 | .open = shm_open, /* callback for a new vm-area open */ | 319 | .open = shm_open, /* callback for a new vm-area open */ |
317 | .close = shm_close, /* callback for when the vm-area is released */ | 320 | .close = shm_close, /* callback for when the vm-area is released */ |
@@ -761,8 +764,7 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) | |||
761 | if (euid != shp->shm_perm.uid && | 764 | if (euid != shp->shm_perm.uid && |
762 | euid != shp->shm_perm.cuid) | 765 | euid != shp->shm_perm.cuid) |
763 | goto out_unlock; | 766 | goto out_unlock; |
764 | if (cmd == SHM_LOCK && | 767 | if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) |
765 | !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur) | ||
766 | goto out_unlock; | 768 | goto out_unlock; |
767 | } | 769 | } |
768 | 770 | ||
@@ -878,8 +880,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) | |||
878 | if (err) | 880 | if (err) |
879 | goto out_unlock; | 881 | goto out_unlock; |
880 | 882 | ||
881 | path.dentry = dget(shp->shm_file->f_path.dentry); | 883 | path = shp->shm_file->f_path; |
882 | path.mnt = shp->shm_file->f_path.mnt; | 884 | path_get(&path); |
883 | shp->shm_nattch++; | 885 | shp->shm_nattch++; |
884 | size = i_size_read(path.dentry->d_inode); | 886 | size = i_size_read(path.dentry->d_inode); |
885 | shm_unlock(shp); | 887 | shm_unlock(shp); |
@@ -889,10 +891,12 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) | |||
889 | if (!sfd) | 891 | if (!sfd) |
890 | goto out_put_dentry; | 892 | goto out_put_dentry; |
891 | 893 | ||
892 | file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations); | 894 | file = alloc_file(&path, f_mode, |
895 | is_file_hugepages(shp->shm_file) ? | ||
896 | &shm_file_operations_huge : | ||
897 | &shm_file_operations); | ||
893 | if (!file) | 898 | if (!file) |
894 | goto out_free; | 899 | goto out_free; |
895 | ima_counts_get(file); | ||
896 | 900 | ||
897 | file->private_data = sfd; | 901 | file->private_data = sfd; |
898 | file->f_mapping = shp->shm_file->f_mapping; | 902 | file->f_mapping = shp->shm_file->f_mapping; |
@@ -947,7 +951,7 @@ out_unlock: | |||
947 | out_free: | 951 | out_free: |
948 | kfree(sfd); | 952 | kfree(sfd); |
949 | out_put_dentry: | 953 | out_put_dentry: |
950 | dput(path.dentry); | 954 | path_put(&path); |
951 | goto out_nattch; | 955 | goto out_nattch; |
952 | } | 956 | } |
953 | 957 | ||