diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/apparmor/include/path.h | 7 | ||||
-rw-r--r-- | security/integrity/digsig.c | 1 | ||||
-rw-r--r-- | security/keys/big_key.c | 110 | ||||
-rw-r--r-- | security/security.c | 32 | ||||
-rw-r--r-- | security/selinux/hooks.c | 92 | ||||
-rw-r--r-- | security/selinux/include/xfrm.h | 4 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 197 | ||||
-rw-r--r-- | security/tomoyo/network.c | 5 |
8 files changed, 214 insertions, 234 deletions
diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h index 05fb3305671e..e042b994f2b8 100644 --- a/security/apparmor/include/path.h +++ b/security/apparmor/include/path.h @@ -43,15 +43,10 @@ struct aa_buffers { DECLARE_PER_CPU(struct aa_buffers, aa_buffers); -#define COUNT_ARGS(X...) COUNT_ARGS_HELPER(, ##X, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) -#define COUNT_ARGS_HELPER(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, n, X...) n -#define CONCAT(X, Y) X ## Y -#define CONCAT_AFTER(X, Y) CONCAT(X, Y) - #define ASSIGN(FN, X, N) ((X) = FN(N)) #define EVAL1(FN, X) ASSIGN(FN, X, 0) /*X = FN(0)*/ #define EVAL2(FN, X, Y...) do { ASSIGN(FN, X, 1); EVAL1(FN, Y); } while (0) -#define EVAL(FN, X...) CONCAT_AFTER(EVAL, COUNT_ARGS(X))(FN, X) +#define EVAL(FN, X...) CONCATENATE(EVAL, COUNT_ARGS(X))(FN, X) #define for_each_cpu_buffer(I) for ((I) = 0; (I) < MAX_PATH_BUFFERS; (I)++) diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 6f9e4ce568cd..9bb0a7f2863e 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -18,6 +18,7 @@ #include <linux/cred.h> #include <linux/key-type.h> #include <linux/digsig.h> +#include <linux/vmalloc.h> #include <crypto/public_key.h> #include <keys/system_keyring.h> diff --git a/security/keys/big_key.c b/security/keys/big_key.c index 929e14978c42..fa728f662a6f 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c @@ -22,6 +22,13 @@ #include <keys/big_key-type.h> #include <crypto/aead.h> +struct big_key_buf { + unsigned int nr_pages; + void *virt; + struct scatterlist *sg; + struct page *pages[]; +}; + /* * Layout of key payload words. */ @@ -91,10 +98,9 @@ static DEFINE_MUTEX(big_key_aead_lock); /* * Encrypt/decrypt big_key data */ -static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key) +static int big_key_crypt(enum big_key_op op, struct big_key_buf *buf, size_t datalen, u8 *key) { int ret; - struct scatterlist sgio; struct aead_request *aead_req; /* We always use a zero nonce. The reason we can get away with this is * because we're using a different randomly generated key for every @@ -109,8 +115,7 @@ static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key) return -ENOMEM; memset(zero_nonce, 0, sizeof(zero_nonce)); - sg_init_one(&sgio, data, datalen + (op == BIG_KEY_ENC ? ENC_AUTHTAG_SIZE : 0)); - aead_request_set_crypt(aead_req, &sgio, &sgio, datalen, zero_nonce); + aead_request_set_crypt(aead_req, buf->sg, buf->sg, datalen, zero_nonce); aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); aead_request_set_ad(aead_req, 0); @@ -130,21 +135,81 @@ error: } /* + * Free up the buffer. + */ +static void big_key_free_buffer(struct big_key_buf *buf) +{ + unsigned int i; + + if (buf->virt) { + memset(buf->virt, 0, buf->nr_pages * PAGE_SIZE); + vunmap(buf->virt); + } + + for (i = 0; i < buf->nr_pages; i++) + if (buf->pages[i]) + __free_page(buf->pages[i]); + + kfree(buf); +} + +/* + * Allocate a buffer consisting of a set of pages with a virtual mapping + * applied over them. + */ +static void *big_key_alloc_buffer(size_t len) +{ + struct big_key_buf *buf; + unsigned int npg = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; + unsigned int i, l; + + buf = kzalloc(sizeof(struct big_key_buf) + + sizeof(struct page) * npg + + sizeof(struct scatterlist) * npg, + GFP_KERNEL); + if (!buf) + return NULL; + + buf->nr_pages = npg; + buf->sg = (void *)(buf->pages + npg); + sg_init_table(buf->sg, npg); + + for (i = 0; i < buf->nr_pages; i++) { + buf->pages[i] = alloc_page(GFP_KERNEL); + if (!buf->pages[i]) + goto nomem; + + l = min_t(size_t, len, PAGE_SIZE); + sg_set_page(&buf->sg[i], buf->pages[i], l, 0); + len -= l; + } + + buf->virt = vmap(buf->pages, buf->nr_pages, VM_MAP, PAGE_KERNEL); + if (!buf->virt) + goto nomem; + + return buf; + +nomem: + big_key_free_buffer(buf); + return NULL; +} + +/* * Preparse a big key */ int big_key_preparse(struct key_preparsed_payload *prep) { + struct big_key_buf *buf; struct path *path = (struct path *)&prep->payload.data[big_key_path]; struct file *file; u8 *enckey; - u8 *data = NULL; ssize_t written; - size_t datalen = prep->datalen; + size_t datalen = prep->datalen, enclen = datalen + ENC_AUTHTAG_SIZE; int ret; - ret = -EINVAL; if (datalen <= 0 || datalen > 1024 * 1024 || !prep->data) - goto error; + return -EINVAL; /* Set an arbitrary quota */ prep->quotalen = 16; @@ -157,13 +222,12 @@ int big_key_preparse(struct key_preparsed_payload *prep) * * File content is stored encrypted with randomly generated key. */ - size_t enclen = datalen + ENC_AUTHTAG_SIZE; loff_t pos = 0; - data = kmalloc(enclen, GFP_KERNEL); - if (!data) + buf = big_key_alloc_buffer(enclen); + if (!buf) return -ENOMEM; - memcpy(data, prep->data, datalen); + memcpy(buf->virt, prep->data, datalen); /* generate random key */ enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL); @@ -176,7 +240,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) goto err_enckey; /* encrypt aligned data */ - ret = big_key_crypt(BIG_KEY_ENC, data, datalen, enckey); + ret = big_key_crypt(BIG_KEY_ENC, buf, datalen, enckey); if (ret) goto err_enckey; @@ -187,7 +251,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) goto err_enckey; } - written = kernel_write(file, data, enclen, &pos); + written = kernel_write(file, buf->virt, enclen, &pos); if (written != enclen) { ret = written; if (written >= 0) @@ -202,7 +266,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) *path = file->f_path; path_get(path); fput(file); - kzfree(data); + big_key_free_buffer(buf); } else { /* Just store the data in a buffer */ void *data = kmalloc(datalen, GFP_KERNEL); @@ -220,7 +284,7 @@ err_fput: err_enckey: kzfree(enckey); error: - kzfree(data); + big_key_free_buffer(buf); return ret; } @@ -298,15 +362,15 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) return datalen; if (datalen > BIG_KEY_FILE_THRESHOLD) { + struct big_key_buf *buf; struct path *path = (struct path *)&key->payload.data[big_key_path]; struct file *file; - u8 *data; u8 *enckey = (u8 *)key->payload.data[big_key_data]; size_t enclen = datalen + ENC_AUTHTAG_SIZE; loff_t pos = 0; - data = kmalloc(enclen, GFP_KERNEL); - if (!data) + buf = big_key_alloc_buffer(enclen); + if (!buf) return -ENOMEM; file = dentry_open(path, O_RDONLY, current_cred()); @@ -316,26 +380,26 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) } /* read file to kernel and decrypt */ - ret = kernel_read(file, data, enclen, &pos); + ret = kernel_read(file, buf->virt, enclen, &pos); if (ret >= 0 && ret != enclen) { ret = -EIO; goto err_fput; } - ret = big_key_crypt(BIG_KEY_DEC, data, enclen, enckey); + ret = big_key_crypt(BIG_KEY_DEC, buf, enclen, enckey); if (ret) goto err_fput; ret = datalen; /* copy decrypted data to user */ - if (copy_to_user(buffer, data, datalen) != 0) + if (copy_to_user(buffer, buf->virt, datalen) != 0) ret = -EFAULT; err_fput: fput(file); error: - kzfree(data); + big_key_free_buffer(buf); } else { ret = datalen; if (copy_to_user(buffer, key->payload.data[big_key_data], 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) call_void_hook(msg_msg_free_security, msg); } -int security_msg_queue_alloc(struct msg_queue *msq) +int security_msg_queue_alloc(struct kern_ipc_perm *msq) { return call_int_hook(msg_queue_alloc_security, 0, msq); } -void security_msg_queue_free(struct msg_queue *msq) +void security_msg_queue_free(struct kern_ipc_perm *msq) { call_void_hook(msg_queue_free_security, msq); } -int security_msg_queue_associate(struct msg_queue *msq, int msqflg) +int security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) { return call_int_hook(msg_queue_associate, 0, msq, msqflg); } -int security_msg_queue_msgctl(struct msg_queue *msq, int cmd) +int security_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd) { return call_int_hook(msg_queue_msgctl, 0, msq, cmd); } -int security_msg_queue_msgsnd(struct msg_queue *msq, +int security_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg) { return call_int_hook(msg_queue_msgsnd, 0, msq, msg, msqflg); } -int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, +int security_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg, struct task_struct *target, long type, int mode) { return call_int_hook(msg_queue_msgrcv, 0, msq, msg, target, type, mode); } -int security_shm_alloc(struct shmid_kernel *shp) +int security_shm_alloc(struct kern_ipc_perm *shp) { return call_int_hook(shm_alloc_security, 0, shp); } -void security_shm_free(struct shmid_kernel *shp) +void security_shm_free(struct kern_ipc_perm *shp) { call_void_hook(shm_free_security, shp); } -int security_shm_associate(struct shmid_kernel *shp, int shmflg) +int security_shm_associate(struct kern_ipc_perm *shp, int shmflg) { return call_int_hook(shm_associate, 0, shp, shmflg); } -int security_shm_shmctl(struct shmid_kernel *shp, int cmd) +int security_shm_shmctl(struct kern_ipc_perm *shp, int cmd) { return call_int_hook(shm_shmctl, 0, shp, cmd); } -int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg) +int security_shm_shmat(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg) { return call_int_hook(shm_shmat, 0, shp, shmaddr, shmflg); } -int security_sem_alloc(struct sem_array *sma) +int security_sem_alloc(struct kern_ipc_perm *sma) { return call_int_hook(sem_alloc_security, 0, sma); } -void security_sem_free(struct sem_array *sma) +void security_sem_free(struct kern_ipc_perm *sma) { call_void_hook(sem_free_security, sma); } -int security_sem_associate(struct sem_array *sma, int semflg) +int security_sem_associate(struct kern_ipc_perm *sma, int semflg) { return call_int_hook(sem_associate, 0, sma, semflg); } -int security_sem_semctl(struct sem_array *sma, int cmd) +int security_sem_semctl(struct kern_ipc_perm *sma, int cmd) { return call_int_hook(sem_semctl, 0, sma, cmd); } -int security_sem_semop(struct sem_array *sma, struct sembuf *sops, +int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops, unsigned nsops, int alter) { 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) } /* message queue security operations */ -static int selinux_msg_queue_alloc_security(struct msg_queue *msq) +static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) { struct ipc_security_struct *isec; struct common_audit_data ad; u32 sid = current_sid(); int rc; - rc = ipc_alloc_security(&msq->q_perm, SECCLASS_MSGQ); + rc = ipc_alloc_security(msq, SECCLASS_MSGQ); if (rc) return rc; - isec = msq->q_perm.security; + isec = msq->security; ad.type = LSM_AUDIT_DATA_IPC; - ad.u.ipc_id = msq->q_perm.key; + ad.u.ipc_id = msq->key; rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, MSGQ__CREATE, &ad); if (rc) { - ipc_free_security(&msq->q_perm); + ipc_free_security(msq); return rc; } return 0; } -static void selinux_msg_queue_free_security(struct msg_queue *msq) +static void selinux_msg_queue_free_security(struct kern_ipc_perm *msq) { - ipc_free_security(&msq->q_perm); + ipc_free_security(msq); } -static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) +static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) { struct ipc_security_struct *isec; struct common_audit_data ad; u32 sid = current_sid(); - isec = msq->q_perm.security; + isec = msq->security; ad.type = LSM_AUDIT_DATA_IPC; - ad.u.ipc_id = msq->q_perm.key; + ad.u.ipc_id = msq->key; return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, MSGQ__ASSOCIATE, &ad); } -static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd) +static int selinux_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd) { int err; int perms; @@ -5602,11 +5602,11 @@ static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd) return 0; } - err = ipc_has_perm(&msq->q_perm, perms); + err = ipc_has_perm(msq, perms); return err; } -static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, int msqflg) +static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg) { struct ipc_security_struct *isec; struct msg_security_struct *msec; @@ -5614,7 +5614,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, u32 sid = current_sid(); int rc; - isec = msq->q_perm.security; + isec = msq->security; msec = msg->security; /* @@ -5632,7 +5632,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, } ad.type = LSM_AUDIT_DATA_IPC; - ad.u.ipc_id = msq->q_perm.key; + ad.u.ipc_id = msq->key; /* Can this process write to the queue? */ 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, return rc; } -static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, +static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg, struct task_struct *target, long type, int mode) { @@ -5659,11 +5659,11 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, u32 sid = task_sid(target); int rc; - isec = msq->q_perm.security; + isec = msq->security; msec = msg->security; ad.type = LSM_AUDIT_DATA_IPC; - ad.u.ipc_id = msq->q_perm.key; + ad.u.ipc_id = msq->key; rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, MSGQ__READ, &ad); @@ -5674,53 +5674,53 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, } /* Shared Memory security operations */ -static int selinux_shm_alloc_security(struct shmid_kernel *shp) +static int selinux_shm_alloc_security(struct kern_ipc_perm *shp) { struct ipc_security_struct *isec; struct common_audit_data ad; u32 sid = current_sid(); int rc; - rc = ipc_alloc_security(&shp->shm_perm, SECCLASS_SHM); + rc = ipc_alloc_security(shp, SECCLASS_SHM); if (rc) return rc; - isec = shp->shm_perm.security; + isec = shp->security; ad.type = LSM_AUDIT_DATA_IPC; - ad.u.ipc_id = shp->shm_perm.key; + ad.u.ipc_id = shp->key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, SHM__CREATE, &ad); if (rc) { - ipc_free_security(&shp->shm_perm); + ipc_free_security(shp); return rc; } return 0; } -static void selinux_shm_free_security(struct shmid_kernel *shp) +static void selinux_shm_free_security(struct kern_ipc_perm *shp) { - ipc_free_security(&shp->shm_perm); + ipc_free_security(shp); } -static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) +static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) { struct ipc_security_struct *isec; struct common_audit_data ad; u32 sid = current_sid(); - isec = shp->shm_perm.security; + isec = shp->security; ad.type = LSM_AUDIT_DATA_IPC; - ad.u.ipc_id = shp->shm_perm.key; + ad.u.ipc_id = shp->key; return avc_has_perm(sid, isec->sid, SECCLASS_SHM, SHM__ASSOCIATE, &ad); } /* Note, at this point, shp is locked down */ -static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd) +static int selinux_shm_shmctl(struct kern_ipc_perm *shp, int cmd) { int perms; int err; @@ -5749,11 +5749,11 @@ static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd) return 0; } - err = ipc_has_perm(&shp->shm_perm, perms); + err = ipc_has_perm(shp, perms); return err; } -static int selinux_shm_shmat(struct shmid_kernel *shp, +static int selinux_shm_shmat(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg) { u32 perms; @@ -5763,57 +5763,57 @@ static int selinux_shm_shmat(struct shmid_kernel *shp, else perms = SHM__READ | SHM__WRITE; - return ipc_has_perm(&shp->shm_perm, perms); + return ipc_has_perm(shp, perms); } /* Semaphore security operations */ -static int selinux_sem_alloc_security(struct sem_array *sma) +static int selinux_sem_alloc_security(struct kern_ipc_perm *sma) { struct ipc_security_struct *isec; struct common_audit_data ad; u32 sid = current_sid(); int rc; - rc = ipc_alloc_security(&sma->sem_perm, SECCLASS_SEM); + rc = ipc_alloc_security(sma, SECCLASS_SEM); if (rc) return rc; - isec = sma->sem_perm.security; + isec = sma->security; ad.type = LSM_AUDIT_DATA_IPC; - ad.u.ipc_id = sma->sem_perm.key; + ad.u.ipc_id = sma->key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, SEM__CREATE, &ad); if (rc) { - ipc_free_security(&sma->sem_perm); + ipc_free_security(sma); return rc; } return 0; } -static void selinux_sem_free_security(struct sem_array *sma) +static void selinux_sem_free_security(struct kern_ipc_perm *sma) { - ipc_free_security(&sma->sem_perm); + ipc_free_security(sma); } -static int selinux_sem_associate(struct sem_array *sma, int semflg) +static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) { struct ipc_security_struct *isec; struct common_audit_data ad; u32 sid = current_sid(); - isec = sma->sem_perm.security; + isec = sma->security; ad.type = LSM_AUDIT_DATA_IPC; - ad.u.ipc_id = sma->sem_perm.key; + ad.u.ipc_id = sma->key; return avc_has_perm(sid, isec->sid, SECCLASS_SEM, SEM__ASSOCIATE, &ad); } /* Note, at this point, sma is locked down */ -static int selinux_sem_semctl(struct sem_array *sma, int cmd) +static int selinux_sem_semctl(struct kern_ipc_perm *sma, int cmd) { int err; u32 perms; @@ -5851,11 +5851,11 @@ static int selinux_sem_semctl(struct sem_array *sma, int cmd) return 0; } - err = ipc_has_perm(&sma->sem_perm, perms); + err = ipc_has_perm(sma, perms); return err; } -static int selinux_sem_semop(struct sem_array *sma, +static int selinux_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops, unsigned nsops, int alter) { u32 perms; @@ -5865,7 +5865,7 @@ static int selinux_sem_semop(struct sem_array *sma, else perms = SEM__READ; - return ipc_has_perm(&sma->sem_perm, perms); + return ipc_has_perm(sma, perms); } static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 1f173a7a4daa..a0b465316292 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h @@ -47,10 +47,10 @@ static inline void selinux_xfrm_notify_policyload(void) { struct net *net; - rtnl_lock(); + down_read(&net_rwsem); for_each_net(net) rt_genid_bump_all(net); - rtnl_unlock(); + up_read(&net_rwsem); } #else static inline int selinux_xfrm_enabled(void) 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) } /** - * smack_of_shm - the smack pointer for the shm - * @shp: the object + * smack_of_ipc - the smack pointer for the ipc + * @isp: the object * * Returns a pointer to the smack value */ -static struct smack_known *smack_of_shm(struct shmid_kernel *shp) +static struct smack_known *smack_of_ipc(struct kern_ipc_perm *isp) { - return (struct smack_known *)shp->shm_perm.security; + return (struct smack_known *)isp->security; } /** - * smack_shm_alloc_security - Set the security blob for shm - * @shp: the object + * smack_ipc_alloc_security - Set the security blob for ipc + * @isp: the object * * Returns 0 */ -static int smack_shm_alloc_security(struct shmid_kernel *shp) +static int smack_ipc_alloc_security(struct kern_ipc_perm *isp) { - struct kern_ipc_perm *isp = &shp->shm_perm; struct smack_known *skp = smk_of_current(); isp->security = skp; @@ -2971,34 +2970,32 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp) } /** - * smack_shm_free_security - Clear the security blob for shm - * @shp: the object + * smack_ipc_free_security - Clear the security blob for ipc + * @isp: the object * * Clears the blob pointer */ -static void smack_shm_free_security(struct shmid_kernel *shp) +static void smack_ipc_free_security(struct kern_ipc_perm *isp) { - struct kern_ipc_perm *isp = &shp->shm_perm; - isp->security = NULL; } /** * smk_curacc_shm : check if current has access on shm - * @shp : the object + * @isp : the object * @access : access requested * * Returns 0 if current has the requested access, error code otherwise */ -static int smk_curacc_shm(struct shmid_kernel *shp, int access) +static int smk_curacc_shm(struct kern_ipc_perm *isp, int access) { - struct smack_known *ssp = smack_of_shm(shp); + struct smack_known *ssp = smack_of_ipc(isp); struct smk_audit_info ad; int rc; #ifdef CONFIG_AUDIT smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); - ad.a.u.ipc_id = shp->shm_perm.id; + ad.a.u.ipc_id = isp->id; #endif rc = smk_curacc(ssp, access, &ad); rc = smk_bu_current("shm", ssp, access, rc); @@ -3007,27 +3004,27 @@ static int smk_curacc_shm(struct shmid_kernel *shp, int access) /** * smack_shm_associate - Smack access check for shm - * @shp: the object + * @isp: the object * @shmflg: access requested * * Returns 0 if current has the requested access, error code otherwise */ -static int smack_shm_associate(struct shmid_kernel *shp, int shmflg) +static int smack_shm_associate(struct kern_ipc_perm *isp, int shmflg) { int may; may = smack_flags_to_may(shmflg); - return smk_curacc_shm(shp, may); + return smk_curacc_shm(isp, may); } /** * smack_shm_shmctl - Smack access check for shm - * @shp: the object + * @isp: the object * @cmd: what it wants to do * * Returns 0 if current has the requested access, error code otherwise */ -static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) +static int smack_shm_shmctl(struct kern_ipc_perm *isp, int cmd) { int may; @@ -3051,81 +3048,42 @@ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) default: return -EINVAL; } - return smk_curacc_shm(shp, may); + return smk_curacc_shm(isp, may); } /** * smack_shm_shmat - Smack access for shmat - * @shp: the object + * @isp: the object * @shmaddr: unused * @shmflg: access requested * * Returns 0 if current has the requested access, error code otherwise */ -static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, +static int smack_shm_shmat(struct kern_ipc_perm *ipc, char __user *shmaddr, int shmflg) { int may; may = smack_flags_to_may(shmflg); - return smk_curacc_shm(shp, may); -} - -/** - * smack_of_sem - the smack pointer for the sem - * @sma: the object - * - * Returns a pointer to the smack value - */ -static struct smack_known *smack_of_sem(struct sem_array *sma) -{ - return (struct smack_known *)sma->sem_perm.security; -} - -/** - * smack_sem_alloc_security - Set the security blob for sem - * @sma: the object - * - * Returns 0 - */ -static int smack_sem_alloc_security(struct sem_array *sma) -{ - struct kern_ipc_perm *isp = &sma->sem_perm; - struct smack_known *skp = smk_of_current(); - - isp->security = skp; - return 0; -} - -/** - * smack_sem_free_security - Clear the security blob for sem - * @sma: the object - * - * Clears the blob pointer - */ -static void smack_sem_free_security(struct sem_array *sma) -{ - struct kern_ipc_perm *isp = &sma->sem_perm; - - isp->security = NULL; + return smk_curacc_shm(ipc, may); } /** * smk_curacc_sem : check if current has access on sem - * @sma : the object + * @isp : the object * @access : access requested * * Returns 0 if current has the requested access, error code otherwise */ -static int smk_curacc_sem(struct sem_array *sma, int access) +static int smk_curacc_sem(struct kern_ipc_perm *isp, int access) { - struct smack_known *ssp = smack_of_sem(sma); + struct smack_known *ssp = smack_of_ipc(isp); struct smk_audit_info ad; int rc; #ifdef CONFIG_AUDIT smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); - ad.a.u.ipc_id = sma->sem_perm.id; + ad.a.u.ipc_id = isp->id; #endif rc = smk_curacc(ssp, access, &ad); rc = smk_bu_current("sem", ssp, access, rc); @@ -3134,27 +3092,27 @@ static int smk_curacc_sem(struct sem_array *sma, int access) /** * smack_sem_associate - Smack access check for sem - * @sma: the object + * @isp: the object * @semflg: access requested * * Returns 0 if current has the requested access, error code otherwise */ -static int smack_sem_associate(struct sem_array *sma, int semflg) +static int smack_sem_associate(struct kern_ipc_perm *isp, int semflg) { int may; may = smack_flags_to_may(semflg); - return smk_curacc_sem(sma, may); + return smk_curacc_sem(isp, may); } /** * smack_sem_shmctl - Smack access check for sem - * @sma: the object + * @isp: the object * @cmd: what it wants to do * * Returns 0 if current has the requested access, error code otherwise */ -static int smack_sem_semctl(struct sem_array *sma, int cmd) +static int smack_sem_semctl(struct kern_ipc_perm *isp, int cmd) { int may; @@ -3184,12 +3142,12 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd) return -EINVAL; } - return smk_curacc_sem(sma, may); + return smk_curacc_sem(isp, may); } /** * smack_sem_semop - Smack checks of semaphore operations - * @sma: the object + * @isp: the object * @sops: unused * @nsops: unused * @alter: unused @@ -3198,67 +3156,28 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd) * * Returns 0 if access is allowed, error code otherwise */ -static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops, +static int smack_sem_semop(struct kern_ipc_perm *isp, struct sembuf *sops, unsigned nsops, int alter) { - return smk_curacc_sem(sma, MAY_READWRITE); -} - -/** - * smack_msg_alloc_security - Set the security blob for msg - * @msq: the object - * - * Returns 0 - */ -static int smack_msg_queue_alloc_security(struct msg_queue *msq) -{ - struct kern_ipc_perm *kisp = &msq->q_perm; - struct smack_known *skp = smk_of_current(); - - kisp->security = skp; - return 0; -} - -/** - * smack_msg_free_security - Clear the security blob for msg - * @msq: the object - * - * Clears the blob pointer - */ -static void smack_msg_queue_free_security(struct msg_queue *msq) -{ - struct kern_ipc_perm *kisp = &msq->q_perm; - - kisp->security = NULL; -} - -/** - * smack_of_msq - the smack pointer for the msq - * @msq: the object - * - * Returns a pointer to the smack label entry - */ -static struct smack_known *smack_of_msq(struct msg_queue *msq) -{ - return (struct smack_known *)msq->q_perm.security; + return smk_curacc_sem(isp, MAY_READWRITE); } /** * smk_curacc_msq : helper to check if current has access on msq - * @msq : the msq + * @isp : the msq * @access : access requested * * return 0 if current has access, error otherwise */ -static int smk_curacc_msq(struct msg_queue *msq, int access) +static int smk_curacc_msq(struct kern_ipc_perm *isp, int access) { - struct smack_known *msp = smack_of_msq(msq); + struct smack_known *msp = smack_of_ipc(isp); struct smk_audit_info ad; int rc; #ifdef CONFIG_AUDIT smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); - ad.a.u.ipc_id = msq->q_perm.id; + ad.a.u.ipc_id = isp->id; #endif rc = smk_curacc(msp, access, &ad); rc = smk_bu_current("msq", msp, access, rc); @@ -3267,27 +3186,27 @@ static int smk_curacc_msq(struct msg_queue *msq, int access) /** * smack_msg_queue_associate - Smack access check for msg_queue - * @msq: the object + * @isp: the object * @msqflg: access requested * * Returns 0 if current has the requested access, error code otherwise */ -static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg) +static int smack_msg_queue_associate(struct kern_ipc_perm *isp, int msqflg) { int may; may = smack_flags_to_may(msqflg); - return smk_curacc_msq(msq, may); + return smk_curacc_msq(isp, may); } /** * smack_msg_queue_msgctl - Smack access check for msg_queue - * @msq: the object + * @isp: the object * @cmd: what it wants to do * * Returns 0 if current has the requested access, error code otherwise */ -static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) +static int smack_msg_queue_msgctl(struct kern_ipc_perm *isp, int cmd) { int may; @@ -3310,29 +3229,29 @@ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) return -EINVAL; } - return smk_curacc_msq(msq, may); + return smk_curacc_msq(isp, may); } /** * smack_msg_queue_msgsnd - Smack access check for msg_queue - * @msq: the object + * @isp: the object * @msg: unused * @msqflg: access requested * * Returns 0 if current has the requested access, error code otherwise */ -static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, +static int smack_msg_queue_msgsnd(struct kern_ipc_perm *isp, struct msg_msg *msg, int msqflg) { int may; may = smack_flags_to_may(msqflg); - return smk_curacc_msq(msq, may); + return smk_curacc_msq(isp, may); } /** * smack_msg_queue_msgsnd - Smack access check for msg_queue - * @msq: the object + * @isp: the object * @msg: unused * @target: unused * @type: unused @@ -3340,10 +3259,10 @@ static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, * * Returns 0 if current has read and write access, error code otherwise */ -static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, +static int smack_msg_queue_msgrcv(struct kern_ipc_perm *isp, struct msg_msg *msg, struct task_struct *target, long type, int mode) { - return smk_curacc_msq(msq, MAY_READWRITE); + return smk_curacc_msq(isp, MAY_READWRITE); } /** @@ -4756,21 +4675,21 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security), LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security), - LSM_HOOK_INIT(msg_queue_alloc_security, smack_msg_queue_alloc_security), - LSM_HOOK_INIT(msg_queue_free_security, smack_msg_queue_free_security), + LSM_HOOK_INIT(msg_queue_alloc_security, smack_ipc_alloc_security), + LSM_HOOK_INIT(msg_queue_free_security, smack_ipc_free_security), LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate), LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl), LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd), LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv), - LSM_HOOK_INIT(shm_alloc_security, smack_shm_alloc_security), - LSM_HOOK_INIT(shm_free_security, smack_shm_free_security), + LSM_HOOK_INIT(shm_alloc_security, smack_ipc_alloc_security), + LSM_HOOK_INIT(shm_free_security, smack_ipc_free_security), LSM_HOOK_INIT(shm_associate, smack_shm_associate), LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl), LSM_HOOK_INIT(shm_shmat, smack_shm_shmat), - LSM_HOOK_INIT(sem_alloc_security, smack_sem_alloc_security), - LSM_HOOK_INIT(sem_free_security, smack_sem_free_security), + LSM_HOOK_INIT(sem_alloc_security, smack_ipc_alloc_security), + LSM_HOOK_INIT(sem_free_security, smack_ipc_free_security), LSM_HOOK_INIT(sem_associate, smack_sem_associate), LSM_HOOK_INIT(sem_semctl, smack_sem_semctl), LSM_HOOK_INIT(sem_semop, smack_sem_semop), diff --git a/security/tomoyo/network.c b/security/tomoyo/network.c index cd6932e5225c..9094f4b3b367 100644 --- a/security/tomoyo/network.c +++ b/security/tomoyo/network.c @@ -655,10 +655,11 @@ int tomoyo_socket_listen_permission(struct socket *sock) return 0; { const int error = sock->ops->getname(sock, (struct sockaddr *) - &addr, &addr_len, 0); + &addr, 0); - if (error) + if (error < 0) return error; + addr_len = error; } address.protocol = type; address.operation = TOMOYO_NETWORK_LISTEN; |