diff options
| -rw-r--r-- | include/linux/ipc.h | 2 | ||||
| -rw-r--r-- | include/linux/lsm_hooks.h | 32 | ||||
| -rw-r--r-- | include/linux/msg.h | 18 | ||||
| -rw-r--r-- | include/linux/security.h | 67 | ||||
| -rw-r--r-- | include/linux/sem.h | 40 | ||||
| -rw-r--r-- | include/linux/shm.h | 22 | ||||
| -rw-r--r-- | ipc/msg.c | 62 | ||||
| -rw-r--r-- | ipc/sem.c | 81 | ||||
| -rw-r--r-- | ipc/shm.c | 68 | ||||
| -rw-r--r-- | ipc/util.c | 9 | ||||
| -rw-r--r-- | ipc/util.h | 12 | ||||
| -rw-r--r-- | kernel/pid_namespace.c | 67 | ||||
| -rw-r--r-- | security/security.c | 32 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 92 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 197 |
15 files changed, 346 insertions, 455 deletions
diff --git a/include/linux/ipc.h b/include/linux/ipc.h index 821b2f260992..6cc2df7f7ac9 100644 --- a/include/linux/ipc.h +++ b/include/linux/ipc.h | |||
| @@ -8,8 +8,6 @@ | |||
| 8 | #include <uapi/linux/ipc.h> | 8 | #include <uapi/linux/ipc.h> |
| 9 | #include <linux/refcount.h> | 9 | #include <linux/refcount.h> |
| 10 | 10 | ||
| 11 | #define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */ | ||
| 12 | |||
| 13 | /* used by in-kernel data structures */ | 11 | /* used by in-kernel data structures */ |
| 14 | struct kern_ipc_perm { | 12 | struct kern_ipc_perm { |
| 15 | spinlock_t lock; | 13 | spinlock_t lock; |
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 7161d8e7ee79..bde167fa2c51 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h | |||
| @@ -1575,28 +1575,28 @@ union security_list_options { | |||
| 1575 | int (*msg_msg_alloc_security)(struct msg_msg *msg); | 1575 | int (*msg_msg_alloc_security)(struct msg_msg *msg); |
| 1576 | void (*msg_msg_free_security)(struct msg_msg *msg); | 1576 | void (*msg_msg_free_security)(struct msg_msg *msg); |
| 1577 | 1577 | ||
| 1578 | int (*msg_queue_alloc_security)(struct msg_queue *msq); | 1578 | int (*msg_queue_alloc_security)(struct kern_ipc_perm *msq); |
| 1579 | void (*msg_queue_free_security)(struct msg_queue *msq); | 1579 | void (*msg_queue_free_security)(struct kern_ipc_perm *msq); |
| 1580 | int (*msg_queue_associate)(struct msg_queue *msq, int msqflg); | 1580 | int (*msg_queue_associate)(struct kern_ipc_perm *msq, int msqflg); |
| 1581 | int (*msg_queue_msgctl)(struct msg_queue *msq, int cmd); | 1581 | int (*msg_queue_msgctl)(struct kern_ipc_perm *msq, int cmd); |
| 1582 | int (*msg_queue_msgsnd)(struct msg_queue *msq, struct msg_msg *msg, | 1582 | int (*msg_queue_msgsnd)(struct kern_ipc_perm *msq, struct msg_msg *msg, |
| 1583 | int msqflg); | 1583 | int msqflg); |
| 1584 | int (*msg_queue_msgrcv)(struct msg_queue *msq, struct msg_msg *msg, | 1584 | int (*msg_queue_msgrcv)(struct kern_ipc_perm *msq, struct msg_msg *msg, |
| 1585 | struct task_struct *target, long type, | 1585 | struct task_struct *target, long type, |
| 1586 | int mode); | 1586 | int mode); |
| 1587 | 1587 | ||
| 1588 | int (*shm_alloc_security)(struct shmid_kernel *shp); | 1588 | int (*shm_alloc_security)(struct kern_ipc_perm *shp); |
| 1589 | void (*shm_free_security)(struct shmid_kernel *shp); | 1589 | void (*shm_free_security)(struct kern_ipc_perm *shp); |
| 1590 | int (*shm_associate)(struct shmid_kernel *shp, int shmflg); | 1590 | int (*shm_associate)(struct kern_ipc_perm *shp, int shmflg); |
| 1591 | int (*shm_shmctl)(struct shmid_kernel *shp, int cmd); | 1591 | int (*shm_shmctl)(struct kern_ipc_perm *shp, int cmd); |
| 1592 | int (*shm_shmat)(struct shmid_kernel *shp, char __user *shmaddr, | 1592 | int (*shm_shmat)(struct kern_ipc_perm *shp, char __user *shmaddr, |
| 1593 | int shmflg); | 1593 | int shmflg); |
| 1594 | 1594 | ||
| 1595 | int (*sem_alloc_security)(struct sem_array *sma); | 1595 | int (*sem_alloc_security)(struct kern_ipc_perm *sma); |
| 1596 | void (*sem_free_security)(struct sem_array *sma); | 1596 | void (*sem_free_security)(struct kern_ipc_perm *sma); |
| 1597 | int (*sem_associate)(struct sem_array *sma, int semflg); | 1597 | int (*sem_associate)(struct kern_ipc_perm *sma, int semflg); |
| 1598 | int (*sem_semctl)(struct sem_array *sma, int cmd); | 1598 | int (*sem_semctl)(struct kern_ipc_perm *sma, int cmd); |
| 1599 | int (*sem_semop)(struct sem_array *sma, struct sembuf *sops, | 1599 | int (*sem_semop)(struct kern_ipc_perm *sma, struct sembuf *sops, |
| 1600 | unsigned nsops, int alter); | 1600 | unsigned nsops, int alter); |
| 1601 | 1601 | ||
| 1602 | int (*netlink_send)(struct sock *sk, struct sk_buff *skb); | 1602 | int (*netlink_send)(struct sock *sk, struct sk_buff *skb); |
diff --git a/include/linux/msg.h b/include/linux/msg.h index 0a7eefeee0d1..9a972a296b95 100644 --- a/include/linux/msg.h +++ b/include/linux/msg.h | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | #define _LINUX_MSG_H | 3 | #define _LINUX_MSG_H |
| 4 | 4 | ||
| 5 | #include <linux/list.h> | 5 | #include <linux/list.h> |
| 6 | #include <linux/time64.h> | ||
| 7 | #include <uapi/linux/msg.h> | 6 | #include <uapi/linux/msg.h> |
| 8 | 7 | ||
| 9 | /* one msg_msg structure for each message */ | 8 | /* one msg_msg structure for each message */ |
| @@ -16,21 +15,4 @@ struct msg_msg { | |||
| 16 | /* the actual message follows immediately */ | 15 | /* the actual message follows immediately */ |
| 17 | }; | 16 | }; |
| 18 | 17 | ||
| 19 | /* one msq_queue structure for each present queue on the system */ | ||
| 20 | struct msg_queue { | ||
| 21 | struct kern_ipc_perm q_perm; | ||
| 22 | time64_t q_stime; /* last msgsnd time */ | ||
| 23 | time64_t q_rtime; /* last msgrcv time */ | ||
| 24 | time64_t q_ctime; /* last change time */ | ||
| 25 | unsigned long q_cbytes; /* current number of bytes on queue */ | ||
| 26 | unsigned long q_qnum; /* number of messages in queue */ | ||
| 27 | unsigned long q_qbytes; /* max number of bytes on queue */ | ||
| 28 | pid_t q_lspid; /* pid of last msgsnd */ | ||
| 29 | pid_t q_lrpid; /* last receive pid */ | ||
| 30 | |||
| 31 | struct list_head q_messages; | ||
| 32 | struct list_head q_receivers; | ||
| 33 | struct list_head q_senders; | ||
| 34 | } __randomize_layout; | ||
| 35 | |||
| 36 | #endif /* _LINUX_MSG_H */ | 18 | #endif /* _LINUX_MSG_H */ |
diff --git a/include/linux/security.h b/include/linux/security.h index 73f1ef625d40..128e1e4a5346 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -36,7 +36,6 @@ struct linux_binprm; | |||
| 36 | struct cred; | 36 | struct cred; |
| 37 | struct rlimit; | 37 | struct rlimit; |
| 38 | struct siginfo; | 38 | struct siginfo; |
| 39 | struct sem_array; | ||
| 40 | struct sembuf; | 39 | struct sembuf; |
| 41 | struct kern_ipc_perm; | 40 | struct kern_ipc_perm; |
| 42 | struct audit_context; | 41 | struct audit_context; |
| @@ -50,9 +49,7 @@ struct qstr; | |||
| 50 | struct iattr; | 49 | struct iattr; |
| 51 | struct fown_struct; | 50 | struct fown_struct; |
| 52 | struct file_operations; | 51 | struct file_operations; |
| 53 | struct shmid_kernel; | ||
| 54 | struct msg_msg; | 52 | struct msg_msg; |
| 55 | struct msg_queue; | ||
| 56 | struct xattr; | 53 | struct xattr; |
| 57 | struct xfrm_sec_ctx; | 54 | struct xfrm_sec_ctx; |
| 58 | struct mm_struct; | 55 | struct mm_struct; |
| @@ -355,24 +352,24 @@ int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag); | |||
| 355 | void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid); | 352 | void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid); |
| 356 | int security_msg_msg_alloc(struct msg_msg *msg); | 353 | int security_msg_msg_alloc(struct msg_msg *msg); |
| 357 | void security_msg_msg_free(struct msg_msg *msg); | 354 | void security_msg_msg_free(struct msg_msg *msg); |
| 358 | int security_msg_queue_alloc(struct msg_queue *msq); | 355 | int security_msg_queue_alloc(struct kern_ipc_perm *msq); |
| 359 | void security_msg_queue_free(struct msg_queue *msq); | 356 | void security_msg_queue_free(struct kern_ipc_perm *msq); |
| 360 | int security_msg_queue_associate(struct msg_queue *msq, int msqflg); | 357 | int security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg); |
| 361 | int security_msg_queue_msgctl(struct msg_queue *msq, int cmd); | 358 | int security_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd); |
| 362 | int security_msg_queue_msgsnd(struct msg_queue *msq, | 359 | int security_msg_queue_msgsnd(struct kern_ipc_perm *msq, |
| 363 | struct msg_msg *msg, int msqflg); | 360 | struct msg_msg *msg, int msqflg); |
| 364 | int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | 361 | int security_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg, |
| 365 | struct task_struct *target, long type, int mode); | 362 | struct task_struct *target, long type, int mode); |
| 366 | int security_shm_alloc(struct shmid_kernel *shp); | 363 | int security_shm_alloc(struct kern_ipc_perm *shp); |
| 367 | void security_shm_free(struct shmid_kernel *shp); | 364 | void security_shm_free(struct kern_ipc_perm *shp); |
| 368 | int security_shm_associate(struct shmid_kernel *shp, int shmflg); | 365 | int security_shm_associate(struct kern_ipc_perm *shp, int shmflg); |
| 369 | int security_shm_shmctl(struct shmid_kernel *shp, int cmd); | 366 | int security_shm_shmctl(struct kern_ipc_perm *shp, int cmd); |
| 370 | int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg); | 367 | int security_shm_shmat(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg); |
| 371 | int security_sem_alloc(struct sem_array *sma); | 368 | int security_sem_alloc(struct kern_ipc_perm *sma); |
| 372 | void security_sem_free(struct sem_array *sma); | 369 | void security_sem_free(struct kern_ipc_perm *sma); |
| 373 | int security_sem_associate(struct sem_array *sma, int semflg); | 370 | int security_sem_associate(struct kern_ipc_perm *sma, int semflg); |
| 374 | int security_sem_semctl(struct sem_array *sma, int cmd); | 371 | int security_sem_semctl(struct kern_ipc_perm *sma, int cmd); |
| 375 | int security_sem_semop(struct sem_array *sma, struct sembuf *sops, | 372 | int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops, |
| 376 | unsigned nsops, int alter); | 373 | unsigned nsops, int alter); |
| 377 | void security_d_instantiate(struct dentry *dentry, struct inode *inode); | 374 | void security_d_instantiate(struct dentry *dentry, struct inode *inode); |
| 378 | int security_getprocattr(struct task_struct *p, char *name, char **value); | 375 | int security_getprocattr(struct task_struct *p, char *name, char **value); |
| @@ -1045,32 +1042,32 @@ static inline int security_msg_msg_alloc(struct msg_msg *msg) | |||
| 1045 | static inline void security_msg_msg_free(struct msg_msg *msg) | 1042 | static inline void security_msg_msg_free(struct msg_msg *msg) |
| 1046 | { } | 1043 | { } |
| 1047 | 1044 | ||
| 1048 | static inline int security_msg_queue_alloc(struct msg_queue *msq) | 1045 | static inline int security_msg_queue_alloc(struct kern_ipc_perm *msq) |
| 1049 | { | 1046 | { |
| 1050 | return 0; | 1047 | return 0; |
| 1051 | } | 1048 | } |
| 1052 | 1049 | ||
| 1053 | static inline void security_msg_queue_free(struct msg_queue *msq) | 1050 | static inline void security_msg_queue_free(struct kern_ipc_perm *msq) |
| 1054 | { } | 1051 | { } |
| 1055 | 1052 | ||
| 1056 | static inline int security_msg_queue_associate(struct msg_queue *msq, | 1053 | static inline int security_msg_queue_associate(struct kern_ipc_perm *msq, |
| 1057 | int msqflg) | 1054 | int msqflg) |
| 1058 | { | 1055 | { |
| 1059 | return 0; | 1056 | return 0; |
| 1060 | } | 1057 | } |
| 1061 | 1058 | ||
| 1062 | static inline int security_msg_queue_msgctl(struct msg_queue *msq, int cmd) | 1059 | static inline int security_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd) |
| 1063 | { | 1060 | { |
| 1064 | return 0; | 1061 | return 0; |
| 1065 | } | 1062 | } |
| 1066 | 1063 | ||
| 1067 | static inline int security_msg_queue_msgsnd(struct msg_queue *msq, | 1064 | static inline int security_msg_queue_msgsnd(struct kern_ipc_perm *msq, |
| 1068 | struct msg_msg *msg, int msqflg) | 1065 | struct msg_msg *msg, int msqflg) |
| 1069 | { | 1066 | { |
| 1070 | return 0; | 1067 | return 0; |
| 1071 | } | 1068 | } |
| 1072 | 1069 | ||
| 1073 | static inline int security_msg_queue_msgrcv(struct msg_queue *msq, | 1070 | static inline int security_msg_queue_msgrcv(struct kern_ipc_perm *msq, |
| 1074 | struct msg_msg *msg, | 1071 | struct msg_msg *msg, |
| 1075 | struct task_struct *target, | 1072 | struct task_struct *target, |
| 1076 | long type, int mode) | 1073 | long type, int mode) |
| @@ -1078,50 +1075,50 @@ static inline int security_msg_queue_msgrcv(struct msg_queue *msq, | |||
| 1078 | return 0; | 1075 | return 0; |
| 1079 | } | 1076 | } |
| 1080 | 1077 | ||
| 1081 | static inline int security_shm_alloc(struct shmid_kernel *shp) | 1078 | static inline int security_shm_alloc(struct kern_ipc_perm *shp) |
| 1082 | { | 1079 | { |
| 1083 | return 0; | 1080 | return 0; |
| 1084 | } | 1081 | } |
| 1085 | 1082 | ||
| 1086 | static inline void security_shm_free(struct shmid_kernel *shp) | 1083 | static inline void security_shm_free(struct kern_ipc_perm *shp) |
| 1087 | { } | 1084 | { } |
| 1088 | 1085 | ||
| 1089 | static inline int security_shm_associate(struct shmid_kernel *shp, | 1086 | static inline int security_shm_associate(struct kern_ipc_perm *shp, |
| 1090 | int shmflg) | 1087 | int shmflg) |
| 1091 | { | 1088 | { |
| 1092 | return 0; | 1089 | return 0; |
| 1093 | } | 1090 | } |
| 1094 | 1091 | ||
| 1095 | static inline int security_shm_shmctl(struct shmid_kernel *shp, int cmd) | 1092 | static inline int security_shm_shmctl(struct kern_ipc_perm *shp, int cmd) |
| 1096 | { | 1093 | { |
| 1097 | return 0; | 1094 | return 0; |
| 1098 | } | 1095 | } |
| 1099 | 1096 | ||
| 1100 | static inline int security_shm_shmat(struct shmid_kernel *shp, | 1097 | static inline int security_shm_shmat(struct kern_ipc_perm *shp, |
| 1101 | char __user *shmaddr, int shmflg) | 1098 | char __user *shmaddr, int shmflg) |
| 1102 | { | 1099 | { |
| 1103 | return 0; | 1100 | return 0; |
| 1104 | } | 1101 | } |
| 1105 | 1102 | ||
| 1106 | static inline int security_sem_alloc(struct sem_array *sma) | 1103 | static inline int security_sem_alloc(struct kern_ipc_perm *sma) |
| 1107 | { | 1104 | { |
| 1108 | return 0; | 1105 | return 0; |
| 1109 | } | 1106 | } |
| 1110 | 1107 | ||
| 1111 | static inline void security_sem_free(struct sem_array *sma) | 1108 | static inline void security_sem_free(struct kern_ipc_perm *sma) |
| 1112 | { } | 1109 | { } |
| 1113 | 1110 | ||
| 1114 | static inline int security_sem_associate(struct sem_array *sma, int semflg) | 1111 | static inline int security_sem_associate(struct kern_ipc_perm *sma, int semflg) |
| 1115 | { | 1112 | { |
| 1116 | return 0; | 1113 | return 0; |
| 1117 | } | 1114 | } |
| 1118 | 1115 | ||
| 1119 | static inline int security_sem_semctl(struct sem_array *sma, int cmd) | 1116 | static inline int security_sem_semctl(struct kern_ipc_perm *sma, int cmd) |
| 1120 | { | 1117 | { |
| 1121 | return 0; | 1118 | return 0; |
| 1122 | } | 1119 | } |
| 1123 | 1120 | ||
| 1124 | static inline int security_sem_semop(struct sem_array *sma, | 1121 | static inline int security_sem_semop(struct kern_ipc_perm *sma, |
| 1125 | struct sembuf *sops, unsigned nsops, | 1122 | struct sembuf *sops, unsigned nsops, |
| 1126 | int alter) | 1123 | int alter) |
| 1127 | { | 1124 | { |
diff --git a/include/linux/sem.h b/include/linux/sem.h index 9badd322dcee..5608a500c43e 100644 --- a/include/linux/sem.h +++ b/include/linux/sem.h | |||
| @@ -2,48 +2,10 @@ | |||
| 2 | #ifndef _LINUX_SEM_H | 2 | #ifndef _LINUX_SEM_H |
| 3 | #define _LINUX_SEM_H | 3 | #define _LINUX_SEM_H |
| 4 | 4 | ||
| 5 | #include <linux/atomic.h> | ||
| 6 | #include <linux/rcupdate.h> | ||
| 7 | #include <linux/cache.h> | ||
| 8 | #include <linux/time64.h> | ||
| 9 | #include <uapi/linux/sem.h> | 5 | #include <uapi/linux/sem.h> |
| 10 | 6 | ||
| 11 | struct task_struct; | 7 | struct task_struct; |
| 12 | 8 | struct sem_undo_list; | |
| 13 | /* One semaphore structure for each semaphore in the system. */ | ||
| 14 | struct sem { | ||
| 15 | int semval; /* current value */ | ||
| 16 | /* | ||
| 17 | * PID of the process that last modified the semaphore. For | ||
| 18 | * Linux, specifically these are: | ||
| 19 | * - semop | ||
| 20 | * - semctl, via SETVAL and SETALL. | ||
| 21 | * - at task exit when performing undo adjustments (see exit_sem). | ||
| 22 | */ | ||
| 23 | int sempid; | ||
| 24 | spinlock_t lock; /* spinlock for fine-grained semtimedop */ | ||
| 25 | struct list_head pending_alter; /* pending single-sop operations */ | ||
| 26 | /* that alter the semaphore */ | ||
| 27 | struct list_head pending_const; /* pending single-sop operations */ | ||
| 28 | /* that do not alter the semaphore*/ | ||
| 29 | time_t sem_otime; /* candidate for sem_otime */ | ||
| 30 | } ____cacheline_aligned_in_smp; | ||
| 31 | |||
| 32 | /* One sem_array data structure for each set of semaphores in the system. */ | ||
| 33 | struct sem_array { | ||
| 34 | struct kern_ipc_perm sem_perm; /* permissions .. see ipc.h */ | ||
| 35 | time64_t sem_ctime; /* create/last semctl() time */ | ||
| 36 | struct list_head pending_alter; /* pending operations */ | ||
| 37 | /* that alter the array */ | ||
| 38 | struct list_head pending_const; /* pending complex operations */ | ||
| 39 | /* that do not alter semvals */ | ||
| 40 | struct list_head list_id; /* undo requests on this array */ | ||
| 41 | int sem_nsems; /* no. of semaphores in array */ | ||
| 42 | int complex_count; /* pending complex operations */ | ||
| 43 | unsigned int use_global_lock;/* >0: global lock required */ | ||
| 44 | |||
| 45 | struct sem sems[]; | ||
| 46 | } __randomize_layout; | ||
| 47 | 9 | ||
| 48 | #ifdef CONFIG_SYSVIPC | 10 | #ifdef CONFIG_SYSVIPC |
| 49 | 11 | ||
diff --git a/include/linux/shm.h b/include/linux/shm.h index 2bbafacfbfc9..d8e69aed3d32 100644 --- a/include/linux/shm.h +++ b/include/linux/shm.h | |||
| @@ -7,27 +7,7 @@ | |||
| 7 | #include <uapi/linux/shm.h> | 7 | #include <uapi/linux/shm.h> |
| 8 | #include <asm/shmparam.h> | 8 | #include <asm/shmparam.h> |
| 9 | 9 | ||
| 10 | struct shmid_kernel /* private to the kernel */ | 10 | struct file; |
| 11 | { | ||
| 12 | struct kern_ipc_perm shm_perm; | ||
| 13 | struct file *shm_file; | ||
| 14 | unsigned long shm_nattch; | ||
| 15 | unsigned long shm_segsz; | ||
| 16 | time64_t shm_atim; | ||
| 17 | time64_t shm_dtim; | ||
| 18 | time64_t shm_ctim; | ||
| 19 | pid_t shm_cprid; | ||
| 20 | pid_t shm_lprid; | ||
| 21 | struct user_struct *mlock_user; | ||
| 22 | |||
| 23 | /* The task created the shm object. NULL if the task is dead. */ | ||
| 24 | struct task_struct *shm_creator; | ||
| 25 | struct list_head shm_clist; /* list by creator */ | ||
| 26 | } __randomize_layout; | ||
| 27 | |||
| 28 | /* shm_mode upper byte flags */ | ||
| 29 | #define SHM_DEST 01000 /* segment will be destroyed on last detach */ | ||
| 30 | #define SHM_LOCKED 02000 /* segment will not be swapped */ | ||
| 31 | 11 | ||
| 32 | #ifdef CONFIG_SYSVIPC | 12 | #ifdef CONFIG_SYSVIPC |
| 33 | struct sysv_shm { | 13 | struct sysv_shm { |
| @@ -43,6 +43,23 @@ | |||
| 43 | #include <linux/uaccess.h> | 43 | #include <linux/uaccess.h> |
| 44 | #include "util.h" | 44 | #include "util.h" |
| 45 | 45 | ||
| 46 | /* one msq_queue structure for each present queue on the system */ | ||
| 47 | struct msg_queue { | ||
| 48 | struct kern_ipc_perm q_perm; | ||
| 49 | time64_t q_stime; /* last msgsnd time */ | ||
| 50 | time64_t q_rtime; /* last msgrcv time */ | ||
| 51 | time64_t q_ctime; /* last change time */ | ||
| 52 | unsigned long q_cbytes; /* current number of bytes on queue */ | ||
| 53 | unsigned long q_qnum; /* number of messages in queue */ | ||
| 54 | unsigned long q_qbytes; /* max number of bytes on queue */ | ||
| 55 | struct pid *q_lspid; /* pid of last msgsnd */ | ||
| 56 | struct pid *q_lrpid; /* last receive pid */ | ||
| 57 | |||
| 58 | struct list_head q_messages; | ||
| 59 | struct list_head q_receivers; | ||
| 60 | struct list_head q_senders; | ||
| 61 | } __randomize_layout; | ||
| 62 | |||
| 46 | /* one msg_receiver structure for each sleeping receiver */ | 63 | /* one msg_receiver structure for each sleeping receiver */ |
| 47 | struct msg_receiver { | 64 | struct msg_receiver { |
| 48 | struct list_head r_list; | 65 | struct list_head r_list; |
| @@ -101,7 +118,7 @@ static void msg_rcu_free(struct rcu_head *head) | |||
| 101 | struct kern_ipc_perm *p = container_of(head, struct kern_ipc_perm, rcu); | 118 | struct kern_ipc_perm *p = container_of(head, struct kern_ipc_perm, rcu); |
| 102 | struct msg_queue *msq = container_of(p, struct msg_queue, q_perm); | 119 | struct msg_queue *msq = container_of(p, struct msg_queue, q_perm); |
| 103 | 120 | ||
| 104 | security_msg_queue_free(msq); | 121 | security_msg_queue_free(&msq->q_perm); |
| 105 | kvfree(msq); | 122 | kvfree(msq); |
| 106 | } | 123 | } |
| 107 | 124 | ||
| @@ -127,7 +144,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) | |||
| 127 | msq->q_perm.key = key; | 144 | msq->q_perm.key = key; |
| 128 | 145 | ||
| 129 | msq->q_perm.security = NULL; | 146 | msq->q_perm.security = NULL; |
| 130 | retval = security_msg_queue_alloc(msq); | 147 | retval = security_msg_queue_alloc(&msq->q_perm); |
| 131 | if (retval) { | 148 | if (retval) { |
| 132 | kvfree(msq); | 149 | kvfree(msq); |
| 133 | return retval; | 150 | return retval; |
| @@ -137,7 +154,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) | |||
| 137 | msq->q_ctime = ktime_get_real_seconds(); | 154 | msq->q_ctime = ktime_get_real_seconds(); |
| 138 | msq->q_cbytes = msq->q_qnum = 0; | 155 | msq->q_cbytes = msq->q_qnum = 0; |
| 139 | msq->q_qbytes = ns->msg_ctlmnb; | 156 | msq->q_qbytes = ns->msg_ctlmnb; |
| 140 | msq->q_lspid = msq->q_lrpid = 0; | 157 | msq->q_lspid = msq->q_lrpid = NULL; |
| 141 | INIT_LIST_HEAD(&msq->q_messages); | 158 | INIT_LIST_HEAD(&msq->q_messages); |
| 142 | INIT_LIST_HEAD(&msq->q_receivers); | 159 | INIT_LIST_HEAD(&msq->q_receivers); |
| 143 | INIT_LIST_HEAD(&msq->q_senders); | 160 | INIT_LIST_HEAD(&msq->q_senders); |
| @@ -250,25 +267,17 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) | |||
| 250 | free_msg(msg); | 267 | free_msg(msg); |
| 251 | } | 268 | } |
| 252 | atomic_sub(msq->q_cbytes, &ns->msg_bytes); | 269 | atomic_sub(msq->q_cbytes, &ns->msg_bytes); |
| 270 | ipc_update_pid(&msq->q_lspid, NULL); | ||
| 271 | ipc_update_pid(&msq->q_lrpid, NULL); | ||
| 253 | ipc_rcu_putref(&msq->q_perm, msg_rcu_free); | 272 | ipc_rcu_putref(&msq->q_perm, msg_rcu_free); |
| 254 | } | 273 | } |
| 255 | 274 | ||
| 256 | /* | ||
| 257 | * Called with msg_ids.rwsem and ipcp locked. | ||
| 258 | */ | ||
| 259 | static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg) | ||
| 260 | { | ||
| 261 | struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm); | ||
| 262 | |||
| 263 | return security_msg_queue_associate(msq, msgflg); | ||
| 264 | } | ||
| 265 | |||
| 266 | long ksys_msgget(key_t key, int msgflg) | 275 | long ksys_msgget(key_t key, int msgflg) |
| 267 | { | 276 | { |
| 268 | struct ipc_namespace *ns; | 277 | struct ipc_namespace *ns; |
| 269 | static const struct ipc_ops msg_ops = { | 278 | static const struct ipc_ops msg_ops = { |
| 270 | .getnew = newque, | 279 | .getnew = newque, |
| 271 | .associate = msg_security, | 280 | .associate = security_msg_queue_associate, |
| 272 | }; | 281 | }; |
| 273 | struct ipc_params msg_params; | 282 | struct ipc_params msg_params; |
| 274 | 283 | ||
| @@ -385,7 +394,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, | |||
| 385 | 394 | ||
| 386 | msq = container_of(ipcp, struct msg_queue, q_perm); | 395 | msq = container_of(ipcp, struct msg_queue, q_perm); |
| 387 | 396 | ||
| 388 | err = security_msg_queue_msgctl(msq, cmd); | 397 | err = security_msg_queue_msgctl(&msq->q_perm, cmd); |
| 389 | if (err) | 398 | if (err) |
| 390 | goto out_unlock1; | 399 | goto out_unlock1; |
| 391 | 400 | ||
| @@ -507,7 +516,7 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid, | |||
| 507 | if (ipcperms(ns, &msq->q_perm, S_IRUGO)) | 516 | if (ipcperms(ns, &msq->q_perm, S_IRUGO)) |
| 508 | goto out_unlock; | 517 | goto out_unlock; |
| 509 | 518 | ||
| 510 | err = security_msg_queue_msgctl(msq, cmd); | 519 | err = security_msg_queue_msgctl(&msq->q_perm, cmd); |
| 511 | if (err) | 520 | if (err) |
| 512 | goto out_unlock; | 521 | goto out_unlock; |
| 513 | 522 | ||
| @@ -526,8 +535,8 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid, | |||
| 526 | p->msg_cbytes = msq->q_cbytes; | 535 | p->msg_cbytes = msq->q_cbytes; |
| 527 | p->msg_qnum = msq->q_qnum; | 536 | p->msg_qnum = msq->q_qnum; |
| 528 | p->msg_qbytes = msq->q_qbytes; | 537 | p->msg_qbytes = msq->q_qbytes; |
| 529 | p->msg_lspid = msq->q_lspid; | 538 | p->msg_lspid = pid_vnr(msq->q_lspid); |
| 530 | p->msg_lrpid = msq->q_lrpid; | 539 | p->msg_lrpid = pid_vnr(msq->q_lrpid); |
| 531 | 540 | ||
| 532 | ipc_unlock_object(&msq->q_perm); | 541 | ipc_unlock_object(&msq->q_perm); |
| 533 | rcu_read_unlock(); | 542 | rcu_read_unlock(); |
| @@ -733,7 +742,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg, | |||
| 733 | 742 | ||
| 734 | list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) { | 743 | list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) { |
| 735 | if (testmsg(msg, msr->r_msgtype, msr->r_mode) && | 744 | if (testmsg(msg, msr->r_msgtype, msr->r_mode) && |
| 736 | !security_msg_queue_msgrcv(msq, msg, msr->r_tsk, | 745 | !security_msg_queue_msgrcv(&msq->q_perm, msg, msr->r_tsk, |
| 737 | msr->r_msgtype, msr->r_mode)) { | 746 | msr->r_msgtype, msr->r_mode)) { |
| 738 | 747 | ||
| 739 | list_del(&msr->r_list); | 748 | list_del(&msr->r_list); |
| @@ -741,7 +750,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg, | |||
| 741 | wake_q_add(wake_q, msr->r_tsk); | 750 | wake_q_add(wake_q, msr->r_tsk); |
| 742 | WRITE_ONCE(msr->r_msg, ERR_PTR(-E2BIG)); | 751 | WRITE_ONCE(msr->r_msg, ERR_PTR(-E2BIG)); |
| 743 | } else { | 752 | } else { |
| 744 | msq->q_lrpid = task_pid_vnr(msr->r_tsk); | 753 | ipc_update_pid(&msq->q_lrpid, task_pid(msr->r_tsk)); |
| 745 | msq->q_rtime = get_seconds(); | 754 | msq->q_rtime = get_seconds(); |
| 746 | 755 | ||
| 747 | wake_q_add(wake_q, msr->r_tsk); | 756 | wake_q_add(wake_q, msr->r_tsk); |
| @@ -799,7 +808,7 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext, | |||
| 799 | goto out_unlock0; | 808 | goto out_unlock0; |
| 800 | } | 809 | } |
| 801 | 810 | ||
| 802 | err = security_msg_queue_msgsnd(msq, msg, msgflg); | 811 | err = security_msg_queue_msgsnd(&msq->q_perm, msg, msgflg); |
| 803 | if (err) | 812 | if (err) |
| 804 | goto out_unlock0; | 813 | goto out_unlock0; |
| 805 | 814 | ||
| @@ -842,7 +851,7 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext, | |||
| 842 | 851 | ||
| 843 | } | 852 | } |
| 844 | 853 | ||
| 845 | msq->q_lspid = task_tgid_vnr(current); | 854 | ipc_update_pid(&msq->q_lspid, task_tgid(current)); |
| 846 | msq->q_stime = get_seconds(); | 855 | msq->q_stime = get_seconds(); |
| 847 | 856 | ||
| 848 | if (!pipelined_send(msq, msg, &wake_q)) { | 857 | if (!pipelined_send(msq, msg, &wake_q)) { |
| @@ -987,7 +996,7 @@ static struct msg_msg *find_msg(struct msg_queue *msq, long *msgtyp, int mode) | |||
| 987 | 996 | ||
| 988 | list_for_each_entry(msg, &msq->q_messages, m_list) { | 997 | list_for_each_entry(msg, &msq->q_messages, m_list) { |
| 989 | if (testmsg(msg, *msgtyp, mode) && | 998 | if (testmsg(msg, *msgtyp, mode) && |
| 990 | !security_msg_queue_msgrcv(msq, msg, current, | 999 | !security_msg_queue_msgrcv(&msq->q_perm, msg, current, |
| 991 | *msgtyp, mode)) { | 1000 | *msgtyp, mode)) { |
| 992 | if (mode == SEARCH_LESSEQUAL && msg->m_type != 1) { | 1001 | if (mode == SEARCH_LESSEQUAL && msg->m_type != 1) { |
| 993 | *msgtyp = msg->m_type - 1; | 1002 | *msgtyp = msg->m_type - 1; |
| @@ -1072,7 +1081,7 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in | |||
| 1072 | list_del(&msg->m_list); | 1081 | list_del(&msg->m_list); |
| 1073 | msq->q_qnum--; | 1082 | msq->q_qnum--; |
| 1074 | msq->q_rtime = get_seconds(); | 1083 | msq->q_rtime = get_seconds(); |
| 1075 | msq->q_lrpid = task_tgid_vnr(current); | 1084 | ipc_update_pid(&msq->q_lrpid, task_tgid(current)); |
| 1076 | msq->q_cbytes -= msg->m_ts; | 1085 | msq->q_cbytes -= msg->m_ts; |
| 1077 | atomic_sub(msg->m_ts, &ns->msg_bytes); | 1086 | atomic_sub(msg->m_ts, &ns->msg_bytes); |
| 1078 | atomic_dec(&ns->msg_hdrs); | 1087 | atomic_dec(&ns->msg_hdrs); |
| @@ -1227,6 +1236,7 @@ void msg_exit_ns(struct ipc_namespace *ns) | |||
| 1227 | #ifdef CONFIG_PROC_FS | 1236 | #ifdef CONFIG_PROC_FS |
| 1228 | static int sysvipc_msg_proc_show(struct seq_file *s, void *it) | 1237 | static int sysvipc_msg_proc_show(struct seq_file *s, void *it) |
| 1229 | { | 1238 | { |
| 1239 | struct pid_namespace *pid_ns = ipc_seq_pid_ns(s); | ||
| 1230 | struct user_namespace *user_ns = seq_user_ns(s); | 1240 | struct user_namespace *user_ns = seq_user_ns(s); |
| 1231 | struct kern_ipc_perm *ipcp = it; | 1241 | struct kern_ipc_perm *ipcp = it; |
| 1232 | struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm); | 1242 | struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm); |
| @@ -1238,8 +1248,8 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it) | |||
| 1238 | msq->q_perm.mode, | 1248 | msq->q_perm.mode, |
| 1239 | msq->q_cbytes, | 1249 | msq->q_cbytes, |
| 1240 | msq->q_qnum, | 1250 | msq->q_qnum, |
| 1241 | msq->q_lspid, | 1251 | pid_nr_ns(msq->q_lspid, pid_ns), |
| 1242 | msq->q_lrpid, | 1252 | pid_nr_ns(msq->q_lrpid, pid_ns), |
| 1243 | from_kuid_munged(user_ns, msq->q_perm.uid), | 1253 | from_kuid_munged(user_ns, msq->q_perm.uid), |
| 1244 | from_kgid_munged(user_ns, msq->q_perm.gid), | 1254 | from_kgid_munged(user_ns, msq->q_perm.gid), |
| 1245 | from_kuid_munged(user_ns, msq->q_perm.cuid), | 1255 | from_kuid_munged(user_ns, msq->q_perm.cuid), |
| @@ -88,13 +88,47 @@ | |||
| 88 | #include <linux/uaccess.h> | 88 | #include <linux/uaccess.h> |
| 89 | #include "util.h" | 89 | #include "util.h" |
| 90 | 90 | ||
| 91 | /* One semaphore structure for each semaphore in the system. */ | ||
| 92 | struct sem { | ||
| 93 | int semval; /* current value */ | ||
| 94 | /* | ||
| 95 | * PID of the process that last modified the semaphore. For | ||
| 96 | * Linux, specifically these are: | ||
| 97 | * - semop | ||
| 98 | * - semctl, via SETVAL and SETALL. | ||
| 99 | * - at task exit when performing undo adjustments (see exit_sem). | ||
| 100 | */ | ||
| 101 | struct pid *sempid; | ||
| 102 | spinlock_t lock; /* spinlock for fine-grained semtimedop */ | ||
| 103 | struct list_head pending_alter; /* pending single-sop operations */ | ||
| 104 | /* that alter the semaphore */ | ||
| 105 | struct list_head pending_const; /* pending single-sop operations */ | ||
| 106 | /* that do not alter the semaphore*/ | ||
| 107 | time_t sem_otime; /* candidate for sem_otime */ | ||
| 108 | } ____cacheline_aligned_in_smp; | ||
| 109 | |||
| 110 | /* One sem_array data structure for each set of semaphores in the system. */ | ||
| 111 | struct sem_array { | ||
| 112 | struct kern_ipc_perm sem_perm; /* permissions .. see ipc.h */ | ||
| 113 | time64_t sem_ctime; /* create/last semctl() time */ | ||
| 114 | struct list_head pending_alter; /* pending operations */ | ||
| 115 | /* that alter the array */ | ||
| 116 | struct list_head pending_const; /* pending complex operations */ | ||
| 117 | /* that do not alter semvals */ | ||
| 118 | struct list_head list_id; /* undo requests on this array */ | ||
| 119 | int sem_nsems; /* no. of semaphores in array */ | ||
| 120 | int complex_count; /* pending complex operations */ | ||
| 121 | unsigned int use_global_lock;/* >0: global lock required */ | ||
| 122 | |||
| 123 | struct sem sems[]; | ||
| 124 | } __randomize_layout; | ||
| 91 | 125 | ||
| 92 | /* One queue for each sleeping process in the system. */ | 126 | /* One queue for each sleeping process in the system. */ |
| 93 | struct sem_queue { | 127 | struct sem_queue { |
| 94 | struct list_head list; /* queue of pending operations */ | 128 | struct list_head list; /* queue of pending operations */ |
| 95 | struct task_struct *sleeper; /* this process */ | 129 | struct task_struct *sleeper; /* this process */ |
| 96 | struct sem_undo *undo; /* undo structure */ | 130 | struct sem_undo *undo; /* undo structure */ |
| 97 | int pid; /* process id of requesting process */ | 131 | struct pid *pid; /* process id of requesting process */ |
| 98 | int status; /* completion status of operation */ | 132 | int status; /* completion status of operation */ |
| 99 | struct sembuf *sops; /* array of pending operations */ | 133 | struct sembuf *sops; /* array of pending operations */ |
| 100 | struct sembuf *blocking; /* the operation that blocked */ | 134 | struct sembuf *blocking; /* the operation that blocked */ |
| @@ -265,7 +299,7 @@ static void sem_rcu_free(struct rcu_head *head) | |||
| 265 | struct kern_ipc_perm *p = container_of(head, struct kern_ipc_perm, rcu); | 299 | struct kern_ipc_perm *p = container_of(head, struct kern_ipc_perm, rcu); |
| 266 | struct sem_array *sma = container_of(p, struct sem_array, sem_perm); | 300 | struct sem_array *sma = container_of(p, struct sem_array, sem_perm); |
| 267 | 301 | ||
| 268 | security_sem_free(sma); | 302 | security_sem_free(&sma->sem_perm); |
| 269 | kvfree(sma); | 303 | kvfree(sma); |
| 270 | } | 304 | } |
| 271 | 305 | ||
| @@ -495,7 +529,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) | |||
| 495 | sma->sem_perm.key = key; | 529 | sma->sem_perm.key = key; |
| 496 | 530 | ||
| 497 | sma->sem_perm.security = NULL; | 531 | sma->sem_perm.security = NULL; |
| 498 | retval = security_sem_alloc(sma); | 532 | retval = security_sem_alloc(&sma->sem_perm); |
| 499 | if (retval) { | 533 | if (retval) { |
| 500 | kvfree(sma); | 534 | kvfree(sma); |
| 501 | return retval; | 535 | return retval; |
| @@ -533,17 +567,6 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) | |||
| 533 | /* | 567 | /* |
| 534 | * Called with sem_ids.rwsem and ipcp locked. | 568 | * Called with sem_ids.rwsem and ipcp locked. |
| 535 | */ | 569 | */ |
| 536 | static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg) | ||
| 537 | { | ||
| 538 | struct sem_array *sma; | ||
| 539 | |||
| 540 | sma = container_of(ipcp, struct sem_array, sem_perm); | ||
| 541 | return security_sem_associate(sma, semflg); | ||
| 542 | } | ||
| 543 | |||
| 544 | /* | ||
| 545 | * Called with sem_ids.rwsem and ipcp locked. | ||
| 546 | */ | ||
| 547 | static inline int sem_more_checks(struct kern_ipc_perm *ipcp, | 570 | static inline int sem_more_checks(struct kern_ipc_perm *ipcp, |
| 548 | struct ipc_params *params) | 571 | struct ipc_params *params) |
| 549 | { | 572 | { |
| @@ -561,7 +584,7 @@ long ksys_semget(key_t key, int nsems, int semflg) | |||
| 561 | struct ipc_namespace *ns; | 584 | struct ipc_namespace *ns; |
| 562 | static const struct ipc_ops sem_ops = { | 585 | static const struct ipc_ops sem_ops = { |
| 563 | .getnew = newary, | 586 | .getnew = newary, |
| 564 | .associate = sem_security, | 587 | .associate = security_sem_associate, |
| 565 | .more_checks = sem_more_checks, | 588 | .more_checks = sem_more_checks, |
| 566 | }; | 589 | }; |
| 567 | struct ipc_params sem_params; | 590 | struct ipc_params sem_params; |
| @@ -602,7 +625,8 @@ SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg) | |||
| 602 | */ | 625 | */ |
| 603 | static int perform_atomic_semop_slow(struct sem_array *sma, struct sem_queue *q) | 626 | static int perform_atomic_semop_slow(struct sem_array *sma, struct sem_queue *q) |
| 604 | { | 627 | { |
| 605 | int result, sem_op, nsops, pid; | 628 | int result, sem_op, nsops; |
| 629 | struct pid *pid; | ||
| 606 | struct sembuf *sop; | 630 | struct sembuf *sop; |
| 607 | struct sem *curr; | 631 | struct sem *curr; |
| 608 | struct sembuf *sops; | 632 | struct sembuf *sops; |
| @@ -640,7 +664,7 @@ static int perform_atomic_semop_slow(struct sem_array *sma, struct sem_queue *q) | |||
| 640 | sop--; | 664 | sop--; |
| 641 | pid = q->pid; | 665 | pid = q->pid; |
| 642 | while (sop >= sops) { | 666 | while (sop >= sops) { |
| 643 | sma->sems[sop->sem_num].sempid = pid; | 667 | ipc_update_pid(&sma->sems[sop->sem_num].sempid, pid); |
| 644 | sop--; | 668 | sop--; |
| 645 | } | 669 | } |
| 646 | 670 | ||
| @@ -727,7 +751,7 @@ static int perform_atomic_semop(struct sem_array *sma, struct sem_queue *q) | |||
| 727 | un->semadj[sop->sem_num] = undo; | 751 | un->semadj[sop->sem_num] = undo; |
| 728 | } | 752 | } |
| 729 | curr->semval += sem_op; | 753 | curr->semval += sem_op; |
| 730 | curr->sempid = q->pid; | 754 | ipc_update_pid(&curr->sempid, q->pid); |
| 731 | } | 755 | } |
| 732 | 756 | ||
| 733 | return 0; | 757 | return 0; |
| @@ -1134,6 +1158,7 @@ static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) | |||
| 1134 | unlink_queue(sma, q); | 1158 | unlink_queue(sma, q); |
| 1135 | wake_up_sem_queue_prepare(q, -EIDRM, &wake_q); | 1159 | wake_up_sem_queue_prepare(q, -EIDRM, &wake_q); |
| 1136 | } | 1160 | } |
| 1161 | ipc_update_pid(&sem->sempid, NULL); | ||
| 1137 | } | 1162 | } |
| 1138 | 1163 | ||
| 1139 | /* Remove the semaphore set from the IDR */ | 1164 | /* Remove the semaphore set from the IDR */ |
| @@ -1214,7 +1239,7 @@ static int semctl_stat(struct ipc_namespace *ns, int semid, | |||
| 1214 | if (ipcperms(ns, &sma->sem_perm, S_IRUGO)) | 1239 | if (ipcperms(ns, &sma->sem_perm, S_IRUGO)) |
| 1215 | goto out_unlock; | 1240 | goto out_unlock; |
| 1216 | 1241 | ||
| 1217 | err = security_sem_semctl(sma, cmd); | 1242 | err = security_sem_semctl(&sma->sem_perm, cmd); |
| 1218 | if (err) | 1243 | if (err) |
| 1219 | goto out_unlock; | 1244 | goto out_unlock; |
| 1220 | 1245 | ||
| @@ -1305,7 +1330,7 @@ static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum, | |||
| 1305 | return -EACCES; | 1330 | return -EACCES; |
| 1306 | } | 1331 | } |
| 1307 | 1332 | ||
| 1308 | err = security_sem_semctl(sma, SETVAL); | 1333 | err = security_sem_semctl(&sma->sem_perm, SETVAL); |
| 1309 | if (err) { | 1334 | if (err) { |
| 1310 | rcu_read_unlock(); | 1335 | rcu_read_unlock(); |
| 1311 | return -EACCES; | 1336 | return -EACCES; |
| @@ -1326,7 +1351,7 @@ static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum, | |||
| 1326 | un->semadj[semnum] = 0; | 1351 | un->semadj[semnum] = 0; |
| 1327 | 1352 | ||
| 1328 | curr->semval = val; | 1353 | curr->semval = val; |
| 1329 | curr->sempid = task_tgid_vnr(current); | 1354 | ipc_update_pid(&curr->sempid, task_tgid(current)); |
| 1330 | sma->sem_ctime = ktime_get_real_seconds(); | 1355 | sma->sem_ctime = ktime_get_real_seconds(); |
| 1331 | /* maybe some queued-up processes were waiting for this */ | 1356 | /* maybe some queued-up processes were waiting for this */ |
| 1332 | do_smart_update(sma, NULL, 0, 0, &wake_q); | 1357 | do_smart_update(sma, NULL, 0, 0, &wake_q); |
| @@ -1359,7 +1384,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum, | |||
| 1359 | if (ipcperms(ns, &sma->sem_perm, cmd == SETALL ? S_IWUGO : S_IRUGO)) | 1384 | if (ipcperms(ns, &sma->sem_perm, cmd == SETALL ? S_IWUGO : S_IRUGO)) |
| 1360 | goto out_rcu_wakeup; | 1385 | goto out_rcu_wakeup; |
| 1361 | 1386 | ||
| 1362 | err = security_sem_semctl(sma, cmd); | 1387 | err = security_sem_semctl(&sma->sem_perm, cmd); |
| 1363 | if (err) | 1388 | if (err) |
| 1364 | goto out_rcu_wakeup; | 1389 | goto out_rcu_wakeup; |
| 1365 | 1390 | ||
| @@ -1447,7 +1472,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum, | |||
| 1447 | 1472 | ||
| 1448 | for (i = 0; i < nsems; i++) { | 1473 | for (i = 0; i < nsems; i++) { |
| 1449 | sma->sems[i].semval = sem_io[i]; | 1474 | sma->sems[i].semval = sem_io[i]; |
| 1450 | sma->sems[i].sempid = task_tgid_vnr(current); | 1475 | ipc_update_pid(&sma->sems[i].sempid, task_tgid(current)); |
| 1451 | } | 1476 | } |
| 1452 | 1477 | ||
| 1453 | ipc_assert_locked_object(&sma->sem_perm); | 1478 | ipc_assert_locked_object(&sma->sem_perm); |
| @@ -1479,7 +1504,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum, | |||
| 1479 | err = curr->semval; | 1504 | err = curr->semval; |
| 1480 | goto out_unlock; | 1505 | goto out_unlock; |
| 1481 | case GETPID: | 1506 | case GETPID: |
| 1482 | err = curr->sempid; | 1507 | err = pid_vnr(curr->sempid); |
| 1483 | goto out_unlock; | 1508 | goto out_unlock; |
| 1484 | case GETNCNT: | 1509 | case GETNCNT: |
| 1485 | err = count_semcnt(sma, semnum, 0); | 1510 | err = count_semcnt(sma, semnum, 0); |
| @@ -1550,7 +1575,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid, | |||
| 1550 | 1575 | ||
| 1551 | sma = container_of(ipcp, struct sem_array, sem_perm); | 1576 | sma = container_of(ipcp, struct sem_array, sem_perm); |
| 1552 | 1577 | ||
| 1553 | err = security_sem_semctl(sma, cmd); | 1578 | err = security_sem_semctl(&sma->sem_perm, cmd); |
| 1554 | if (err) | 1579 | if (err) |
| 1555 | goto out_unlock1; | 1580 | goto out_unlock1; |
| 1556 | 1581 | ||
| @@ -1977,7 +2002,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops, | |||
| 1977 | goto out_free; | 2002 | goto out_free; |
| 1978 | } | 2003 | } |
| 1979 | 2004 | ||
| 1980 | error = security_sem_semop(sma, sops, nsops, alter); | 2005 | error = security_sem_semop(&sma->sem_perm, sops, nsops, alter); |
| 1981 | if (error) { | 2006 | if (error) { |
| 1982 | rcu_read_unlock(); | 2007 | rcu_read_unlock(); |
| 1983 | goto out_free; | 2008 | goto out_free; |
| @@ -2008,7 +2033,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops, | |||
| 2008 | queue.sops = sops; | 2033 | queue.sops = sops; |
| 2009 | queue.nsops = nsops; | 2034 | queue.nsops = nsops; |
| 2010 | queue.undo = un; | 2035 | queue.undo = un; |
| 2011 | queue.pid = task_tgid_vnr(current); | 2036 | queue.pid = task_tgid(current); |
| 2012 | queue.alter = alter; | 2037 | queue.alter = alter; |
| 2013 | queue.dupsop = dupsop; | 2038 | queue.dupsop = dupsop; |
| 2014 | 2039 | ||
| @@ -2315,7 +2340,7 @@ void exit_sem(struct task_struct *tsk) | |||
| 2315 | semaphore->semval = 0; | 2340 | semaphore->semval = 0; |
| 2316 | if (semaphore->semval > SEMVMX) | 2341 | if (semaphore->semval > SEMVMX) |
| 2317 | semaphore->semval = SEMVMX; | 2342 | semaphore->semval = SEMVMX; |
| 2318 | semaphore->sempid = task_tgid_vnr(current); | 2343 | ipc_update_pid(&semaphore->sempid, task_tgid(current)); |
| 2319 | } | 2344 | } |
| 2320 | } | 2345 | } |
| 2321 | /* maybe some queued-up processes were waiting for this */ | 2346 | /* maybe some queued-up processes were waiting for this */ |
| @@ -48,6 +48,28 @@ | |||
| 48 | 48 | ||
| 49 | #include "util.h" | 49 | #include "util.h" |
| 50 | 50 | ||
| 51 | struct shmid_kernel /* private to the kernel */ | ||
| 52 | { | ||
| 53 | struct kern_ipc_perm shm_perm; | ||
| 54 | struct file *shm_file; | ||
| 55 | unsigned long shm_nattch; | ||
| 56 | unsigned long shm_segsz; | ||
| 57 | time64_t shm_atim; | ||
| 58 | time64_t shm_dtim; | ||
| 59 | time64_t shm_ctim; | ||
| 60 | struct pid *shm_cprid; | ||
| 61 | struct pid *shm_lprid; | ||
| 62 | struct user_struct *mlock_user; | ||
| 63 | |||
| 64 | /* The task created the shm object. NULL if the task is dead. */ | ||
| 65 | struct task_struct *shm_creator; | ||
| 66 | struct list_head shm_clist; /* list by creator */ | ||
| 67 | } __randomize_layout; | ||
| 68 | |||
| 69 | /* shm_mode upper byte flags */ | ||
| 70 | #define SHM_DEST 01000 /* segment will be destroyed on last detach */ | ||
| 71 | #define SHM_LOCKED 02000 /* segment will not be swapped */ | ||
| 72 | |||
| 51 | struct shm_file_data { | 73 | struct shm_file_data { |
| 52 | int id; | 74 | int id; |
| 53 | struct ipc_namespace *ns; | 75 | struct ipc_namespace *ns; |
| @@ -181,7 +203,7 @@ static void shm_rcu_free(struct rcu_head *head) | |||
| 181 | rcu); | 203 | rcu); |
| 182 | struct shmid_kernel *shp = container_of(ptr, struct shmid_kernel, | 204 | struct shmid_kernel *shp = container_of(ptr, struct shmid_kernel, |
| 183 | shm_perm); | 205 | shm_perm); |
| 184 | security_shm_free(shp); | 206 | security_shm_free(&shp->shm_perm); |
| 185 | kvfree(shp); | 207 | kvfree(shp); |
| 186 | } | 208 | } |
| 187 | 209 | ||
| @@ -204,7 +226,7 @@ static int __shm_open(struct vm_area_struct *vma) | |||
| 204 | return PTR_ERR(shp); | 226 | return PTR_ERR(shp); |
| 205 | 227 | ||
| 206 | shp->shm_atim = ktime_get_real_seconds(); | 228 | shp->shm_atim = ktime_get_real_seconds(); |
| 207 | shp->shm_lprid = task_tgid_vnr(current); | 229 | ipc_update_pid(&shp->shm_lprid, task_tgid(current)); |
| 208 | shp->shm_nattch++; | 230 | shp->shm_nattch++; |
| 209 | shm_unlock(shp); | 231 | shm_unlock(shp); |
| 210 | return 0; | 232 | return 0; |
| @@ -245,6 +267,8 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) | |||
| 245 | user_shm_unlock(i_size_read(file_inode(shm_file)), | 267 | user_shm_unlock(i_size_read(file_inode(shm_file)), |
| 246 | shp->mlock_user); | 268 | shp->mlock_user); |
| 247 | fput(shm_file); | 269 | fput(shm_file); |
| 270 | ipc_update_pid(&shp->shm_cprid, NULL); | ||
| 271 | ipc_update_pid(&shp->shm_lprid, NULL); | ||
| 248 | ipc_rcu_putref(&shp->shm_perm, shm_rcu_free); | 272 | ipc_rcu_putref(&shp->shm_perm, shm_rcu_free); |
| 249 | } | 273 | } |
| 250 | 274 | ||
| @@ -289,7 +313,7 @@ static void shm_close(struct vm_area_struct *vma) | |||
| 289 | if (WARN_ON_ONCE(IS_ERR(shp))) | 313 | if (WARN_ON_ONCE(IS_ERR(shp))) |
| 290 | goto done; /* no-op */ | 314 | goto done; /* no-op */ |
| 291 | 315 | ||
| 292 | shp->shm_lprid = task_tgid_vnr(current); | 316 | ipc_update_pid(&shp->shm_lprid, task_tgid(current)); |
| 293 | shp->shm_dtim = ktime_get_real_seconds(); | 317 | shp->shm_dtim = ktime_get_real_seconds(); |
| 294 | shp->shm_nattch--; | 318 | shp->shm_nattch--; |
| 295 | if (shm_may_destroy(ns, shp)) | 319 | if (shm_may_destroy(ns, shp)) |
| @@ -566,7 +590,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) | |||
| 566 | shp->mlock_user = NULL; | 590 | shp->mlock_user = NULL; |
| 567 | 591 | ||
| 568 | shp->shm_perm.security = NULL; | 592 | shp->shm_perm.security = NULL; |
| 569 | error = security_shm_alloc(shp); | 593 | error = security_shm_alloc(&shp->shm_perm); |
| 570 | if (error) { | 594 | if (error) { |
| 571 | kvfree(shp); | 595 | kvfree(shp); |
| 572 | return error; | 596 | return error; |
| @@ -604,8 +628,8 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) | |||
| 604 | if (IS_ERR(file)) | 628 | if (IS_ERR(file)) |
| 605 | goto no_file; | 629 | goto no_file; |
| 606 | 630 | ||
| 607 | shp->shm_cprid = task_tgid_vnr(current); | 631 | shp->shm_cprid = get_pid(task_tgid(current)); |
| 608 | shp->shm_lprid = 0; | 632 | shp->shm_lprid = NULL; |
| 609 | shp->shm_atim = shp->shm_dtim = 0; | 633 | shp->shm_atim = shp->shm_dtim = 0; |
| 610 | shp->shm_ctim = ktime_get_real_seconds(); | 634 | shp->shm_ctim = ktime_get_real_seconds(); |
| 611 | shp->shm_segsz = size; | 635 | shp->shm_segsz = size; |
| @@ -634,6 +658,8 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) | |||
| 634 | return error; | 658 | return error; |
| 635 | 659 | ||
| 636 | no_id: | 660 | no_id: |
| 661 | ipc_update_pid(&shp->shm_cprid, NULL); | ||
| 662 | ipc_update_pid(&shp->shm_lprid, NULL); | ||
| 637 | if (is_file_hugepages(file) && shp->mlock_user) | 663 | if (is_file_hugepages(file) && shp->mlock_user) |
| 638 | user_shm_unlock(size, shp->mlock_user); | 664 | user_shm_unlock(size, shp->mlock_user); |
| 639 | fput(file); | 665 | fput(file); |
| @@ -645,17 +671,6 @@ no_file: | |||
| 645 | /* | 671 | /* |
| 646 | * Called with shm_ids.rwsem and ipcp locked. | 672 | * Called with shm_ids.rwsem and ipcp locked. |
| 647 | */ | 673 | */ |
| 648 | static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg) | ||
| 649 | { | ||
| 650 | struct shmid_kernel *shp; | ||
| 651 | |||
| 652 | shp = container_of(ipcp, struct shmid_kernel, shm_perm); | ||
| 653 | return security_shm_associate(shp, shmflg); | ||
| 654 | } | ||
| 655 | |||
| 656 | /* | ||
| 657 | * Called with shm_ids.rwsem and ipcp locked. | ||
| 658 | */ | ||
| 659 | static inline int shm_more_checks(struct kern_ipc_perm *ipcp, | 674 | static inline int shm_more_checks(struct kern_ipc_perm *ipcp, |
| 660 | struct ipc_params *params) | 675 | struct ipc_params *params) |
| 661 | { | 676 | { |
| @@ -673,7 +688,7 @@ long ksys_shmget(key_t key, size_t size, int shmflg) | |||
| 673 | struct ipc_namespace *ns; | 688 | struct ipc_namespace *ns; |
| 674 | static const struct ipc_ops shm_ops = { | 689 | static const struct ipc_ops shm_ops = { |
| 675 | .getnew = newseg, | 690 | .getnew = newseg, |
| 676 | .associate = shm_security, | 691 | .associate = security_shm_associate, |
| 677 | .more_checks = shm_more_checks, | 692 | .more_checks = shm_more_checks, |
| 678 | }; | 693 | }; |
| 679 | struct ipc_params shm_params; | 694 | struct ipc_params shm_params; |
| @@ -852,7 +867,7 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, | |||
| 852 | 867 | ||
| 853 | shp = container_of(ipcp, struct shmid_kernel, shm_perm); | 868 | shp = container_of(ipcp, struct shmid_kernel, shm_perm); |
| 854 | 869 | ||
| 855 | err = security_shm_shmctl(shp, cmd); | 870 | err = security_shm_shmctl(&shp->shm_perm, cmd); |
| 856 | if (err) | 871 | if (err) |
| 857 | goto out_unlock1; | 872 | goto out_unlock1; |
| 858 | 873 | ||
| @@ -951,7 +966,7 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid, | |||
| 951 | if (ipcperms(ns, &shp->shm_perm, S_IRUGO)) | 966 | if (ipcperms(ns, &shp->shm_perm, S_IRUGO)) |
| 952 | goto out_unlock; | 967 | goto out_unlock; |
| 953 | 968 | ||
| 954 | err = security_shm_shmctl(shp, cmd); | 969 | err = security_shm_shmctl(&shp->shm_perm, cmd); |
| 955 | if (err) | 970 | if (err) |
| 956 | goto out_unlock; | 971 | goto out_unlock; |
| 957 | 972 | ||
| @@ -968,8 +983,8 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid, | |||
| 968 | tbuf->shm_atime = shp->shm_atim; | 983 | tbuf->shm_atime = shp->shm_atim; |
| 969 | tbuf->shm_dtime = shp->shm_dtim; | 984 | tbuf->shm_dtime = shp->shm_dtim; |
| 970 | tbuf->shm_ctime = shp->shm_ctim; | 985 | tbuf->shm_ctime = shp->shm_ctim; |
| 971 | tbuf->shm_cpid = shp->shm_cprid; | 986 | tbuf->shm_cpid = pid_vnr(shp->shm_cprid); |
| 972 | tbuf->shm_lpid = shp->shm_lprid; | 987 | tbuf->shm_lpid = pid_vnr(shp->shm_lprid); |
| 973 | tbuf->shm_nattch = shp->shm_nattch; | 988 | tbuf->shm_nattch = shp->shm_nattch; |
| 974 | 989 | ||
| 975 | ipc_unlock_object(&shp->shm_perm); | 990 | ipc_unlock_object(&shp->shm_perm); |
| @@ -995,7 +1010,7 @@ static int shmctl_do_lock(struct ipc_namespace *ns, int shmid, int cmd) | |||
| 995 | } | 1010 | } |
| 996 | 1011 | ||
| 997 | audit_ipc_obj(&(shp->shm_perm)); | 1012 | audit_ipc_obj(&(shp->shm_perm)); |
| 998 | err = security_shm_shmctl(shp, cmd); | 1013 | err = security_shm_shmctl(&shp->shm_perm, cmd); |
| 999 | if (err) | 1014 | if (err) |
| 1000 | goto out_unlock1; | 1015 | goto out_unlock1; |
| 1001 | 1016 | ||
| @@ -1375,7 +1390,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, | |||
| 1375 | if (ipcperms(ns, &shp->shm_perm, acc_mode)) | 1390 | if (ipcperms(ns, &shp->shm_perm, acc_mode)) |
| 1376 | goto out_unlock; | 1391 | goto out_unlock; |
| 1377 | 1392 | ||
| 1378 | err = security_shm_shmat(shp, shmaddr, shmflg); | 1393 | err = security_shm_shmat(&shp->shm_perm, shmaddr, shmflg); |
| 1379 | if (err) | 1394 | if (err) |
| 1380 | goto out_unlock; | 1395 | goto out_unlock; |
| 1381 | 1396 | ||
| @@ -1618,6 +1633,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) | |||
| 1618 | #ifdef CONFIG_PROC_FS | 1633 | #ifdef CONFIG_PROC_FS |
| 1619 | static int sysvipc_shm_proc_show(struct seq_file *s, void *it) | 1634 | static int sysvipc_shm_proc_show(struct seq_file *s, void *it) |
| 1620 | { | 1635 | { |
| 1636 | struct pid_namespace *pid_ns = ipc_seq_pid_ns(s); | ||
| 1621 | struct user_namespace *user_ns = seq_user_ns(s); | 1637 | struct user_namespace *user_ns = seq_user_ns(s); |
| 1622 | struct kern_ipc_perm *ipcp = it; | 1638 | struct kern_ipc_perm *ipcp = it; |
| 1623 | struct shmid_kernel *shp; | 1639 | struct shmid_kernel *shp; |
| @@ -1640,8 +1656,8 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it) | |||
| 1640 | shp->shm_perm.id, | 1656 | shp->shm_perm.id, |
| 1641 | shp->shm_perm.mode, | 1657 | shp->shm_perm.mode, |
| 1642 | shp->shm_segsz, | 1658 | shp->shm_segsz, |
| 1643 | shp->shm_cprid, | 1659 | pid_nr_ns(shp->shm_cprid, pid_ns), |
| 1644 | shp->shm_lprid, | 1660 | pid_nr_ns(shp->shm_lprid, pid_ns), |
| 1645 | shp->shm_nattch, | 1661 | shp->shm_nattch, |
| 1646 | from_kuid_munged(user_ns, shp->shm_perm.uid), | 1662 | from_kuid_munged(user_ns, shp->shm_perm.uid), |
| 1647 | from_kgid_munged(user_ns, shp->shm_perm.gid), | 1663 | from_kgid_munged(user_ns, shp->shm_perm.gid), |
diff --git a/ipc/util.c b/ipc/util.c index 4ed5a17dd06f..3783b7991cc7 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
| @@ -747,9 +747,16 @@ int ipc_parse_version(int *cmd) | |||
| 747 | #ifdef CONFIG_PROC_FS | 747 | #ifdef CONFIG_PROC_FS |
| 748 | struct ipc_proc_iter { | 748 | struct ipc_proc_iter { |
| 749 | struct ipc_namespace *ns; | 749 | struct ipc_namespace *ns; |
| 750 | struct pid_namespace *pid_ns; | ||
| 750 | struct ipc_proc_iface *iface; | 751 | struct ipc_proc_iface *iface; |
| 751 | }; | 752 | }; |
| 752 | 753 | ||
| 754 | struct pid_namespace *ipc_seq_pid_ns(struct seq_file *s) | ||
| 755 | { | ||
| 756 | struct ipc_proc_iter *iter = s->private; | ||
| 757 | return iter->pid_ns; | ||
| 758 | } | ||
| 759 | |||
| 753 | /* | 760 | /* |
| 754 | * This routine locks the ipc structure found at least at position pos. | 761 | * This routine locks the ipc structure found at least at position pos. |
| 755 | */ | 762 | */ |
| @@ -872,6 +879,7 @@ static int sysvipc_proc_open(struct inode *inode, struct file *file) | |||
| 872 | 879 | ||
| 873 | iter->iface = PDE_DATA(inode); | 880 | iter->iface = PDE_DATA(inode); |
| 874 | iter->ns = get_ipc_ns(current->nsproxy->ipc_ns); | 881 | iter->ns = get_ipc_ns(current->nsproxy->ipc_ns); |
| 882 | iter->pid_ns = get_pid_ns(task_active_pid_ns(current)); | ||
| 875 | 883 | ||
| 876 | return 0; | 884 | return 0; |
| 877 | } | 885 | } |
| @@ -881,6 +889,7 @@ static int sysvipc_proc_release(struct inode *inode, struct file *file) | |||
| 881 | struct seq_file *seq = file->private_data; | 889 | struct seq_file *seq = file->private_data; |
| 882 | struct ipc_proc_iter *iter = seq->private; | 890 | struct ipc_proc_iter *iter = seq->private; |
| 883 | put_ipc_ns(iter->ns); | 891 | put_ipc_ns(iter->ns); |
| 892 | put_pid_ns(iter->pid_ns); | ||
| 884 | return seq_release_private(inode, file); | 893 | return seq_release_private(inode, file); |
| 885 | } | 894 | } |
| 886 | 895 | ||
diff --git a/ipc/util.h b/ipc/util.h index 51853dc2f340..acc5159e96d0 100644 --- a/ipc/util.h +++ b/ipc/util.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
| 16 | #include <linux/ipc_namespace.h> | 16 | #include <linux/ipc_namespace.h> |
| 17 | 17 | ||
| 18 | #define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */ | ||
| 18 | #define SEQ_MULTIPLIER (IPCMNI) | 19 | #define SEQ_MULTIPLIER (IPCMNI) |
| 19 | 20 | ||
| 20 | int sem_init(void); | 21 | int sem_init(void); |
| @@ -22,6 +23,7 @@ int msg_init(void); | |||
| 22 | void shm_init(void); | 23 | void shm_init(void); |
| 23 | 24 | ||
| 24 | struct ipc_namespace; | 25 | struct ipc_namespace; |
| 26 | struct pid_namespace; | ||
| 25 | 27 | ||
| 26 | #ifdef CONFIG_POSIX_MQUEUE | 28 | #ifdef CONFIG_POSIX_MQUEUE |
| 27 | extern void mq_clear_sbinfo(struct ipc_namespace *ns); | 29 | extern void mq_clear_sbinfo(struct ipc_namespace *ns); |
| @@ -85,6 +87,7 @@ int ipc_init_ids(struct ipc_ids *); | |||
| 85 | #ifdef CONFIG_PROC_FS | 87 | #ifdef CONFIG_PROC_FS |
| 86 | void __init ipc_init_proc_interface(const char *path, const char *header, | 88 | void __init ipc_init_proc_interface(const char *path, const char *header, |
| 87 | int ids, int (*show)(struct seq_file *, void *)); | 89 | int ids, int (*show)(struct seq_file *, void *)); |
| 90 | struct pid_namespace *ipc_seq_pid_ns(struct seq_file *); | ||
| 88 | #else | 91 | #else |
| 89 | #define ipc_init_proc_interface(path, header, ids, show) do {} while (0) | 92 | #define ipc_init_proc_interface(path, header, ids, show) do {} while (0) |
| 90 | #endif | 93 | #endif |
| @@ -149,6 +152,15 @@ struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns, | |||
| 149 | struct ipc_ids *ids, int id, int cmd, | 152 | struct ipc_ids *ids, int id, int cmd, |
| 150 | struct ipc64_perm *perm, int extra_perm); | 153 | struct ipc64_perm *perm, int extra_perm); |
| 151 | 154 | ||
| 155 | static inline void ipc_update_pid(struct pid **pos, struct pid *pid) | ||
| 156 | { | ||
| 157 | struct pid *old = *pos; | ||
| 158 | if (old != pid) { | ||
| 159 | *pos = get_pid(pid); | ||
| 160 | put_pid(old); | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 152 | #ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION | 164 | #ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION |
| 153 | /* On IA-64, we always use the "64-bit version" of the IPC structures. */ | 165 | /* On IA-64, we always use the "64-bit version" of the IPC structures. */ |
| 154 | # define ipc_parse_version(cmd) IPC_64 | 166 | # define ipc_parse_version(cmd) IPC_64 |
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 93b57f026688..2a2ac53d8b8b 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c | |||
| @@ -23,55 +23,39 @@ | |||
| 23 | #include <linux/sched/signal.h> | 23 | #include <linux/sched/signal.h> |
| 24 | #include <linux/idr.h> | 24 | #include <linux/idr.h> |
| 25 | 25 | ||
| 26 | struct pid_cache { | ||
| 27 | int nr_ids; | ||
| 28 | char name[16]; | ||
| 29 | struct kmem_cache *cachep; | ||
| 30 | struct list_head list; | ||
| 31 | }; | ||
| 32 | |||
| 33 | static LIST_HEAD(pid_caches_lh); | ||
| 34 | static DEFINE_MUTEX(pid_caches_mutex); | 26 | static DEFINE_MUTEX(pid_caches_mutex); |
| 35 | static struct kmem_cache *pid_ns_cachep; | 27 | static struct kmem_cache *pid_ns_cachep; |
| 28 | /* MAX_PID_NS_LEVEL is needed for limiting size of 'struct pid' */ | ||
| 29 | #define MAX_PID_NS_LEVEL 32 | ||
| 30 | /* Write once array, filled from the beginning. */ | ||
| 31 | static struct kmem_cache *pid_cache[MAX_PID_NS_LEVEL]; | ||
| 36 | 32 | ||
| 37 | /* | 33 | /* |
| 38 | * creates the kmem cache to allocate pids from. | 34 | * creates the kmem cache to allocate pids from. |
| 39 | * @nr_ids: the number of numerical ids this pid will have to carry | 35 | * @level: pid namespace level |
| 40 | */ | 36 | */ |
| 41 | 37 | ||
| 42 | static struct kmem_cache *create_pid_cachep(int nr_ids) | 38 | static struct kmem_cache *create_pid_cachep(unsigned int level) |
| 43 | { | 39 | { |
| 44 | struct pid_cache *pcache; | 40 | /* Level 0 is init_pid_ns.pid_cachep */ |
| 45 | struct kmem_cache *cachep; | 41 | struct kmem_cache **pkc = &pid_cache[level - 1]; |
| 46 | 42 | struct kmem_cache *kc; | |
| 43 | char name[4 + 10 + 1]; | ||
| 44 | unsigned int len; | ||
| 45 | |||
| 46 | kc = READ_ONCE(*pkc); | ||
| 47 | if (kc) | ||
| 48 | return kc; | ||
| 49 | |||
| 50 | snprintf(name, sizeof(name), "pid_%u", level + 1); | ||
| 51 | len = sizeof(struct pid) + level * sizeof(struct upid); | ||
| 47 | mutex_lock(&pid_caches_mutex); | 52 | mutex_lock(&pid_caches_mutex); |
| 48 | list_for_each_entry(pcache, &pid_caches_lh, list) | 53 | /* Name collision forces to do allocation under mutex. */ |
| 49 | if (pcache->nr_ids == nr_ids) | 54 | if (!*pkc) |
| 50 | goto out; | 55 | *pkc = kmem_cache_create(name, len, 0, SLAB_HWCACHE_ALIGN, 0); |
| 51 | |||
| 52 | pcache = kmalloc(sizeof(struct pid_cache), GFP_KERNEL); | ||
| 53 | if (pcache == NULL) | ||
| 54 | goto err_alloc; | ||
| 55 | |||
| 56 | snprintf(pcache->name, sizeof(pcache->name), "pid_%d", nr_ids); | ||
| 57 | cachep = kmem_cache_create(pcache->name, | ||
| 58 | sizeof(struct pid) + (nr_ids - 1) * sizeof(struct upid), | ||
| 59 | 0, SLAB_HWCACHE_ALIGN, NULL); | ||
| 60 | if (cachep == NULL) | ||
| 61 | goto err_cachep; | ||
| 62 | |||
| 63 | pcache->nr_ids = nr_ids; | ||
| 64 | pcache->cachep = cachep; | ||
| 65 | list_add(&pcache->list, &pid_caches_lh); | ||
| 66 | out: | ||
| 67 | mutex_unlock(&pid_caches_mutex); | 56 | mutex_unlock(&pid_caches_mutex); |
| 68 | return pcache->cachep; | 57 | /* current can fail, but someone else can succeed. */ |
| 69 | 58 | return READ_ONCE(*pkc); | |
| 70 | err_cachep: | ||
| 71 | kfree(pcache); | ||
| 72 | err_alloc: | ||
| 73 | mutex_unlock(&pid_caches_mutex); | ||
| 74 | return NULL; | ||
| 75 | } | 59 | } |
| 76 | 60 | ||
| 77 | static void proc_cleanup_work(struct work_struct *work) | 61 | static void proc_cleanup_work(struct work_struct *work) |
| @@ -80,9 +64,6 @@ static void proc_cleanup_work(struct work_struct *work) | |||
| 80 | pid_ns_release_proc(ns); | 64 | pid_ns_release_proc(ns); |
| 81 | } | 65 | } |
| 82 | 66 | ||
| 83 | /* MAX_PID_NS_LEVEL is needed for limiting size of 'struct pid' */ | ||
| 84 | #define MAX_PID_NS_LEVEL 32 | ||
| 85 | |||
| 86 | static struct ucounts *inc_pid_namespaces(struct user_namespace *ns) | 67 | static struct ucounts *inc_pid_namespaces(struct user_namespace *ns) |
| 87 | { | 68 | { |
| 88 | return inc_ucount(ns, current_euid(), UCOUNT_PID_NAMESPACES); | 69 | return inc_ucount(ns, current_euid(), UCOUNT_PID_NAMESPACES); |
| @@ -119,7 +100,7 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns | |||
| 119 | 100 | ||
| 120 | idr_init(&ns->idr); | 101 | idr_init(&ns->idr); |
| 121 | 102 | ||
| 122 | ns->pid_cachep = create_pid_cachep(level + 1); | 103 | ns->pid_cachep = create_pid_cachep(level); |
| 123 | if (ns->pid_cachep == NULL) | 104 | if (ns->pid_cachep == NULL) |
| 124 | goto out_free_idr; | 105 | goto out_free_idr; |
| 125 | 106 | ||
diff --git a/security/security.c b/security/security.c index 1cd8526cb0b7..02d734e69955 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -1163,84 +1163,84 @@ void security_msg_msg_free(struct msg_msg *msg) | |||
| 1163 | call_void_hook(msg_msg_free_security, msg); | 1163 | call_void_hook(msg_msg_free_security, msg); |
| 1164 | } | 1164 | } |
| 1165 | 1165 | ||
| 1166 | int security_msg_queue_alloc(struct msg_queue *msq) | 1166 | int security_msg_queue_alloc(struct kern_ipc_perm *msq) |
| 1167 | { | 1167 | { |
| 1168 | return call_int_hook(msg_queue_alloc_security, 0, msq); | 1168 | return call_int_hook(msg_queue_alloc_security, 0, msq); |
| 1169 | } | 1169 | } |
| 1170 | 1170 | ||
| 1171 | void security_msg_queue_free(struct msg_queue *msq) | 1171 | void security_msg_queue_free(struct kern_ipc_perm *msq) |
| 1172 | { | 1172 | { |
| 1173 | call_void_hook(msg_queue_free_security, msq); | 1173 | call_void_hook(msg_queue_free_security, msq); |
| 1174 | } | 1174 | } |
| 1175 | 1175 | ||
| 1176 | int security_msg_queue_associate(struct msg_queue *msq, int msqflg) | 1176 | int security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) |
| 1177 | { | 1177 | { |
| 1178 | return call_int_hook(msg_queue_associate, 0, msq, msqflg); | 1178 | return call_int_hook(msg_queue_associate, 0, msq, msqflg); |
| 1179 | } | 1179 | } |
| 1180 | 1180 | ||
| 1181 | int security_msg_queue_msgctl(struct msg_queue *msq, int cmd) | 1181 | int security_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd) |
| 1182 | { | 1182 | { |
| 1183 | return call_int_hook(msg_queue_msgctl, 0, msq, cmd); | 1183 | return call_int_hook(msg_queue_msgctl, 0, msq, cmd); |
| 1184 | } | 1184 | } |
| 1185 | 1185 | ||
| 1186 | int security_msg_queue_msgsnd(struct msg_queue *msq, | 1186 | int security_msg_queue_msgsnd(struct kern_ipc_perm *msq, |
| 1187 | struct msg_msg *msg, int msqflg) | 1187 | struct msg_msg *msg, int msqflg) |
| 1188 | { | 1188 | { |
| 1189 | return call_int_hook(msg_queue_msgsnd, 0, msq, msg, msqflg); | 1189 | return call_int_hook(msg_queue_msgsnd, 0, msq, msg, msqflg); |
| 1190 | } | 1190 | } |
| 1191 | 1191 | ||
| 1192 | int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | 1192 | int security_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg, |
| 1193 | struct task_struct *target, long type, int mode) | 1193 | struct task_struct *target, long type, int mode) |
| 1194 | { | 1194 | { |
| 1195 | return call_int_hook(msg_queue_msgrcv, 0, msq, msg, target, type, mode); | 1195 | return call_int_hook(msg_queue_msgrcv, 0, msq, msg, target, type, mode); |
| 1196 | } | 1196 | } |
| 1197 | 1197 | ||
| 1198 | int security_shm_alloc(struct shmid_kernel *shp) | 1198 | int security_shm_alloc(struct kern_ipc_perm *shp) |
| 1199 | { | 1199 | { |
| 1200 | return call_int_hook(shm_alloc_security, 0, shp); | 1200 | return call_int_hook(shm_alloc_security, 0, shp); |
| 1201 | } | 1201 | } |
| 1202 | 1202 | ||
| 1203 | void security_shm_free(struct shmid_kernel *shp) | 1203 | void security_shm_free(struct kern_ipc_perm *shp) |
| 1204 | { | 1204 | { |
| 1205 | call_void_hook(shm_free_security, shp); | 1205 | call_void_hook(shm_free_security, shp); |
| 1206 | } | 1206 | } |
| 1207 | 1207 | ||
| 1208 | int security_shm_associate(struct shmid_kernel *shp, int shmflg) | 1208 | int security_shm_associate(struct kern_ipc_perm *shp, int shmflg) |
| 1209 | { | 1209 | { |
| 1210 | return call_int_hook(shm_associate, 0, shp, shmflg); | 1210 | return call_int_hook(shm_associate, 0, shp, shmflg); |
| 1211 | } | 1211 | } |
| 1212 | 1212 | ||
| 1213 | int security_shm_shmctl(struct shmid_kernel *shp, int cmd) | 1213 | int security_shm_shmctl(struct kern_ipc_perm *shp, int cmd) |
| 1214 | { | 1214 | { |
| 1215 | return call_int_hook(shm_shmctl, 0, shp, cmd); | 1215 | return call_int_hook(shm_shmctl, 0, shp, cmd); |
| 1216 | } | 1216 | } |
| 1217 | 1217 | ||
| 1218 | int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg) | 1218 | int security_shm_shmat(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg) |
| 1219 | { | 1219 | { |
| 1220 | return call_int_hook(shm_shmat, 0, shp, shmaddr, shmflg); | 1220 | return call_int_hook(shm_shmat, 0, shp, shmaddr, shmflg); |
| 1221 | } | 1221 | } |
| 1222 | 1222 | ||
| 1223 | int security_sem_alloc(struct sem_array *sma) | 1223 | int security_sem_alloc(struct kern_ipc_perm *sma) |
| 1224 | { | 1224 | { |
| 1225 | return call_int_hook(sem_alloc_security, 0, sma); | 1225 | return call_int_hook(sem_alloc_security, 0, sma); |
| 1226 | } | 1226 | } |
| 1227 | 1227 | ||
| 1228 | void security_sem_free(struct sem_array *sma) | 1228 | void security_sem_free(struct kern_ipc_perm *sma) |
| 1229 | { | 1229 | { |
| 1230 | call_void_hook(sem_free_security, sma); | 1230 | call_void_hook(sem_free_security, sma); |
| 1231 | } | 1231 | } |
| 1232 | 1232 | ||
| 1233 | int security_sem_associate(struct sem_array *sma, int semflg) | 1233 | int security_sem_associate(struct kern_ipc_perm *sma, int semflg) |
| 1234 | { | 1234 | { |
| 1235 | return call_int_hook(sem_associate, 0, sma, semflg); | 1235 | return call_int_hook(sem_associate, 0, sma, semflg); |
| 1236 | } | 1236 | } |
| 1237 | 1237 | ||
| 1238 | int security_sem_semctl(struct sem_array *sma, int cmd) | 1238 | int security_sem_semctl(struct kern_ipc_perm *sma, int cmd) |
| 1239 | { | 1239 | { |
| 1240 | return call_int_hook(sem_semctl, 0, sma, cmd); | 1240 | return call_int_hook(sem_semctl, 0, sma, cmd); |
| 1241 | } | 1241 | } |
| 1242 | 1242 | ||
| 1243 | int security_sem_semop(struct sem_array *sma, struct sembuf *sops, | 1243 | int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops, |
| 1244 | unsigned nsops, int alter) | 1244 | unsigned nsops, int alter) |
| 1245 | { | 1245 | { |
| 1246 | return call_int_hook(sem_semop, 0, sma, sops, nsops, alter); | 1246 | return call_int_hook(sem_semop, 0, sma, sops, nsops, alter); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 8644d864e3c1..925e546b5a87 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -5532,52 +5532,52 @@ static void selinux_msg_msg_free_security(struct msg_msg *msg) | |||
| 5532 | } | 5532 | } |
| 5533 | 5533 | ||
| 5534 | /* message queue security operations */ | 5534 | /* message queue security operations */ |
| 5535 | static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | 5535 | static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) |
| 5536 | { | 5536 | { |
| 5537 | struct ipc_security_struct *isec; | 5537 | struct ipc_security_struct *isec; |
| 5538 | struct common_audit_data ad; | 5538 | struct common_audit_data ad; |
| 5539 | u32 sid = current_sid(); | 5539 | u32 sid = current_sid(); |
| 5540 | int rc; | 5540 | int rc; |
| 5541 | 5541 | ||
| 5542 | rc = ipc_alloc_security(&msq->q_perm, SECCLASS_MSGQ); | 5542 | rc = ipc_alloc_security(msq, SECCLASS_MSGQ); |
| 5543 | if (rc) | 5543 | if (rc) |
| 5544 | return rc; | 5544 | return rc; |
| 5545 | 5545 | ||
| 5546 | isec = msq->q_perm.security; | 5546 | isec = msq->security; |
| 5547 | 5547 | ||
| 5548 | ad.type = LSM_AUDIT_DATA_IPC; | 5548 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5549 | ad.u.ipc_id = msq->q_perm.key; | 5549 | ad.u.ipc_id = msq->key; |
| 5550 | 5550 | ||
| 5551 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, | 5551 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
| 5552 | MSGQ__CREATE, &ad); | 5552 | MSGQ__CREATE, &ad); |
| 5553 | if (rc) { | 5553 | if (rc) { |
| 5554 | ipc_free_security(&msq->q_perm); | 5554 | ipc_free_security(msq); |
| 5555 | return rc; | 5555 | return rc; |
| 5556 | } | 5556 | } |
| 5557 | return 0; | 5557 | return 0; |
| 5558 | } | 5558 | } |
| 5559 | 5559 | ||
| 5560 | static void selinux_msg_queue_free_security(struct msg_queue *msq) | 5560 | static void selinux_msg_queue_free_security(struct kern_ipc_perm *msq) |
| 5561 | { | 5561 | { |
| 5562 | ipc_free_security(&msq->q_perm); | 5562 | ipc_free_security(msq); |
| 5563 | } | 5563 | } |
| 5564 | 5564 | ||
| 5565 | static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) | 5565 | static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) |
| 5566 | { | 5566 | { |
| 5567 | struct ipc_security_struct *isec; | 5567 | struct ipc_security_struct *isec; |
| 5568 | struct common_audit_data ad; | 5568 | struct common_audit_data ad; |
| 5569 | u32 sid = current_sid(); | 5569 | u32 sid = current_sid(); |
| 5570 | 5570 | ||
| 5571 | isec = msq->q_perm.security; | 5571 | isec = msq->security; |
| 5572 | 5572 | ||
| 5573 | ad.type = LSM_AUDIT_DATA_IPC; | 5573 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5574 | ad.u.ipc_id = msq->q_perm.key; | 5574 | ad.u.ipc_id = msq->key; |
| 5575 | 5575 | ||
| 5576 | return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, | 5576 | return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
| 5577 | MSGQ__ASSOCIATE, &ad); | 5577 | MSGQ__ASSOCIATE, &ad); |
| 5578 | } | 5578 | } |
| 5579 | 5579 | ||
| 5580 | static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd) | 5580 | static int selinux_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd) |
| 5581 | { | 5581 | { |
| 5582 | int err; | 5582 | int err; |
| 5583 | int perms; | 5583 | int perms; |
| @@ -5602,11 +5602,11 @@ static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd) | |||
| 5602 | return 0; | 5602 | return 0; |
| 5603 | } | 5603 | } |
| 5604 | 5604 | ||
| 5605 | err = ipc_has_perm(&msq->q_perm, perms); | 5605 | err = ipc_has_perm(msq, perms); |
| 5606 | return err; | 5606 | return err; |
| 5607 | } | 5607 | } |
| 5608 | 5608 | ||
| 5609 | static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, int msqflg) | 5609 | static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg) |
| 5610 | { | 5610 | { |
| 5611 | struct ipc_security_struct *isec; | 5611 | struct ipc_security_struct *isec; |
| 5612 | struct msg_security_struct *msec; | 5612 | struct msg_security_struct *msec; |
| @@ -5614,7 +5614,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
| 5614 | u32 sid = current_sid(); | 5614 | u32 sid = current_sid(); |
| 5615 | int rc; | 5615 | int rc; |
| 5616 | 5616 | ||
| 5617 | isec = msq->q_perm.security; | 5617 | isec = msq->security; |
| 5618 | msec = msg->security; | 5618 | msec = msg->security; |
| 5619 | 5619 | ||
| 5620 | /* | 5620 | /* |
| @@ -5632,7 +5632,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
| 5632 | } | 5632 | } |
| 5633 | 5633 | ||
| 5634 | ad.type = LSM_AUDIT_DATA_IPC; | 5634 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5635 | ad.u.ipc_id = msq->q_perm.key; | 5635 | ad.u.ipc_id = msq->key; |
| 5636 | 5636 | ||
| 5637 | /* Can this process write to the queue? */ | 5637 | /* Can this process write to the queue? */ |
| 5638 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, | 5638 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
| @@ -5649,7 +5649,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
| 5649 | return rc; | 5649 | return rc; |
| 5650 | } | 5650 | } |
| 5651 | 5651 | ||
| 5652 | static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | 5652 | static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg, |
| 5653 | struct task_struct *target, | 5653 | struct task_struct *target, |
| 5654 | long type, int mode) | 5654 | long type, int mode) |
| 5655 | { | 5655 | { |
| @@ -5659,11 +5659,11 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
| 5659 | u32 sid = task_sid(target); | 5659 | u32 sid = task_sid(target); |
| 5660 | int rc; | 5660 | int rc; |
| 5661 | 5661 | ||
| 5662 | isec = msq->q_perm.security; | 5662 | isec = msq->security; |
| 5663 | msec = msg->security; | 5663 | msec = msg->security; |
| 5664 | 5664 | ||
| 5665 | ad.type = LSM_AUDIT_DATA_IPC; | 5665 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5666 | ad.u.ipc_id = msq->q_perm.key; | 5666 | ad.u.ipc_id = msq->key; |
| 5667 | 5667 | ||
| 5668 | rc = avc_has_perm(sid, isec->sid, | 5668 | rc = avc_has_perm(sid, isec->sid, |
| 5669 | SECCLASS_MSGQ, MSGQ__READ, &ad); | 5669 | SECCLASS_MSGQ, MSGQ__READ, &ad); |
| @@ -5674,53 +5674,53 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
| 5674 | } | 5674 | } |
| 5675 | 5675 | ||
| 5676 | /* Shared Memory security operations */ | 5676 | /* Shared Memory security operations */ |
| 5677 | static int selinux_shm_alloc_security(struct shmid_kernel *shp) | 5677 | static int selinux_shm_alloc_security(struct kern_ipc_perm *shp) |
| 5678 | { | 5678 | { |
| 5679 | struct ipc_security_struct *isec; | 5679 | struct ipc_security_struct *isec; |
| 5680 | struct common_audit_data ad; | 5680 | struct common_audit_data ad; |
| 5681 | u32 sid = current_sid(); | 5681 | u32 sid = current_sid(); |
| 5682 | int rc; | 5682 | int rc; |
| 5683 | 5683 | ||
| 5684 | rc = ipc_alloc_security(&shp->shm_perm, SECCLASS_SHM); | 5684 | rc = ipc_alloc_security(shp, SECCLASS_SHM); |
| 5685 | if (rc) | 5685 | if (rc) |
| 5686 | return rc; | 5686 | return rc; |
| 5687 | 5687 | ||
| 5688 | isec = shp->shm_perm.security; | 5688 | isec = shp->security; |
| 5689 | 5689 | ||
| 5690 | ad.type = LSM_AUDIT_DATA_IPC; | 5690 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5691 | ad.u.ipc_id = shp->shm_perm.key; | 5691 | ad.u.ipc_id = shp->key; |
| 5692 | 5692 | ||
| 5693 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, | 5693 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
| 5694 | SHM__CREATE, &ad); | 5694 | SHM__CREATE, &ad); |
| 5695 | if (rc) { | 5695 | if (rc) { |
| 5696 | ipc_free_security(&shp->shm_perm); | 5696 | ipc_free_security(shp); |
| 5697 | return rc; | 5697 | return rc; |
| 5698 | } | 5698 | } |
| 5699 | return 0; | 5699 | return 0; |
| 5700 | } | 5700 | } |
| 5701 | 5701 | ||
| 5702 | static void selinux_shm_free_security(struct shmid_kernel *shp) | 5702 | static void selinux_shm_free_security(struct kern_ipc_perm *shp) |
| 5703 | { | 5703 | { |
| 5704 | ipc_free_security(&shp->shm_perm); | 5704 | ipc_free_security(shp); |
| 5705 | } | 5705 | } |
| 5706 | 5706 | ||
| 5707 | static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) | 5707 | static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) |
| 5708 | { | 5708 | { |
| 5709 | struct ipc_security_struct *isec; | 5709 | struct ipc_security_struct *isec; |
| 5710 | struct common_audit_data ad; | 5710 | struct common_audit_data ad; |
| 5711 | u32 sid = current_sid(); | 5711 | u32 sid = current_sid(); |
| 5712 | 5712 | ||
| 5713 | isec = shp->shm_perm.security; | 5713 | isec = shp->security; |
| 5714 | 5714 | ||
| 5715 | ad.type = LSM_AUDIT_DATA_IPC; | 5715 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5716 | ad.u.ipc_id = shp->shm_perm.key; | 5716 | ad.u.ipc_id = shp->key; |
| 5717 | 5717 | ||
| 5718 | return avc_has_perm(sid, isec->sid, SECCLASS_SHM, | 5718 | return avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
| 5719 | SHM__ASSOCIATE, &ad); | 5719 | SHM__ASSOCIATE, &ad); |
| 5720 | } | 5720 | } |
| 5721 | 5721 | ||
| 5722 | /* Note, at this point, shp is locked down */ | 5722 | /* Note, at this point, shp is locked down */ |
| 5723 | static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd) | 5723 | static int selinux_shm_shmctl(struct kern_ipc_perm *shp, int cmd) |
| 5724 | { | 5724 | { |
| 5725 | int perms; | 5725 | int perms; |
| 5726 | int err; | 5726 | int err; |
| @@ -5749,11 +5749,11 @@ static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd) | |||
| 5749 | return 0; | 5749 | return 0; |
| 5750 | } | 5750 | } |
| 5751 | 5751 | ||
| 5752 | err = ipc_has_perm(&shp->shm_perm, perms); | 5752 | err = ipc_has_perm(shp, perms); |
| 5753 | return err; | 5753 | return err; |
| 5754 | } | 5754 | } |
| 5755 | 5755 | ||
| 5756 | static int selinux_shm_shmat(struct shmid_kernel *shp, | 5756 | static int selinux_shm_shmat(struct kern_ipc_perm *shp, |
| 5757 | char __user *shmaddr, int shmflg) | 5757 | char __user *shmaddr, int shmflg) |
| 5758 | { | 5758 | { |
| 5759 | u32 perms; | 5759 | u32 perms; |
| @@ -5763,57 +5763,57 @@ static int selinux_shm_shmat(struct shmid_kernel *shp, | |||
| 5763 | else | 5763 | else |
| 5764 | perms = SHM__READ | SHM__WRITE; | 5764 | perms = SHM__READ | SHM__WRITE; |
| 5765 | 5765 | ||
| 5766 | return ipc_has_perm(&shp->shm_perm, perms); | 5766 | return ipc_has_perm(shp, perms); |
| 5767 | } | 5767 | } |
| 5768 | 5768 | ||
| 5769 | /* Semaphore security operations */ | 5769 | /* Semaphore security operations */ |
| 5770 | static int selinux_sem_alloc_security(struct sem_array *sma) | 5770 | static int selinux_sem_alloc_security(struct kern_ipc_perm *sma) |
| 5771 | { | 5771 | { |
| 5772 | struct ipc_security_struct *isec; | 5772 | struct ipc_security_struct *isec; |
| 5773 | struct common_audit_data ad; | 5773 | struct common_audit_data ad; |
| 5774 | u32 sid = current_sid(); | 5774 | u32 sid = current_sid(); |
| 5775 | int rc; | 5775 | int rc; |
| 5776 | 5776 | ||
| 5777 | rc = ipc_alloc_security(&sma->sem_perm, SECCLASS_SEM); | 5777 | rc = ipc_alloc_security(sma, SECCLASS_SEM); |
| 5778 | if (rc) | 5778 | if (rc) |
| 5779 | return rc; | 5779 | return rc; |
| 5780 | 5780 | ||
| 5781 | isec = sma->sem_perm.security; | 5781 | isec = sma->security; |
| 5782 | 5782 | ||
| 5783 | ad.type = LSM_AUDIT_DATA_IPC; | 5783 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5784 | ad.u.ipc_id = sma->sem_perm.key; | 5784 | ad.u.ipc_id = sma->key; |
| 5785 | 5785 | ||
| 5786 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, | 5786 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
| 5787 | SEM__CREATE, &ad); | 5787 | SEM__CREATE, &ad); |
| 5788 | if (rc) { | 5788 | if (rc) { |
| 5789 | ipc_free_security(&sma->sem_perm); | 5789 | ipc_free_security(sma); |
| 5790 | return rc; | 5790 | return rc; |
| 5791 | } | 5791 | } |
| 5792 | return 0; | 5792 | return 0; |
| 5793 | } | 5793 | } |
| 5794 | 5794 | ||
| 5795 | static void selinux_sem_free_security(struct sem_array *sma) | 5795 | static void selinux_sem_free_security(struct kern_ipc_perm *sma) |
| 5796 | { | 5796 | { |
| 5797 | ipc_free_security(&sma->sem_perm); | 5797 | ipc_free_security(sma); |
| 5798 | } | 5798 | } |
| 5799 | 5799 | ||
| 5800 | static int selinux_sem_associate(struct sem_array *sma, int semflg) | 5800 | static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) |
| 5801 | { | 5801 | { |
| 5802 | struct ipc_security_struct *isec; | 5802 | struct ipc_security_struct *isec; |
| 5803 | struct common_audit_data ad; | 5803 | struct common_audit_data ad; |
| 5804 | u32 sid = current_sid(); | 5804 | u32 sid = current_sid(); |
| 5805 | 5805 | ||
| 5806 | isec = sma->sem_perm.security; | 5806 | isec = sma->security; |
| 5807 | 5807 | ||
| 5808 | ad.type = LSM_AUDIT_DATA_IPC; | 5808 | ad.type = LSM_AUDIT_DATA_IPC; |
| 5809 | ad.u.ipc_id = sma->sem_perm.key; | 5809 | ad.u.ipc_id = sma->key; |
| 5810 | 5810 | ||
| 5811 | return avc_has_perm(sid, isec->sid, SECCLASS_SEM, | 5811 | return avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
| 5812 | SEM__ASSOCIATE, &ad); | 5812 | SEM__ASSOCIATE, &ad); |
| 5813 | } | 5813 | } |
| 5814 | 5814 | ||
| 5815 | /* Note, at this point, sma is locked down */ | 5815 | /* Note, at this point, sma is locked down */ |
| 5816 | static int selinux_sem_semctl(struct sem_array *sma, int cmd) | 5816 | static int selinux_sem_semctl(struct kern_ipc_perm *sma, int cmd) |
| 5817 | { | 5817 | { |
| 5818 | int err; | 5818 | int err; |
| 5819 | u32 perms; | 5819 | u32 perms; |
| @@ -5851,11 +5851,11 @@ static int selinux_sem_semctl(struct sem_array *sma, int cmd) | |||
| 5851 | return 0; | 5851 | return 0; |
| 5852 | } | 5852 | } |
| 5853 | 5853 | ||
| 5854 | err = ipc_has_perm(&sma->sem_perm, perms); | 5854 | err = ipc_has_perm(sma, perms); |
| 5855 | return err; | 5855 | return err; |
| 5856 | } | 5856 | } |
| 5857 | 5857 | ||
| 5858 | static int selinux_sem_semop(struct sem_array *sma, | 5858 | static int selinux_sem_semop(struct kern_ipc_perm *sma, |
| 5859 | struct sembuf *sops, unsigned nsops, int alter) | 5859 | struct sembuf *sops, unsigned nsops, int alter) |
| 5860 | { | 5860 | { |
| 5861 | u32 perms; | 5861 | u32 perms; |
| @@ -5865,7 +5865,7 @@ static int selinux_sem_semop(struct sem_array *sma, | |||
| 5865 | else | 5865 | else |
| 5866 | perms = SEM__READ; | 5866 | perms = SEM__READ; |
| 5867 | 5867 | ||
| 5868 | return ipc_has_perm(&sma->sem_perm, perms); | 5868 | return ipc_has_perm(sma, perms); |
| 5869 | } | 5869 | } |
| 5870 | 5870 | ||
| 5871 | static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | 5871 | static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 03fdecba93bb..0735b8db158b 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -2945,25 +2945,24 @@ static void smack_msg_msg_free_security(struct msg_msg *msg) | |||
| 2945 | } | 2945 | } |
| 2946 | 2946 | ||
| 2947 | /** | 2947 | /** |
| 2948 | * smack_of_shm - the smack pointer for the shm | 2948 | * smack_of_ipc - the smack pointer for the ipc |
| 2949 | * @shp: the object | 2949 | * @isp: the object |
| 2950 | * | 2950 | * |
| 2951 | * Returns a pointer to the smack value | 2951 | * Returns a pointer to the smack value |
| 2952 | */ | 2952 | */ |
| 2953 | static struct smack_known *smack_of_shm(struct shmid_kernel *shp) | 2953 | static struct smack_known *smack_of_ipc(struct kern_ipc_perm *isp) |
| 2954 | { | 2954 | { |
| 2955 | return (struct smack_known *)shp->shm_perm.security; | 2955 | return (struct smack_known *)isp->security; |
| 2956 | } | 2956 | } |
| 2957 | 2957 | ||
| 2958 | /** | 2958 | /** |
| 2959 | * smack_shm_alloc_security - Set the security blob for shm | 2959 | * smack_ipc_alloc_security - Set the security blob for ipc |
| 2960 | * @shp: the object | 2960 | * @isp: the object |
| 2961 | * | 2961 | * |
| 2962 | * Returns 0 | 2962 | * Returns 0 |
| 2963 | */ | 2963 | */ |
| 2964 | static int smack_shm_alloc_security(struct shmid_kernel *shp) | 2964 | static int smack_ipc_alloc_security(struct kern_ipc_perm *isp) |
| 2965 | { | 2965 | { |
| 2966 | struct kern_ipc_perm *isp = &shp->shm_perm; | ||
| 2967 | struct smack_known *skp = smk_of_current(); | 2966 | struct smack_known *skp = smk_of_current(); |
| 2968 | 2967 | ||
| 2969 | isp->security = skp; | 2968 | isp->security = skp; |
| @@ -2971,34 +2970,32 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp) | |||
| 2971 | } | 2970 | } |
| 2972 | 2971 | ||
| 2973 | /** | 2972 | /** |
| 2974 | * smack_shm_free_security - Clear the security blob for shm | 2973 | * smack_ipc_free_security - Clear the security blob for ipc |
| 2975 | * @shp: the object | 2974 | * @isp: the object |
| 2976 | * | 2975 | * |
| 2977 | * Clears the blob pointer | 2976 | * Clears the blob pointer |
| 2978 | */ | 2977 | */ |
| 2979 | static void smack_shm_free_security(struct shmid_kernel *shp) | 2978 | static void smack_ipc_free_security(struct kern_ipc_perm *isp) |
| 2980 | { | 2979 | { |
| 2981 | struct kern_ipc_perm *isp = &shp->shm_perm; | ||
| 2982 | |||
| 2983 | isp->security = NULL; | 2980 | isp->security = NULL; |
| 2984 | } | 2981 | } |
| 2985 | 2982 | ||
| 2986 | /** | 2983 | /** |
| 2987 | * smk_curacc_shm : check if current has access on shm | 2984 | * smk_curacc_shm : check if current has access on shm |
| 2988 | * @shp : the object | 2985 | * @isp : the object |
| 2989 | * @access : access requested | 2986 | * @access : access requested |
| 2990 | * | 2987 | * |
| 2991 | * Returns 0 if current has the requested access, error code otherwise | 2988 | * Returns 0 if current has the requested access, error code otherwise |
| 2992 | */ | 2989 | */ |
| 2993 | static int smk_curacc_shm(struct shmid_kernel *shp, int access) | 2990 | static int smk_curacc_shm(struct kern_ipc_perm *isp, int access) |
| 2994 | { | 2991 | { |
| 2995 | struct smack_known *ssp = smack_of_shm(shp); | 2992 | struct smack_known *ssp = smack_of_ipc(isp); |
| 2996 | struct smk_audit_info ad; | 2993 | struct smk_audit_info ad; |
| 2997 | int rc; | 2994 | int rc; |
| 2998 | 2995 | ||
| 2999 | #ifdef CONFIG_AUDIT | 2996 | #ifdef CONFIG_AUDIT |
| 3000 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); | 2997 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); |
| 3001 | ad.a.u.ipc_id = shp->shm_perm.id; | 2998 | ad.a.u.ipc_id = isp->id; |
| 3002 | #endif | 2999 | #endif |
| 3003 | rc = smk_curacc(ssp, access, &ad); | 3000 | rc = smk_curacc(ssp, access, &ad); |
| 3004 | rc = smk_bu_current("shm", ssp, access, rc); | 3001 | rc = smk_bu_current("shm", ssp, access, rc); |
| @@ -3007,27 +3004,27 @@ static int smk_curacc_shm(struct shmid_kernel *shp, int access) | |||
| 3007 | 3004 | ||
| 3008 | /** | 3005 | /** |
| 3009 | * smack_shm_associate - Smack access check for shm | 3006 | * smack_shm_associate - Smack access check for shm |
| 3010 | * @shp: the object | 3007 | * @isp: the object |
| 3011 | * @shmflg: access requested | 3008 | * @shmflg: access requested |
| 3012 | * | 3009 | * |
| 3013 | * Returns 0 if current has the requested access, error code otherwise | 3010 | * Returns 0 if current has the requested access, error code otherwise |
| 3014 | */ | 3011 | */ |
| 3015 | static int smack_shm_associate(struct shmid_kernel *shp, int shmflg) | 3012 | static int smack_shm_associate(struct kern_ipc_perm *isp, int shmflg) |
| 3016 | { | 3013 | { |
| 3017 | int may; | 3014 | int may; |
| 3018 | 3015 | ||
| 3019 | may = smack_flags_to_may(shmflg); | 3016 | may = smack_flags_to_may(shmflg); |
| 3020 | return smk_curacc_shm(shp, may); | 3017 | return smk_curacc_shm(isp, may); |
| 3021 | } | 3018 | } |
| 3022 | 3019 | ||
| 3023 | /** | 3020 | /** |
| 3024 | * smack_shm_shmctl - Smack access check for shm | 3021 | * smack_shm_shmctl - Smack access check for shm |
| 3025 | * @shp: the object | 3022 | * @isp: the object |
| 3026 | * @cmd: what it wants to do | 3023 | * @cmd: what it wants to do |
| 3027 | * | 3024 | * |
| 3028 | * Returns 0 if current has the requested access, error code otherwise | 3025 | * Returns 0 if current has the requested access, error code otherwise |
| 3029 | */ | 3026 | */ |
| 3030 | static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) | 3027 | static int smack_shm_shmctl(struct kern_ipc_perm *isp, int cmd) |
| 3031 | { | 3028 | { |
| 3032 | int may; | 3029 | int may; |
| 3033 | 3030 | ||
| @@ -3051,81 +3048,42 @@ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) | |||
| 3051 | default: | 3048 | default: |
| 3052 | return -EINVAL; | 3049 | return -EINVAL; |
| 3053 | } | 3050 | } |
| 3054 | return smk_curacc_shm(shp, may); | 3051 | return smk_curacc_shm(isp, may); |
| 3055 | } | 3052 | } |
| 3056 | 3053 | ||
| 3057 | /** | 3054 | /** |
| 3058 | * smack_shm_shmat - Smack access for shmat | 3055 | * smack_shm_shmat - Smack access for shmat |
| 3059 | * @shp: the object | 3056 | * @isp: the object |
| 3060 | * @shmaddr: unused | 3057 | * @shmaddr: unused |
| 3061 | * @shmflg: access requested | 3058 | * @shmflg: access requested |
| 3062 | * | 3059 | * |
| 3063 | * Returns 0 if current has the requested access, error code otherwise | 3060 | * Returns 0 if current has the requested access, error code otherwise |
| 3064 | */ | 3061 | */ |
| 3065 | static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, | 3062 | static int smack_shm_shmat(struct kern_ipc_perm *ipc, char __user *shmaddr, |
| 3066 | int shmflg) | 3063 | int shmflg) |
| 3067 | { | 3064 | { |
| 3068 | int may; | 3065 | int may; |
| 3069 | 3066 | ||
| 3070 | may = smack_flags_to_may(shmflg); | 3067 | may = smack_flags_to_may(shmflg); |
| 3071 | return smk_curacc_shm(shp, may); | 3068 | return smk_curacc_shm(ipc, may); |
| 3072 | } | ||
| 3073 | |||
| 3074 | /** | ||
| 3075 | * smack_of_sem - the smack pointer for the sem | ||
| 3076 | * @sma: the object | ||
| 3077 | * | ||
| 3078 | * Returns a pointer to the smack value | ||
| 3079 | */ | ||
| 3080 | static struct smack_known *smack_of_sem(struct sem_array *sma) | ||
| 3081 | { | ||
| 3082 | return (struct smack_known *)sma->sem_perm.security; | ||
| 3083 | } | ||
| 3084 | |||
| 3085 | /** | ||
| 3086 | * smack_sem_alloc_security - Set the security blob for sem | ||
| 3087 | * @sma: the object | ||
| 3088 | * | ||
| 3089 | * Returns 0 | ||
| 3090 | */ | ||
| 3091 | static int smack_sem_alloc_security(struct sem_array *sma) | ||
| 3092 | { | ||
| 3093 | struct kern_ipc_perm *isp = &sma->sem_perm; | ||
| 3094 | struct smack_known *skp = smk_of_current(); | ||
| 3095 | |||
| 3096 | isp->security = skp; | ||
| 3097 | return 0; | ||
| 3098 | } | ||
| 3099 | |||
| 3100 | /** | ||
| 3101 | * smack_sem_free_security - Clear the security blob for sem | ||
| 3102 | * @sma: the object | ||
| 3103 | * | ||
| 3104 | * Clears the blob pointer | ||
| 3105 | */ | ||
| 3106 | static void smack_sem_free_security(struct sem_array *sma) | ||
| 3107 | { | ||
| 3108 | struct kern_ipc_perm *isp = &sma->sem_perm; | ||
| 3109 | |||
| 3110 | isp->security = NULL; | ||
| 3111 | } | 3069 | } |
| 3112 | 3070 | ||
| 3113 | /** | 3071 | /** |
| 3114 | * smk_curacc_sem : check if current has access on sem | 3072 | * smk_curacc_sem : check if current has access on sem |
| 3115 | * @sma : the object | 3073 | * @isp : the object |
| 3116 | * @access : access requested | 3074 | * @access : access requested |
| 3117 | * | 3075 | * |
| 3118 | * Returns 0 if current has the requested access, error code otherwise | 3076 | * Returns 0 if current has the requested access, error code otherwise |
| 3119 | */ | 3077 | */ |
| 3120 | static int smk_curacc_sem(struct sem_array *sma, int access) | 3078 | static int smk_curacc_sem(struct kern_ipc_perm *isp, int access) |
| 3121 | { | 3079 | { |
| 3122 | struct smack_known *ssp = smack_of_sem(sma); | 3080 | struct smack_known *ssp = smack_of_ipc(isp); |
| 3123 | struct smk_audit_info ad; | 3081 | struct smk_audit_info ad; |
| 3124 | int rc; | 3082 | int rc; |
| 3125 | 3083 | ||
| 3126 | #ifdef CONFIG_AUDIT | 3084 | #ifdef CONFIG_AUDIT |
| 3127 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); | 3085 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); |
| 3128 | ad.a.u.ipc_id = sma->sem_perm.id; | 3086 | ad.a.u.ipc_id = isp->id; |
| 3129 | #endif | 3087 | #endif |
| 3130 | rc = smk_curacc(ssp, access, &ad); | 3088 | rc = smk_curacc(ssp, access, &ad); |
| 3131 | rc = smk_bu_current("sem", ssp, access, rc); | 3089 | rc = smk_bu_current("sem", ssp, access, rc); |
| @@ -3134,27 +3092,27 @@ static int smk_curacc_sem(struct sem_array *sma, int access) | |||
| 3134 | 3092 | ||
| 3135 | /** | 3093 | /** |
| 3136 | * smack_sem_associate - Smack access check for sem | 3094 | * smack_sem_associate - Smack access check for sem |
| 3137 | * @sma: the object | 3095 | * @isp: the object |
| 3138 | * @semflg: access requested | 3096 | * @semflg: access requested |
| 3139 | * | 3097 | * |
| 3140 | * Returns 0 if current has the requested access, error code otherwise | 3098 | * Returns 0 if current has the requested access, error code otherwise |
| 3141 | */ | 3099 | */ |
| 3142 | static int smack_sem_associate(struct sem_array *sma, int semflg) | 3100 | static int smack_sem_associate(struct kern_ipc_perm *isp, int semflg) |
| 3143 | { | 3101 | { |
| 3144 | int may; | 3102 | int may; |
| 3145 | 3103 | ||
| 3146 | may = smack_flags_to_may(semflg); | 3104 | may = smack_flags_to_may(semflg); |
| 3147 | return smk_curacc_sem(sma, may); | 3105 | return smk_curacc_sem(isp, may); |
| 3148 | } | 3106 | } |
| 3149 | 3107 | ||
| 3150 | /** | 3108 | /** |
| 3151 | * smack_sem_shmctl - Smack access check for sem | 3109 | * smack_sem_shmctl - Smack access check for sem |
| 3152 | * @sma: the object | 3110 | * @isp: the object |
| 3153 | * @cmd: what it wants to do | 3111 | * @cmd: what it wants to do |
| 3154 | * | 3112 | * |
| 3155 | * Returns 0 if current has the requested access, error code otherwise | 3113 | * Returns 0 if current has the requested access, error code otherwise |
| 3156 | */ | 3114 | */ |
| 3157 | static int smack_sem_semctl(struct sem_array *sma, int cmd) | 3115 | static int smack_sem_semctl(struct kern_ipc_perm *isp, int cmd) |
| 3158 | { | 3116 | { |
| 3159 | int may; | 3117 | int may; |
| 3160 | 3118 | ||
| @@ -3184,12 +3142,12 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd) | |||
| 3184 | return -EINVAL; | 3142 | return -EINVAL; |
| 3185 | } | 3143 | } |
| 3186 | 3144 | ||
| 3187 | return smk_curacc_sem(sma, may); | 3145 | return smk_curacc_sem(isp, may); |
| 3188 | } | 3146 | } |
| 3189 | 3147 | ||
| 3190 | /** | 3148 | /** |
| 3191 | * smack_sem_semop - Smack checks of semaphore operations | 3149 | * smack_sem_semop - Smack checks of semaphore operations |
| 3192 | * @sma: the object | 3150 | * @isp: the object |
| 3193 | * @sops: unused | 3151 | * @sops: unused |
| 3194 | * @nsops: unused | 3152 | * @nsops: unused |
| 3195 | * @alter: unused | 3153 | * @alter: unused |
| @@ -3198,67 +3156,28 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd) | |||
| 3198 | * | 3156 | * |
| 3199 | * Returns 0 if access is allowed, error code otherwise | 3157 | * Returns 0 if access is allowed, error code otherwise |
| 3200 | */ | 3158 | */ |
| 3201 | static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops, | 3159 | static int smack_sem_semop(struct kern_ipc_perm *isp, struct sembuf *sops, |
| 3202 | unsigned nsops, int alter) | 3160 | unsigned nsops, int alter) |
| 3203 | { | 3161 | { |
| 3204 | return smk_curacc_sem(sma, MAY_READWRITE); | 3162 | return smk_curacc_sem(isp, MAY_READWRITE); |
| 3205 | } | ||
| 3206 | |||
| 3207 | /** | ||
| 3208 | * smack_msg_alloc_security - Set the security blob for msg | ||
| 3209 | * @msq: the object | ||
| 3210 | * | ||
| 3211 | * Returns 0 | ||
| 3212 | */ | ||
| 3213 | static int smack_msg_queue_alloc_security(struct msg_queue *msq) | ||
| 3214 | { | ||
| 3215 | struct kern_ipc_perm *kisp = &msq->q_perm; | ||
| 3216 | struct smack_known *skp = smk_of_current(); | ||
| 3217 | |||
| 3218 | kisp->security = skp; | ||
| 3219 | return 0; | ||
| 3220 | } | ||
| 3221 | |||
| 3222 | /** | ||
| 3223 | * smack_msg_free_security - Clear the security blob for msg | ||
| 3224 | * @msq: the object | ||
| 3225 | * | ||
| 3226 | * Clears the blob pointer | ||
| 3227 | */ | ||
| 3228 | static void smack_msg_queue_free_security(struct msg_queue *msq) | ||
| 3229 | { | ||
| 3230 | struct kern_ipc_perm *kisp = &msq->q_perm; | ||
| 3231 | |||
| 3232 | kisp->security = NULL; | ||
| 3233 | } | ||
| 3234 | |||
| 3235 | /** | ||
| 3236 | * smack_of_msq - the smack pointer for the msq | ||
| 3237 | * @msq: the object | ||
| 3238 | * | ||
| 3239 | * Returns a pointer to the smack label entry | ||
| 3240 | */ | ||
| 3241 | static struct smack_known *smack_of_msq(struct msg_queue *msq) | ||
| 3242 | { | ||
| 3243 | return (struct smack_known *)msq->q_perm.security; | ||
| 3244 | } | 3163 | } |
| 3245 | 3164 | ||
| 3246 | /** | 3165 | /** |
| 3247 | * smk_curacc_msq : helper to check if current has access on msq | 3166 | * smk_curacc_msq : helper to check if current has access on msq |
| 3248 | * @msq : the msq | 3167 | * @isp : the msq |
| 3249 | * @access : access requested | 3168 | * @access : access requested |
| 3250 | * | 3169 | * |
| 3251 | * return 0 if current has access, error otherwise | 3170 | * return 0 if current has access, error otherwise |
| 3252 | */ | 3171 | */ |
| 3253 | static int smk_curacc_msq(struct msg_queue *msq, int access) | 3172 | static int smk_curacc_msq(struct kern_ipc_perm *isp, int access) |
| 3254 | { | 3173 | { |
| 3255 | struct smack_known *msp = smack_of_msq(msq); | 3174 | struct smack_known *msp = smack_of_ipc(isp); |
| 3256 | struct smk_audit_info ad; | 3175 | struct smk_audit_info ad; |
| 3257 | int rc; | 3176 | int rc; |
| 3258 | 3177 | ||
| 3259 | #ifdef CONFIG_AUDIT | 3178 | #ifdef CONFIG_AUDIT |
| 3260 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); | 3179 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); |
| 3261 | ad.a.u.ipc_id = msq->q_perm.id; | 3180 | ad.a.u.ipc_id = isp->id; |
| 3262 | #endif | 3181 | #endif |
| 3263 | rc = smk_curacc(msp, access, &ad); | 3182 | rc = smk_curacc(msp, access, &ad); |
| 3264 | rc = smk_bu_current("msq", msp, access, rc); | 3183 | rc = smk_bu_current("msq", msp, access, rc); |
| @@ -3267,27 +3186,27 @@ static int smk_curacc_msq(struct msg_queue *msq, int access) | |||
| 3267 | 3186 | ||
| 3268 | /** | 3187 | /** |
| 3269 | * smack_msg_queue_associate - Smack access check for msg_queue | 3188 | * smack_msg_queue_associate - Smack access check for msg_queue |
| 3270 | * @msq: the object | 3189 | * @isp: the object |
| 3271 | * @msqflg: access requested | 3190 | * @msqflg: access requested |
| 3272 | * | 3191 | * |
| 3273 | * Returns 0 if current has the requested access, error code otherwise | 3192 | * Returns 0 if current has the requested access, error code otherwise |
| 3274 | */ | 3193 | */ |
| 3275 | static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg) | 3194 | static int smack_msg_queue_associate(struct kern_ipc_perm *isp, int msqflg) |
| 3276 | { | 3195 | { |
| 3277 | int may; | 3196 | int may; |
| 3278 | 3197 | ||
| 3279 | may = smack_flags_to_may(msqflg); | 3198 | may = smack_flags_to_may(msqflg); |
| 3280 | return smk_curacc_msq(msq, may); | 3199 | return smk_curacc_msq(isp, may); |
| 3281 | } | 3200 | } |
| 3282 | 3201 | ||
| 3283 | /** | 3202 | /** |
| 3284 | * smack_msg_queue_msgctl - Smack access check for msg_queue | 3203 | * smack_msg_queue_msgctl - Smack access check for msg_queue |
| 3285 | * @msq: the object | 3204 | * @isp: the object |
| 3286 | * @cmd: what it wants to do | 3205 | * @cmd: what it wants to do |
| 3287 | * | 3206 | * |
| 3288 | * Returns 0 if current has the requested access, error code otherwise | 3207 | * Returns 0 if current has the requested access, error code otherwise |
| 3289 | */ | 3208 | */ |
| 3290 | static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) | 3209 | static int smack_msg_queue_msgctl(struct kern_ipc_perm *isp, int cmd) |
| 3291 | { | 3210 | { |
| 3292 | int may; | 3211 | int may; |
| 3293 | 3212 | ||
| @@ -3310,29 +3229,29 @@ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) | |||
| 3310 | return -EINVAL; | 3229 | return -EINVAL; |
| 3311 | } | 3230 | } |
| 3312 | 3231 | ||
| 3313 | return smk_curacc_msq(msq, may); | 3232 | return smk_curacc_msq(isp, may); |
| 3314 | } | 3233 | } |
| 3315 | 3234 | ||
| 3316 | /** | 3235 | /** |
| 3317 | * smack_msg_queue_msgsnd - Smack access check for msg_queue | 3236 | * smack_msg_queue_msgsnd - Smack access check for msg_queue |
| 3318 | * @msq: the object | 3237 | * @isp: the object |
| 3319 | * @msg: unused | 3238 | * @msg: unused |
| 3320 | * @msqflg: access requested | 3239 | * @msqflg: access requested |
| 3321 | * | 3240 | * |
| 3322 | * Returns 0 if current has the requested access, error code otherwise | 3241 | * Returns 0 if current has the requested access, error code otherwise |
| 3323 | */ | 3242 | */ |
| 3324 | static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | 3243 | static int smack_msg_queue_msgsnd(struct kern_ipc_perm *isp, struct msg_msg *msg, |
| 3325 | int msqflg) | 3244 | int msqflg) |
| 3326 | { | 3245 | { |
| 3327 | int may; | 3246 | int may; |
| 3328 | 3247 | ||
| 3329 | may = smack_flags_to_may(msqflg); | 3248 | may = smack_flags_to_may(msqflg); |
| 3330 | return smk_curacc_msq(msq, may); | 3249 | return smk_curacc_msq(isp, may); |
| 3331 | } | 3250 | } |
| 3332 | 3251 | ||
| 3333 | /** | 3252 | /** |
| 3334 | * smack_msg_queue_msgsnd - Smack access check for msg_queue | 3253 | * smack_msg_queue_msgsnd - Smack access check for msg_queue |
| 3335 | * @msq: the object | 3254 | * @isp: the object |
| 3336 | * @msg: unused | 3255 | * @msg: unused |
| 3337 | * @target: unused | 3256 | * @target: unused |
| 3338 | * @type: unused | 3257 | * @type: unused |
| @@ -3340,10 +3259,10 @@ static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
| 3340 | * | 3259 | * |
| 3341 | * Returns 0 if current has read and write access, error code otherwise | 3260 | * Returns 0 if current has read and write access, error code otherwise |
| 3342 | */ | 3261 | */ |
| 3343 | static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | 3262 | static int smack_msg_queue_msgrcv(struct kern_ipc_perm *isp, struct msg_msg *msg, |
| 3344 | struct task_struct *target, long type, int mode) | 3263 | struct task_struct *target, long type, int mode) |
| 3345 | { | 3264 | { |
| 3346 | return smk_curacc_msq(msq, MAY_READWRITE); | 3265 | return smk_curacc_msq(isp, MAY_READWRITE); |
| 3347 | } | 3266 | } |
| 3348 | 3267 | ||
| 3349 | /** | 3268 | /** |
| @@ -4756,21 +4675,21 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { | |||
| 4756 | LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security), | 4675 | LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security), |
| 4757 | LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security), | 4676 | LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security), |
| 4758 | 4677 | ||
| 4759 | LSM_HOOK_INIT(msg_queue_alloc_security, smack_msg_queue_alloc_security), | 4678 | LSM_HOOK_INIT(msg_queue_alloc_security, smack_ipc_alloc_security), |
| 4760 | LSM_HOOK_INIT(msg_queue_free_security, smack_msg_queue_free_security), | 4679 | LSM_HOOK_INIT(msg_queue_free_security, smack_ipc_free_security), |
| 4761 | LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate), | 4680 | LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate), |
| 4762 | LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl), | 4681 | LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl), |
| 4763 | LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd), | 4682 | LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd), |
| 4764 | LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv), | 4683 | LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv), |
| 4765 | 4684 | ||
| 4766 | LSM_HOOK_INIT(shm_alloc_security, smack_shm_alloc_security), | 4685 | LSM_HOOK_INIT(shm_alloc_security, smack_ipc_alloc_security), |
| 4767 | LSM_HOOK_INIT(shm_free_security, smack_shm_free_security), | 4686 | LSM_HOOK_INIT(shm_free_security, smack_ipc_free_security), |
| 4768 | LSM_HOOK_INIT(shm_associate, smack_shm_associate), | 4687 | LSM_HOOK_INIT(shm_associate, smack_shm_associate), |
| 4769 | LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl), | 4688 | LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl), |
| 4770 | LSM_HOOK_INIT(shm_shmat, smack_shm_shmat), | 4689 | LSM_HOOK_INIT(shm_shmat, smack_shm_shmat), |
| 4771 | 4690 | ||
| 4772 | LSM_HOOK_INIT(sem_alloc_security, smack_sem_alloc_security), | 4691 | LSM_HOOK_INIT(sem_alloc_security, smack_ipc_alloc_security), |
| 4773 | LSM_HOOK_INIT(sem_free_security, smack_sem_free_security), | 4692 | LSM_HOOK_INIT(sem_free_security, smack_ipc_free_security), |
| 4774 | LSM_HOOK_INIT(sem_associate, smack_sem_associate), | 4693 | LSM_HOOK_INIT(sem_associate, smack_sem_associate), |
| 4775 | LSM_HOOK_INIT(sem_semctl, smack_sem_semctl), | 4694 | LSM_HOOK_INIT(sem_semctl, smack_sem_semctl), |
| 4776 | LSM_HOOK_INIT(sem_semop, smack_sem_semop), | 4695 | LSM_HOOK_INIT(sem_semop, smack_sem_semop), |
