From 7d877f3bda870ab5f001bd92528654471d5966b3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 21 Oct 2005 03:20:43 -0400 Subject: [PATCH] gfp_t: net/* Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'security/selinux/hooks.c') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b13be15165f5..447a1e0f48cb 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -262,7 +262,7 @@ static void superblock_free_security(struct super_block *sb) } #ifdef CONFIG_SECURITY_NETWORK -static int sk_alloc_security(struct sock *sk, int family, int priority) +static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) { struct sk_security_struct *ssec; @@ -3380,7 +3380,7 @@ out: return err; } -static int selinux_sk_alloc_security(struct sock *sk, int family, int priority) +static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) { return sk_alloc_security(sk, family, priority); } -- cgit v1.2.3 From 89d155ef62e5e0c10e4b37aaa5056f0beafe10e6 Mon Sep 17 00:00:00 2001 From: James Morris Date: Sun, 30 Oct 2005 14:59:21 -0800 Subject: [PATCH] SELinux: convert to kzalloc This patch converts SELinux code from kmalloc/memset to the new kazalloc unction. On i386, this results in a text saving of over 1K. Before: text data bss dec hex filename 86319 4642 15236 106197 19ed5 security/selinux/built-in.o After: text data bss dec hex filename 85278 4642 15236 105156 19ac4 security/selinux/built-in.o Signed-off-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 24 ++++++------------ security/selinux/netif.c | 3 +-- security/selinux/selinuxfs.c | 30 ++++++++--------------- security/selinux/ss/conditional.c | 12 +++------ security/selinux/ss/ebitmap.c | 9 +++---- security/selinux/ss/hashtab.c | 6 ++--- security/selinux/ss/policydb.c | 51 +++++++++++++-------------------------- security/selinux/ss/services.c | 11 +++------ 8 files changed, 49 insertions(+), 97 deletions(-) (limited to 'security/selinux/hooks.c') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 447a1e0f48cb..8cd33b2cd865 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -122,11 +122,10 @@ static int task_alloc_security(struct task_struct *task) { struct task_security_struct *tsec; - tsec = kmalloc(sizeof(struct task_security_struct), GFP_KERNEL); + tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL); if (!tsec) return -ENOMEM; - memset(tsec, 0, sizeof(struct task_security_struct)); tsec->magic = SELINUX_MAGIC; tsec->task = task; tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED; @@ -151,11 +150,10 @@ static int inode_alloc_security(struct inode *inode) struct task_security_struct *tsec = current->security; struct inode_security_struct *isec; - isec = kmalloc(sizeof(struct inode_security_struct), GFP_KERNEL); + isec = kzalloc(sizeof(struct inode_security_struct), GFP_KERNEL); if (!isec) return -ENOMEM; - memset(isec, 0, sizeof(struct inode_security_struct)); init_MUTEX(&isec->sem); INIT_LIST_HEAD(&isec->list); isec->magic = SELINUX_MAGIC; @@ -193,11 +191,10 @@ static int file_alloc_security(struct file *file) struct task_security_struct *tsec = current->security; struct file_security_struct *fsec; - fsec = kmalloc(sizeof(struct file_security_struct), GFP_ATOMIC); + fsec = kzalloc(sizeof(struct file_security_struct), GFP_ATOMIC); if (!fsec) return -ENOMEM; - memset(fsec, 0, sizeof(struct file_security_struct)); fsec->magic = SELINUX_MAGIC; fsec->file = file; if (tsec && tsec->magic == SELINUX_MAGIC) { @@ -227,11 +224,10 @@ static int superblock_alloc_security(struct super_block *sb) { struct superblock_security_struct *sbsec; - sbsec = kmalloc(sizeof(struct superblock_security_struct), GFP_KERNEL); + sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL); if (!sbsec) return -ENOMEM; - memset(sbsec, 0, sizeof(struct superblock_security_struct)); init_MUTEX(&sbsec->sem); INIT_LIST_HEAD(&sbsec->list); INIT_LIST_HEAD(&sbsec->isec_head); @@ -269,11 +265,10 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) if (family != PF_UNIX) return 0; - ssec = kmalloc(sizeof(*ssec), priority); + ssec = kzalloc(sizeof(*ssec), priority); if (!ssec) return -ENOMEM; - memset(ssec, 0, sizeof(*ssec)); ssec->magic = SELINUX_MAGIC; ssec->sk = sk; ssec->peer_sid = SECINITSID_UNLABELED; @@ -1483,11 +1478,10 @@ static int selinux_bprm_alloc_security(struct linux_binprm *bprm) { struct bprm_security_struct *bsec; - bsec = kmalloc(sizeof(struct bprm_security_struct), GFP_KERNEL); + bsec = kzalloc(sizeof(struct bprm_security_struct), GFP_KERNEL); if (!bsec) return -ENOMEM; - memset(bsec, 0, sizeof *bsec); bsec->magic = SELINUX_MAGIC; bsec->bprm = bprm; bsec->sid = SECINITSID_UNLABELED; @@ -3599,11 +3593,10 @@ static int ipc_alloc_security(struct task_struct *task, struct task_security_struct *tsec = task->security; struct ipc_security_struct *isec; - isec = kmalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); + isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); if (!isec) return -ENOMEM; - memset(isec, 0, sizeof(struct ipc_security_struct)); isec->magic = SELINUX_MAGIC; isec->sclass = sclass; isec->ipc_perm = perm; @@ -3631,11 +3624,10 @@ static int msg_msg_alloc_security(struct msg_msg *msg) { struct msg_security_struct *msec; - msec = kmalloc(sizeof(struct msg_security_struct), GFP_KERNEL); + msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL); if (!msec) return -ENOMEM; - memset(msec, 0, sizeof(struct msg_security_struct)); msec->magic = SELINUX_MAGIC; msec->msg = msg; msec->sid = SECINITSID_UNLABELED; diff --git a/security/selinux/netif.c b/security/selinux/netif.c index 718d7be9f4dd..b10c34e8a743 100644 --- a/security/selinux/netif.c +++ b/security/selinux/netif.c @@ -114,13 +114,12 @@ static struct sel_netif *sel_netif_lookup(struct net_device *dev) if (likely(netif != NULL)) goto out; - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kzalloc(sizeof(*new), GFP_ATOMIC); if (!new) { netif = ERR_PTR(-ENOMEM); goto out; } - memset(new, 0, sizeof(*new)); nsec = &new->nsec; ret = security_netif_sid(dev->name, &nsec->if_sid, &nsec->msg_sid); diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index a45cc971e735..5f8427627211 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -424,15 +424,13 @@ static ssize_t sel_write_access(struct file * file, char *buf, size_t size) return length; length = -ENOMEM; - scon = kmalloc(size+1, GFP_KERNEL); + scon = kzalloc(size+1, GFP_KERNEL); if (!scon) return length; - memset(scon, 0, size+1); - tcon = kmalloc(size+1, GFP_KERNEL); + tcon = kzalloc(size+1, GFP_KERNEL); if (!tcon) goto out; - memset(tcon, 0, size+1); length = -EINVAL; if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4) @@ -475,15 +473,13 @@ static ssize_t sel_write_create(struct file * file, char *buf, size_t size) return length; length = -ENOMEM; - scon = kmalloc(size+1, GFP_KERNEL); + scon = kzalloc(size+1, GFP_KERNEL); if (!scon) return length; - memset(scon, 0, size+1); - tcon = kmalloc(size+1, GFP_KERNEL); + tcon = kzalloc(size+1, GFP_KERNEL); if (!tcon) goto out; - memset(tcon, 0, size+1); length = -EINVAL; if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) @@ -536,15 +532,13 @@ static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size) return length; length = -ENOMEM; - scon = kmalloc(size+1, GFP_KERNEL); + scon = kzalloc(size+1, GFP_KERNEL); if (!scon) return length; - memset(scon, 0, size+1); - tcon = kmalloc(size+1, GFP_KERNEL); + tcon = kzalloc(size+1, GFP_KERNEL); if (!tcon) goto out; - memset(tcon, 0, size+1); length = -EINVAL; if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) @@ -595,15 +589,13 @@ static ssize_t sel_write_user(struct file * file, char *buf, size_t size) return length; length = -ENOMEM; - con = kmalloc(size+1, GFP_KERNEL); + con = kzalloc(size+1, GFP_KERNEL); if (!con) return length; - memset(con, 0, size+1); - user = kmalloc(size+1, GFP_KERNEL); + user = kzalloc(size+1, GFP_KERNEL); if (!user) goto out; - memset(user, 0, size+1); length = -EINVAL; if (sscanf(buf, "%s %s", con, user) != 2) @@ -658,15 +650,13 @@ static ssize_t sel_write_member(struct file * file, char *buf, size_t size) return length; length = -ENOMEM; - scon = kmalloc(size+1, GFP_KERNEL); + scon = kzalloc(size+1, GFP_KERNEL); if (!scon) return length; - memset(scon, 0, size+1); - tcon = kmalloc(size+1, GFP_KERNEL); + tcon = kzalloc(size+1, GFP_KERNEL); if (!tcon) goto out; - memset(tcon, 0, size+1); length = -EINVAL; if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index daf288007460..d2737edba541 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c @@ -220,10 +220,9 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp) u32 len; int rc; - booldatum = kmalloc(sizeof(struct cond_bool_datum), GFP_KERNEL); + booldatum = kzalloc(sizeof(struct cond_bool_datum), GFP_KERNEL); if (!booldatum) return -1; - memset(booldatum, 0, sizeof(struct cond_bool_datum)); rc = next_entry(buf, fp, sizeof buf); if (rc < 0) @@ -321,10 +320,9 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum goto err; } - list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL); + list = kzalloc(sizeof(struct cond_av_list), GFP_KERNEL); if (!list) goto err; - memset(list, 0, sizeof(*list)); list->node = node_ptr; if (!data->head) @@ -414,11 +412,10 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) if (rc < 0) goto err; - expr = kmalloc(sizeof(struct cond_expr), GFP_KERNEL); + expr = kzalloc(sizeof(struct cond_expr), GFP_KERNEL); if (!expr) { goto err; } - memset(expr, 0, sizeof(struct cond_expr)); expr->expr_type = le32_to_cpu(buf[0]); expr->bool = le32_to_cpu(buf[1]); @@ -460,10 +457,9 @@ int cond_read_list(struct policydb *p, void *fp) len = le32_to_cpu(buf[0]); for (i = 0; i < len; i++) { - node = kmalloc(sizeof(struct cond_node), GFP_KERNEL); + node = kzalloc(sizeof(struct cond_node), GFP_KERNEL); if (!node) goto err; - memset(node, 0, sizeof(struct cond_node)); if (cond_read_node(p, node, fp) != 0) goto err; diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index d515154128cc..47024a6e1844 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c @@ -39,12 +39,11 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src) n = src->node; prev = NULL; while (n) { - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kzalloc(sizeof(*new), GFP_ATOMIC); if (!new) { ebitmap_destroy(dst); return -ENOMEM; } - memset(new, 0, sizeof(*new)); new->startbit = n->startbit; new->map = n->map; new->next = NULL; @@ -150,10 +149,9 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value) if (!value) return 0; - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kzalloc(sizeof(*new), GFP_ATOMIC); if (!new) return -ENOMEM; - memset(new, 0, sizeof(*new)); new->startbit = bit & ~(MAPSIZE - 1); new->map = (MAPBIT << (bit - new->startbit)); @@ -232,13 +230,12 @@ int ebitmap_read(struct ebitmap *e, void *fp) printk(KERN_ERR "security: ebitmap: truncated map\n"); goto bad; } - n = kmalloc(sizeof(*n), GFP_KERNEL); + n = kzalloc(sizeof(*n), GFP_KERNEL); if (!n) { printk(KERN_ERR "security: ebitmap: out of memory\n"); rc = -ENOMEM; goto bad; } - memset(n, 0, sizeof(*n)); n->startbit = le32_to_cpu(buf[0]); diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index 26661fcc00ce..24e5ec957630 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -15,11 +15,10 @@ struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, void *key), struct hashtab *p; u32 i; - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) return p; - memset(p, 0, sizeof(*p)); p->size = size; p->nel = 0; p->hash_value = hash_value; @@ -55,10 +54,9 @@ int hashtab_insert(struct hashtab *h, void *key, void *datum) if (cur && (h->keycmp(h, key, cur->key) == 0)) return -EEXIST; - newnode = kmalloc(sizeof(*newnode), GFP_KERNEL); + newnode = kzalloc(sizeof(*newnode), GFP_KERNEL); if (newnode == NULL) return -ENOMEM; - memset(newnode, 0, sizeof(*newnode)); newnode->key = key; newnode->datum = datum; if (prev) { diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 8e6262d12aa9..2f5f539875f2 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -121,12 +121,11 @@ static int roles_init(struct policydb *p) int rc; struct role_datum *role; - role = kmalloc(sizeof(*role), GFP_KERNEL); + role = kzalloc(sizeof(*role), GFP_KERNEL); if (!role) { rc = -ENOMEM; goto out; } - memset(role, 0, sizeof(*role)); role->value = ++p->p_roles.nprim; if (role->value != OBJECT_R_VAL) { rc = -EINVAL; @@ -851,12 +850,11 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[2]; u32 len; - perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL); + perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); if (!perdatum) { rc = -ENOMEM; goto out; } - memset(perdatum, 0, sizeof(*perdatum)); rc = next_entry(buf, fp, sizeof buf); if (rc < 0) @@ -893,12 +891,11 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) u32 len, nel; int i, rc; - comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL); + comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); if (!comdatum) { rc = -ENOMEM; goto out; } - memset(comdatum, 0, sizeof(*comdatum)); rc = next_entry(buf, fp, sizeof buf); if (rc < 0) @@ -950,10 +947,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, lc = NULL; for (i = 0; i < ncons; i++) { - c = kmalloc(sizeof(*c), GFP_KERNEL); + c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return -ENOMEM; - memset(c, 0, sizeof(*c)); if (lc) { lc->next = c; @@ -969,10 +965,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, le = NULL; depth = -1; for (j = 0; j < nexpr; j++) { - e = kmalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc(sizeof(*e), GFP_KERNEL); if (!e) return -ENOMEM; - memset(e, 0, sizeof(*e)); if (le) { le->next = e; @@ -1033,12 +1028,11 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) u32 len, len2, ncons, nel; int i, rc; - cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL); + cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); if (!cladatum) { rc = -ENOMEM; goto out; } - memset(cladatum, 0, sizeof(*cladatum)); rc = next_entry(buf, fp, sizeof(u32)*6); if (rc < 0) @@ -1127,12 +1121,11 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[2]; u32 len; - role = kmalloc(sizeof(*role), GFP_KERNEL); + role = kzalloc(sizeof(*role), GFP_KERNEL); if (!role) { rc = -ENOMEM; goto out; } - memset(role, 0, sizeof(*role)); rc = next_entry(buf, fp, sizeof buf); if (rc < 0) @@ -1188,12 +1181,11 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[3]; u32 len; - typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL); + typdatum = kzalloc(sizeof(*typdatum),GFP_KERNEL); if (!typdatum) { rc = -ENOMEM; return rc; } - memset(typdatum, 0, sizeof(*typdatum)); rc = next_entry(buf, fp, sizeof buf); if (rc < 0) @@ -1261,12 +1253,11 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[2]; u32 len; - usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL); + usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL); if (!usrdatum) { rc = -ENOMEM; goto out; } - memset(usrdatum, 0, sizeof(*usrdatum)); rc = next_entry(buf, fp, sizeof buf); if (rc < 0) @@ -1316,12 +1307,11 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[2]; u32 len; - levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC); + levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC); if (!levdatum) { rc = -ENOMEM; goto out; } - memset(levdatum, 0, sizeof(*levdatum)); rc = next_entry(buf, fp, sizeof buf); if (rc < 0) @@ -1368,12 +1358,11 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp) __le32 buf[3]; u32 len; - catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC); + catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC); if (!catdatum) { rc = -ENOMEM; goto out; } - memset(catdatum, 0, sizeof(*catdatum)); rc = next_entry(buf, fp, sizeof buf); if (rc < 0) @@ -1567,12 +1556,11 @@ int policydb_read(struct policydb *p, void *fp) nel = le32_to_cpu(buf[0]); ltr = NULL; for (i = 0; i < nel; i++) { - tr = kmalloc(sizeof(*tr), GFP_KERNEL); + tr = kzalloc(sizeof(*tr), GFP_KERNEL); if (!tr) { rc = -ENOMEM; goto bad; } - memset(tr, 0, sizeof(*tr)); if (ltr) { ltr->next = tr; } else { @@ -1593,12 +1581,11 @@ int policydb_read(struct policydb *p, void *fp) nel = le32_to_cpu(buf[0]); lra = NULL; for (i = 0; i < nel; i++) { - ra = kmalloc(sizeof(*ra), GFP_KERNEL); + ra = kzalloc(sizeof(*ra), GFP_KERNEL); if (!ra) { rc = -ENOMEM; goto bad; } - memset(ra, 0, sizeof(*ra)); if (lra) { lra->next = ra; } else { @@ -1627,12 +1614,11 @@ int policydb_read(struct policydb *p, void *fp) nel = le32_to_cpu(buf[0]); l = NULL; for (j = 0; j < nel; j++) { - c = kmalloc(sizeof(*c), GFP_KERNEL); + c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) { rc = -ENOMEM; goto bad; } - memset(c, 0, sizeof(*c)); if (l) { l->next = c; } else { @@ -1743,12 +1729,11 @@ int policydb_read(struct policydb *p, void *fp) if (rc < 0) goto bad; len = le32_to_cpu(buf[0]); - newgenfs = kmalloc(sizeof(*newgenfs), GFP_KERNEL); + newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL); if (!newgenfs) { rc = -ENOMEM; goto bad; } - memset(newgenfs, 0, sizeof(*newgenfs)); newgenfs->fstype = kmalloc(len + 1,GFP_KERNEL); if (!newgenfs->fstype) { @@ -1790,12 +1775,11 @@ int policydb_read(struct policydb *p, void *fp) goto bad; len = le32_to_cpu(buf[0]); - newc = kmalloc(sizeof(*newc), GFP_KERNEL); + newc = kzalloc(sizeof(*newc), GFP_KERNEL); if (!newc) { rc = -ENOMEM; goto bad; } - memset(newc, 0, sizeof(*newc)); newc->u.name = kmalloc(len + 1,GFP_KERNEL); if (!newc->u.name) { @@ -1843,12 +1827,11 @@ int policydb_read(struct policydb *p, void *fp) nel = le32_to_cpu(buf[0]); lrt = NULL; for (i = 0; i < nel; i++) { - rt = kmalloc(sizeof(*rt), GFP_KERNEL); + rt = kzalloc(sizeof(*rt), GFP_KERNEL); if (!rt) { rc = -ENOMEM; goto bad; } - memset(rt, 0, sizeof(*rt)); if (lrt) lrt->next = rt; else diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index aecdded55e74..44eb4d74908d 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1531,12 +1531,11 @@ int security_get_user_sids(u32 fromsid, } usercon.user = user->value; - mysids = kmalloc(maxnel*sizeof(*mysids), GFP_ATOMIC); + mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); if (!mysids) { rc = -ENOMEM; goto out_unlock; } - memset(mysids, 0, maxnel*sizeof(*mysids)); ebitmap_for_each_bit(&user->roles, rnode, i) { if (!ebitmap_node_get_bit(rnode, i)) @@ -1566,13 +1565,12 @@ int security_get_user_sids(u32 fromsid, mysids[mynel++] = sid; } else { maxnel += SIDS_NEL; - mysids2 = kmalloc(maxnel*sizeof(*mysids2), GFP_ATOMIC); + mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); if (!mysids2) { rc = -ENOMEM; kfree(mysids); goto out_unlock; } - memset(mysids2, 0, maxnel*sizeof(*mysids2)); memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); kfree(mysids); mysids = mysids2; @@ -1714,12 +1712,11 @@ int security_get_bools(int *len, char ***names, int **values) goto out; } - *names = (char**)kmalloc(sizeof(char*) * *len, GFP_ATOMIC); + *names = (char**)kcalloc(*len, sizeof(char*), GFP_ATOMIC); if (!*names) goto err; - memset(*names, 0, sizeof(char*) * *len); - *values = (int*)kmalloc(sizeof(int) * *len, GFP_ATOMIC); + *values = (int*)kcalloc(*len, sizeof(int), GFP_ATOMIC); if (!*values) goto err; -- cgit v1.2.3 From d381d8a9a08cac9824096213069159be17fd2e2f Mon Sep 17 00:00:00 2001 From: James Morris Date: Sun, 30 Oct 2005 14:59:22 -0800 Subject: [PATCH] SELinux: canonicalize getxattr() This patch allows SELinux to canonicalize the value returned from getxattr() via the security_inode_getsecurity() hook, which is called after the fs level getxattr() function. The purpose of this is to allow the in-core security context for an inode to override the on-disk value. This could happen in cases such as upgrading a system to a different labeling form (e.g. standard SELinux to MLS) without needing to do a full relabel of the filesystem. In such cases, we want getxattr() to return the canonical security context that the kernel is using rather than what is stored on disk. The implementation hooks into the inode_getsecurity(), adding another parameter to indicate the result of the preceding fs-level getxattr() call, so that SELinux knows whether to compare a value obtained from disk with the kernel value. We also now allow getxattr() to work for mountpoint labeled filesystems (i.e. mount with option context=foo_t), as we are able to return the kernel value to the user. Signed-off-by: James Morris Signed-off-by: Stephen Smalley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/xattr.c | 14 +++++++++----- include/linux/security.h | 11 +++++++---- security/dummy.c | 2 +- security/selinux/hooks.c | 46 ++++++++++++++++++++++++++++++++-------------- 4 files changed, 49 insertions(+), 24 deletions(-) (limited to 'security/selinux/hooks.c') diff --git a/fs/xattr.c b/fs/xattr.c index 3f9c64bea151..f6e00c0e114f 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -143,7 +143,7 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size) if (size) { if (size > XATTR_SIZE_MAX) size = XATTR_SIZE_MAX; - kvalue = kmalloc(size, GFP_KERNEL); + kvalue = kzalloc(size, GFP_KERNEL); if (!kvalue) return -ENOMEM; } @@ -154,11 +154,15 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size) error = -EOPNOTSUPP; if (d->d_inode->i_op && d->d_inode->i_op->getxattr) error = d->d_inode->i_op->getxattr(d, kname, kvalue, size); - else if (!strncmp(kname, XATTR_SECURITY_PREFIX, - sizeof XATTR_SECURITY_PREFIX - 1)) { + + if (!strncmp(kname, XATTR_SECURITY_PREFIX, + sizeof XATTR_SECURITY_PREFIX - 1)) { const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1; - error = security_inode_getsecurity(d->d_inode, suffix, kvalue, - size); + int rv = security_inode_getsecurity(d->d_inode, suffix, kvalue, + size, error); + /* Security module active: overwrite error value */ + if (rv != -EOPNOTSUPP) + error = rv; } if (error > 0) { if (size && copy_to_user(value, kvalue, error)) diff --git a/include/linux/security.h b/include/linux/security.h index dac956ed98f0..607ee209ea3b 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -385,6 +385,9 @@ struct swap_info_struct; * NULL to request the size of the buffer required. @size indicates * the size of @buffer in bytes. Note that @name is the remainder * of the attribute name after the security. prefix has been removed. + * @err is the return value from the preceding fs getxattr call, + * and can be used by the security module to determine whether it + * should try and canonicalize the attribute value. * Return number of bytes used/required on success. * @inode_setsecurity: * Set the security label associated with @name for @inode from the @@ -1091,7 +1094,7 @@ struct security_operations { int (*inode_getxattr) (struct dentry *dentry, char *name); int (*inode_listxattr) (struct dentry *dentry); int (*inode_removexattr) (struct dentry *dentry, char *name); - int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size); + int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size, int err); int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags); int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size); @@ -1580,11 +1583,11 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name) return security_ops->inode_removexattr (dentry, name); } -static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size) +static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) { if (unlikely (IS_PRIVATE (inode))) return 0; - return security_ops->inode_getsecurity(inode, name, buffer, size); + return security_ops->inode_getsecurity(inode, name, buffer, size, err); } static inline int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) @@ -2222,7 +2225,7 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name) return cap_inode_removexattr(dentry, name); } -static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size) +static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) { return -EOPNOTSUPP; } diff --git a/security/dummy.c b/security/dummy.c index 3d34f3de7e82..2a0337a52d32 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -377,7 +377,7 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name) return 0; } -static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size) +static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) { return -EOPNOTSUPP; } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 8cd33b2cd865..d9ec85292e1c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2208,9 +2208,6 @@ static int selinux_inode_getxattr (struct dentry *dentry, char *name) struct inode *inode = dentry->d_inode; struct superblock_security_struct *sbsec = inode->i_sb->s_security; - if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) - return -EOPNOTSUPP; - return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); } @@ -2241,33 +2238,54 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name) return -EACCES; } -static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size) +/* + * Copy the in-core inode security context value to the user. If the + * getxattr() prior to this succeeded, check to see if we need to + * canonicalize the value to be finally returned to the user. + * + * Permission check is handled by selinux_inode_getxattr hook. + */ +static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) { struct inode_security_struct *isec = inode->i_security; char *context; unsigned len; int rc; - /* Permission check handled by selinux_inode_getxattr hook.*/ - - if (strcmp(name, XATTR_SELINUX_SUFFIX)) - return -EOPNOTSUPP; + if (strcmp(name, XATTR_SELINUX_SUFFIX)) { + rc = -EOPNOTSUPP; + goto out; + } rc = security_sid_to_context(isec->sid, &context, &len); if (rc) - return rc; + goto out; + /* Probe for required buffer size */ if (!buffer || !size) { - kfree(context); - return len; + rc = len; + goto out_free; } + if (size < len) { - kfree(context); - return -ERANGE; + rc = -ERANGE; + goto out_free; + } + + if (err > 0) { + if ((len == err) && !(memcmp(context, buffer, len))) { + /* Don't need to canonicalize value */ + rc = err; + goto out_free; + } + memset(buffer, 0, size); } memcpy(buffer, context, len); + rc = len; +out_free: kfree(context); - return len; +out: + return rc; } static int selinux_inode_setsecurity(struct inode *inode, const char *name, -- cgit v1.2.3 From ce4c2bd1a9dfebaefadc2d34b17c6f12101751be Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 30 Oct 2005 14:59:23 -0800 Subject: [PATCH] selinux-canonicalize-getxattr-fix security/selinux/hooks.c: In function `selinux_inode_getxattr': security/selinux/hooks.c:2193: warning: unused variable `sbsec' Cc: James Morris Cc: Stephen Smalley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'security/selinux/hooks.c') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d9ec85292e1c..d50d7a782cf5 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2205,9 +2205,6 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, static int selinux_inode_getxattr (struct dentry *dentry, char *name) { - struct inode *inode = dentry->d_inode; - struct superblock_security_struct *sbsec = inode->i_sb->s_security; - return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); } -- cgit v1.2.3 From 2f51201662b28dbf8c15fb7eb972bc51c6cc3fa5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 30 Oct 2005 15:02:16 -0800 Subject: [PATCH] reduce sizeof(struct file) Now that RCU applied on 'struct file' seems stable, we can place f_rcuhead in a memory location that is not anymore used at call_rcu(&f->f_rcuhead, file_free_rcu) time, to reduce the size of this critical kernel object. The trick I used is to move f_rcuhead and f_list in an union called f_u The callers are changed so that f_rcuhead becomes f_u.fu_rcuhead and f_list becomes f_u.f_list Signed-off-by: Eric Dumazet Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tty_io.c | 2 +- fs/dquot.c | 2 +- fs/file_table.c | 14 +++++++------- fs/proc/generic.c | 2 +- fs/super.c | 2 +- include/linux/fs.h | 10 ++++++++-- security/selinux/hooks.c | 2 +- security/selinux/selinuxfs.c | 2 +- 8 files changed, 21 insertions(+), 15 deletions(-) (limited to 'security/selinux/hooks.c') diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index f5649a337743..c586bfa852ee 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -809,7 +809,7 @@ static void do_tty_hangup(void *data) check_tty_count(tty, "do_tty_hangup"); file_list_lock(); /* This breaks for file handles being sent over AF_UNIX sockets ? */ - list_for_each_entry(filp, &tty->tty_files, f_list) { + list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { if (filp->f_op->write == redirected_tty_write) cons_filp = filp; if (filp->f_op->write != tty_write) diff --git a/fs/dquot.c b/fs/dquot.c index 05f3327d64a3..ea7644227a65 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -662,7 +662,7 @@ static void add_dquot_ref(struct super_block *sb, int type) restart: file_list_lock(); list_for_each(p, &sb->s_files) { - struct file *filp = list_entry(p, struct file, f_list); + struct file *filp = list_entry(p, struct file, f_u.fu_list); struct inode *inode = filp->f_dentry->d_inode; if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) { struct dentry *dentry = dget(filp->f_dentry); diff --git a/fs/file_table.c b/fs/file_table.c index 86ec8ae985b4..4dc205546547 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -56,13 +56,13 @@ void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags) static inline void file_free_rcu(struct rcu_head *head) { - struct file *f = container_of(head, struct file, f_rcuhead); + struct file *f = container_of(head, struct file, f_u.fu_rcuhead); kmem_cache_free(filp_cachep, f); } static inline void file_free(struct file *f) { - call_rcu(&f->f_rcuhead, file_free_rcu); + call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); } /* Find an unused file structure and return a pointer to it. @@ -95,7 +95,7 @@ struct file *get_empty_filp(void) f->f_gid = current->fsgid; rwlock_init(&f->f_owner.lock); /* f->f_version: 0 */ - INIT_LIST_HEAD(&f->f_list); + INIT_LIST_HEAD(&f->f_u.fu_list); return f; over: @@ -225,15 +225,15 @@ void file_move(struct file *file, struct list_head *list) if (!list) return; file_list_lock(); - list_move(&file->f_list, list); + list_move(&file->f_u.fu_list, list); file_list_unlock(); } void file_kill(struct file *file) { - if (!list_empty(&file->f_list)) { + if (!list_empty(&file->f_u.fu_list)) { file_list_lock(); - list_del_init(&file->f_list); + list_del_init(&file->f_u.fu_list); file_list_unlock(); } } @@ -245,7 +245,7 @@ int fs_may_remount_ro(struct super_block *sb) /* Check that no files are currently opened for writing. */ file_list_lock(); list_for_each(p, &sb->s_files) { - struct file *file = list_entry(p, struct file, f_list); + struct file *file = list_entry(p, struct file, f_u.fu_list); struct inode *inode = file->f_dentry->d_inode; /* File with pending delete? */ diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 8a8c34461d48..b638fb500743 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -533,7 +533,7 @@ static void proc_kill_inodes(struct proc_dir_entry *de) */ file_list_lock(); list_for_each(p, &sb->s_files) { - struct file * filp = list_entry(p, struct file, f_list); + struct file * filp = list_entry(p, struct file, f_u.fu_list); struct dentry * dentry = filp->f_dentry; struct inode * inode; struct file_operations *fops; diff --git a/fs/super.c b/fs/super.c index 6e57ee252e14..f60155ec7780 100644 --- a/fs/super.c +++ b/fs/super.c @@ -513,7 +513,7 @@ static void mark_files_ro(struct super_block *sb) struct file *f; file_list_lock(); - list_for_each_entry(f, &sb->s_files, f_list) { + list_for_each_entry(f, &sb->s_files, f_u.fu_list) { if (S_ISREG(f->f_dentry->d_inode->i_mode) && file_count(f)) f->f_mode &= ~FMODE_WRITE; } diff --git a/include/linux/fs.h b/include/linux/fs.h index f83d997c5582..6d6226732c93 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -574,7 +574,14 @@ struct file_ra_state { #define RA_FLAG_INCACHE 0x02 /* file is already in cache */ struct file { - struct list_head f_list; + /* + * fu_list becomes invalid after file_free is called and queued via + * fu_rcuhead for RCU freeing + */ + union { + struct list_head fu_list; + struct rcu_head fu_rcuhead; + } f_u; struct dentry *f_dentry; struct vfsmount *f_vfsmnt; struct file_operations *f_op; @@ -598,7 +605,6 @@ struct file { spinlock_t f_ep_lock; #endif /* #ifdef CONFIG_EPOLL */ struct address_space *f_mapping; - struct rcu_head f_rcuhead; }; extern spinlock_t files_lock; #define file_list_lock() spin_lock(&files_lock); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d50d7a782cf5..bb62838be496 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1609,7 +1609,7 @@ static inline void flush_unauthorized_files(struct files_struct * files) if (tty) { file_list_lock(); - file = list_entry(tty->tty_files.next, typeof(*file), f_list); + file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list); if (file) { /* Revalidate access to controlling tty. Use inode_has_perm on the tty inode directly rather diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 7a387fec2a0c..fdc382389720 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -914,7 +914,7 @@ static void sel_remove_bools(struct dentry *de) file_list_lock(); list_for_each(p, &sb->s_files) { - struct file * filp = list_entry(p, struct file, f_list); + struct file * filp = list_entry(p, struct file, f_u.fu_list); struct dentry * dentry = filp->f_dentry; if (dentry->d_parent != de) { -- cgit v1.2.3 From b67a1b9e4bf878aa5d4b6b44cb5a251a2f425f0d Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 30 Oct 2005 15:03:44 -0800 Subject: [PATCH] remove hardcoded SEND_SIG_xxx constants This patch replaces hardcoded SEND_SIG_xxx constants with their symbolic names. No changes in affected .o files. Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/exit.c | 10 +++++----- kernel/signal.c | 35 ++++++++++++++++++++--------------- security/selinux/hooks.c | 4 ++-- 3 files changed, 27 insertions(+), 22 deletions(-) (limited to 'security/selinux/hooks.c') diff --git a/kernel/exit.c b/kernel/exit.c index 2d39ccc367e6..537394b25e8d 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -547,7 +547,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced) if (p->pdeath_signal) /* We already hold the tasklist_lock here. */ - group_send_sig_info(p->pdeath_signal, (void *) 0, p); + group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p); /* Move the child from its dying parent to the new one. */ if (unlikely(traced)) { @@ -591,8 +591,8 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced) int pgrp = process_group(p); if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) { - __kill_pg_info(SIGHUP, (void *)1, pgrp); - __kill_pg_info(SIGCONT, (void *)1, pgrp); + __kill_pg_info(SIGHUP, SEND_SIG_PRIV, pgrp); + __kill_pg_info(SIGCONT, SEND_SIG_PRIV, pgrp); } } } @@ -727,8 +727,8 @@ static void exit_notify(struct task_struct *tsk) (t->signal->session == tsk->signal->session) && will_become_orphaned_pgrp(process_group(tsk), tsk) && has_stopped_jobs(process_group(tsk))) { - __kill_pg_info(SIGHUP, (void *)1, process_group(tsk)); - __kill_pg_info(SIGCONT, (void *)1, process_group(tsk)); + __kill_pg_info(SIGHUP, SEND_SIG_PRIV, process_group(tsk)); + __kill_pg_info(SIGCONT, SEND_SIG_PRIV, process_group(tsk)); } /* Let father know we died diff --git a/kernel/signal.c b/kernel/signal.c index 9d1512dcf176..1f7b2aaa4a39 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -651,8 +651,9 @@ static int check_kill_permission(int sig, struct siginfo *info, if (!valid_signal(sig)) return error; error = -EPERM; - if ((!info || ((unsigned long)info != 1 && - (unsigned long)info != 2 && SI_FROMUSER(info))) + if ((info == SEND_SIG_NOINFO || + (info != SEND_SIG_PRIV && info != SEND_SIG_FORCED + && SI_FROMUSER(info))) && ((sig != SIGCONT) || (current->signal->session != t->signal->session)) && (current->euid ^ t->suid) && (current->euid ^ t->uid) @@ -789,7 +790,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, * fast-pathed signals for kernel-internal things like SIGSTOP * or SIGKILL. */ - if ((unsigned long)info == 2) + if (info == SEND_SIG_FORCED) goto out_set; /* Real-time signals must be queued if sent by sigqueue, or @@ -801,19 +802,19 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, pass on the info struct. */ q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN && - ((unsigned long) info < 2 || + (info < SEND_SIG_FORCED || info->si_code >= 0))); if (q) { list_add_tail(&q->list, &signals->list); switch ((unsigned long) info) { - case 0: + case (unsigned long) SEND_SIG_NOINFO: q->info.si_signo = sig; q->info.si_errno = 0; q->info.si_code = SI_USER; q->info.si_pid = current->pid; q->info.si_uid = current->uid; break; - case 1: + case (unsigned long) SEND_SIG_PRIV: q->info.si_signo = sig; q->info.si_errno = 0; q->info.si_code = SI_KERNEL; @@ -825,14 +826,15 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, break; } } else { - if (sig >= SIGRTMIN && info && (unsigned long)info != 1 + if (sig >= SIGRTMIN + && info != SEND_SIG_NOINFO && info != SEND_SIG_PRIV && info->si_code != SI_USER) /* * Queue overflow, abort. We may abort if the signal was rt * and sent by user using something other than kill(). */ return -EAGAIN; - if (((unsigned long)info > 1) && (info->si_code == SI_TIMER)) + if ((info > SEND_SIG_PRIV) && (info->si_code == SI_TIMER)) /* * Set up a return to indicate that we dropped * the signal. @@ -858,7 +860,7 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) BUG(); assert_spin_locked(&t->sighand->siglock); - if (((unsigned long)info > 2) && (info->si_code == SI_TIMER)) + if ((info > SEND_SIG_FORCED) && (info->si_code == SI_TIMER)) /* * Set up a return to indicate that we dropped the signal. */ @@ -914,7 +916,7 @@ force_sig_specific(int sig, struct task_struct *t) t->sighand->action[sig-1].sa.sa_handler = SIG_DFL; sigdelset(&t->blocked, sig); recalc_sigpending_tsk(t); - specific_send_sig_info(sig, (void *)2, t); + specific_send_sig_info(sig, SEND_SIG_FORCED, t); spin_unlock_irqrestore(&t->sighand->siglock, flags); } @@ -1050,7 +1052,7 @@ __group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) assert_spin_locked(&p->sighand->siglock); handle_stop_signal(sig, p); - if (((unsigned long)info > 2) && (info->si_code == SI_TIMER)) + if ((info > SEND_SIG_FORCED) && (info->si_code == SI_TIMER)) /* * Set up a return to indicate that we dropped the signal. */ @@ -1285,10 +1287,13 @@ send_sig_info(int sig, struct siginfo *info, struct task_struct *p) return ret; } +#define __si_special(priv) \ + ((priv) ? SEND_SIG_PRIV : SEND_SIG_NOINFO) + int send_sig(int sig, struct task_struct *p, int priv) { - return send_sig_info(sig, (void*)(long)(priv != 0), p); + return send_sig_info(sig, __si_special(priv), p); } /* @@ -1308,7 +1313,7 @@ send_group_sig_info(int sig, struct siginfo *info, struct task_struct *p) void force_sig(int sig, struct task_struct *p) { - force_sig_info(sig, (void*)1L, p); + force_sig_info(sig, SEND_SIG_PRIV, p); } /* @@ -1333,13 +1338,13 @@ force_sigsegv(int sig, struct task_struct *p) int kill_pg(pid_t pgrp, int sig, int priv) { - return kill_pg_info(sig, (void *)(long)(priv != 0), pgrp); + return kill_pg_info(sig, __si_special(priv), pgrp); } int kill_proc(pid_t pid, int sig, int priv) { - return kill_proc_info(sig, (void *)(long)(priv != 0), pid); + return kill_proc_info(sig, __si_special(priv), pid); } /* diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index bb62838be496..295ac472faf1 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2713,8 +2713,8 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int si if (rc) return rc; - if (info && ((unsigned long)info == 1 || - (unsigned long)info == 2 || SI_FROMKERNEL(info))) + if (info != SEND_SIG_NOINFO && (info == SEND_SIG_PRIV || + info == SEND_SIG_FORCED || SI_FROMKERNEL(info))) return 0; if (!sig) -- cgit v1.2.3 From 621d31219d9a788bda924a0613048053f3f5f211 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 30 Oct 2005 15:03:45 -0800 Subject: [PATCH] cleanup the usage of SEND_SIG_xxx constants This patch simplifies some checks for magic siginfo values. It should not change the behaviour in any way. Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sched.h | 5 +++++ kernel/signal.c | 18 +++++++----------- security/selinux/hooks.c | 3 +-- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'security/selinux/hooks.c') diff --git a/include/linux/sched.h b/include/linux/sched.h index 41285a0e7258..03b68a7b4b82 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1084,6 +1084,11 @@ extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned lon #define SEND_SIG_PRIV ((struct siginfo *) 1) #define SEND_SIG_FORCED ((struct siginfo *) 2) +static inline int is_si_special(const struct siginfo *info) +{ + return info <= SEND_SIG_FORCED; +} + /* True if we are on the alternate signal stack. */ static inline int on_sig_stack(unsigned long sp) diff --git a/kernel/signal.c b/kernel/signal.c index 1f7b2aaa4a39..27533b90c347 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -651,9 +651,7 @@ static int check_kill_permission(int sig, struct siginfo *info, if (!valid_signal(sig)) return error; error = -EPERM; - if ((info == SEND_SIG_NOINFO || - (info != SEND_SIG_PRIV && info != SEND_SIG_FORCED - && SI_FROMUSER(info))) + if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info))) && ((sig != SIGCONT) || (current->signal->session != t->signal->session)) && (current->euid ^ t->suid) && (current->euid ^ t->uid) @@ -802,7 +800,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, pass on the info struct. */ q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN && - (info < SEND_SIG_FORCED || + (is_si_special(info) || info->si_code >= 0))); if (q) { list_add_tail(&q->list, &signals->list); @@ -825,16 +823,14 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, copy_siginfo(&q->info, info); break; } - } else { - if (sig >= SIGRTMIN - && info != SEND_SIG_NOINFO && info != SEND_SIG_PRIV - && info->si_code != SI_USER) + } else if (!is_si_special(info)) { + if (sig >= SIGRTMIN && info->si_code != SI_USER) /* * Queue overflow, abort. We may abort if the signal was rt * and sent by user using something other than kill(). */ return -EAGAIN; - if ((info > SEND_SIG_PRIV) && (info->si_code == SI_TIMER)) + if (info->si_code == SI_TIMER) /* * Set up a return to indicate that we dropped * the signal. @@ -860,7 +856,7 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) BUG(); assert_spin_locked(&t->sighand->siglock); - if ((info > SEND_SIG_FORCED) && (info->si_code == SI_TIMER)) + if (!is_si_special(info) && (info->si_code == SI_TIMER)) /* * Set up a return to indicate that we dropped the signal. */ @@ -1052,7 +1048,7 @@ __group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) assert_spin_locked(&p->sighand->siglock); handle_stop_signal(sig, p); - if ((info > SEND_SIG_FORCED) && (info->si_code == SI_TIMER)) + if (!is_si_special(info) && (info->si_code == SI_TIMER)) /* * Set up a return to indicate that we dropped the signal. */ diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 295ac472faf1..45c41490d521 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2713,8 +2713,7 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int si if (rc) return rc; - if (info != SEND_SIG_NOINFO && (info == SEND_SIG_PRIV || - info == SEND_SIG_FORCED || SI_FROMKERNEL(info))) + if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info))) return 0; if (!sig) -- cgit v1.2.3