From 55643171de7ba429fbf2cb72fb1f2c6f2df0dcf3 Mon Sep 17 00:00:00 2001 From: Ashwin Ganti Date: Tue, 24 Feb 2009 19:48:44 -0800 Subject: Staging: add p9auth driver This is a driver that adds Plan 9 style capability device implementation. From: Ashwin Ganti Signed-off-by: Greg Kroah-Hartman --- drivers/staging/p9auth/p9auth.c | 347 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 347 insertions(+) create mode 100644 drivers/staging/p9auth/p9auth.c (limited to 'drivers/staging/p9auth/p9auth.c') diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c new file mode 100644 index 000000000000..6704d97194a8 --- /dev/null +++ b/drivers/staging/p9auth/p9auth.c @@ -0,0 +1,347 @@ +/* + * Plan 9 style capability device implementation for the Linux Kernel + * + * Copyright 2008, 2009 Ashwin Ganti + * + * Released under the GPLv2 + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "p9auth.h" + +int cap_major = CAP_MAJOR; +int cap_minor = 0; +int cap_nr_devs = CAP_NR_DEVS; +int cap_node_size = CAP_NODE_SIZE; + +module_param(cap_major, int, S_IRUGO); +module_param(cap_minor, int, S_IRUGO); +module_param(cap_nr_devs, int, S_IRUGO); + +MODULE_AUTHOR("Ashwin Ganti"); +MODULE_LICENSE("GPL"); + +struct cap_dev *cap_devices; + +void hexdump(unsigned char *buf, unsigned int len) +{ + while (len--) + printk("%02x", *buf++); + printk("\n"); +} + +int cap_trim(struct cap_dev *dev) +{ + struct cap_node *tmp; + struct list_head *pos, *q; + if (dev->head != NULL) { + list_for_each_safe(pos, q, &(dev->head->list)) { + tmp = list_entry(pos, struct cap_node, list); + list_del(pos); + kfree(tmp); + } + } + return 0; +} + +int cap_open(struct inode *inode, struct file *filp) +{ + struct cap_dev *dev; + dev = container_of(inode->i_cdev, struct cap_dev, cdev); + filp->private_data = dev; + + /* trim to 0 the length of the device if open was write-only */ + if ((filp->f_flags & O_ACCMODE) == O_WRONLY) { + if (down_interruptible(&dev->sem)) + return -ERESTARTSYS; + cap_trim(dev); + up(&dev->sem); + } + /* initialise the head if it is NULL */ + if (dev->head == NULL) { + dev->head = + (struct cap_node *) kmalloc(sizeof(struct cap_node), + GFP_KERNEL); + INIT_LIST_HEAD(&(dev->head->list)); + } + return 0; +} + +int cap_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +ssize_t +cap_write(struct file * filp, const char __user * buf, + size_t count, loff_t * f_pos) +{ + struct cap_node *node_ptr, *tmp; + struct list_head *pos; + struct cap_dev *dev = filp->private_data; + ssize_t retval = -ENOMEM; + int len, target_int, source_int, flag = 0; + char *user_buf, *user_buf_running, *source_user, *target_user, + *rand_str, *hash_str, *result; + + if (down_interruptible(&dev->sem)) + return -ERESTARTSYS; + + node_ptr = + (struct cap_node *) kmalloc(sizeof(struct cap_node), + GFP_KERNEL); + user_buf = (char *) kmalloc(count, GFP_KERNEL); + memset(user_buf, 0, count); + + if (copy_from_user(user_buf, buf, count)) { + retval = -EFAULT; + goto out; + } + + /* If the minor number is 0 ( /dev/caphash ) then simply add the + * hashed capability supplied by the user to the list of hashes + */ + if (0 == iminor(filp->f_dentry->d_inode)) { + printk(KERN_INFO "Capability being written to /dev/caphash : \n"); + hexdump(user_buf, count); + memcpy(node_ptr->data, user_buf, count); + list_add(&(node_ptr->list), &(dev->head->list)); + } else { + /* break the supplied string into tokens with @ as the delimiter + If the string is "user1@user2@randomstring" we need to split it + and hash 'user1@user2' using 'randomstring' as the key + */ + user_buf_running = kstrdup(user_buf, GFP_KERNEL); + source_user = strsep(&user_buf_running, "@"); + target_user = strsep(&user_buf_running, "@"); + rand_str = strsep(&user_buf_running, "@"); + + /* hash the string user1@user2 with rand_str as the key */ + len = strlen(source_user) + strlen(target_user) + 1; + hash_str = (char *) kmalloc(len, GFP_KERNEL); + memset(hash_str, 0, len); + strcat(hash_str, source_user); + strcat(hash_str, "@"); + strcat(hash_str, target_user); + + printk(KERN_ALERT "the source user is %s \n", source_user); + printk(KERN_ALERT "the target user is %s \n", target_user); + + result = + cap_hash(hash_str, len, rand_str, strlen(rand_str)); + if (NULL == result) { + retval = -EFAULT; + goto out; + } + memcpy(node_ptr->data, result, CAP_NODE_SIZE); + /* Change the process's uid if the hash is present in the + * list of hashes + */ + list_for_each(pos, &(cap_devices->head->list)) { + /* Change the user id of the process if the hashes match */ + if (0 == + memcmp(result, + list_entry(pos, struct cap_node, + list)->data, + CAP_NODE_SIZE)) { + target_int = (unsigned int) + simple_strtol(target_user, NULL, 0); + source_int = (unsigned int) + simple_strtol(source_user, NULL, 0); + flag = 1; + + /* Check whether the process writing to capuse is actually owned by + * the source owner + */ + if (source_int != current->uid) { + printk(KERN_ALERT + "Process is not owned by the source user of the capability.\n"); + retval = -EFAULT; + goto out; + } + /* What all id's need to be changed here? uid, euid, fsid, savedids ?? + * Currently I am changing the effective user id + * since most of the authorisation decisions are based on it + */ + current->uid = (uid_t) target_int; + current->euid = (uid_t) target_int; + + /* Remove the capability from the list and break */ + tmp = + list_entry(pos, struct cap_node, list); + list_del(pos); + kfree(tmp); + break; + } + } + if (0 == flag) { + /* The capability is not present in the list of the hashes stored, hence return failure */ + printk(KERN_ALERT + "Invalid capabiliy written to /dev/capuse \n"); + retval = -EFAULT; + goto out; + } + } + *f_pos += count; + retval = count; + /* update the size */ + if (dev->size < *f_pos) + dev->size = *f_pos; + + out: + up(&dev->sem); + return retval; +} + +struct file_operations cap_fops = { + .owner = THIS_MODULE, + .write = cap_write, + .open = cap_open, + .release = cap_release, +}; + + +void cap_cleanup_module(void) +{ + int i; + dev_t devno = MKDEV(cap_major, cap_minor); + if (cap_devices) { + for (i = 0; i < cap_nr_devs; i++) { + cap_trim(cap_devices + i); + cdev_del(&cap_devices[i].cdev); + } + kfree(cap_devices); + } + unregister_chrdev_region(devno, cap_nr_devs); + +} + + +static void cap_setup_cdev(struct cap_dev *dev, int index) +{ + int err, devno = MKDEV(cap_major, cap_minor + index); + cdev_init(&dev->cdev, &cap_fops); + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &cap_fops; + err = cdev_add(&dev->cdev, devno, 1); + if (err) + printk(KERN_NOTICE "Error %d adding cap%d", err, index); +} + + +int cap_init_module(void) +{ + int result, i; + dev_t dev = 0; + + if (cap_major) { + dev = MKDEV(cap_major, cap_minor); + result = register_chrdev_region(dev, cap_nr_devs, "cap"); + } else { + result = alloc_chrdev_region(&dev, cap_minor, cap_nr_devs, + "cap"); + cap_major = MAJOR(dev); + } + + if (result < 0) { + printk(KERN_WARNING "cap: can't get major %d\n", + cap_major); + return result; + } + + cap_devices = + kmalloc(cap_nr_devs * sizeof(struct cap_dev), GFP_KERNEL); + if (!cap_devices) { + result = -ENOMEM; + goto fail; + } + memset(cap_devices, 0, cap_nr_devs * sizeof(struct cap_dev)); + + /* Initialize each device. */ + for (i = 0; i < cap_nr_devs; i++) { + cap_devices[i].node_size = cap_node_size; + init_MUTEX(&cap_devices[i].sem); + cap_setup_cdev(&cap_devices[i], i); + } + + return 0; + + fail: + cap_cleanup_module(); + return result; +} + +module_init(cap_init_module); +module_exit(cap_cleanup_module); + +char *cap_hash(char *plain_text, unsigned int plain_text_size, + char *key, unsigned int key_size) +{ + struct scatterlist sg; + char *result = (char *) kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL); + struct crypto_hash *tfm; + struct hash_desc desc; + int ret; + + tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(tfm)) { + printk("failed to load transform for hmac(sha1): %ld\n", + PTR_ERR(tfm)); + kfree(result); + return NULL; + } + + desc.tfm = tfm; + desc.flags = 0; + + memset(result, 0, MAX_DIGEST_SIZE); + sg_set_buf(&sg, plain_text, plain_text_size); + + ret = crypto_hash_setkey(tfm, key, key_size); + if (ret) { + printk("setkey() failed ret=%d\n", ret); + kfree(result); + result = NULL; + goto out; + } + + ret = crypto_hash_digest(&desc, &sg, plain_text_size, result); + if (ret) { + printk("digest () failed ret=%d\n", ret); + kfree(result); + result = NULL; + goto out; + } + + printk("crypto hash digest size %d\n", + crypto_hash_digestsize(tfm)); + hexdump(result, MAX_DIGEST_SIZE); + + out: + crypto_free_hash(tfm); + return result; +} -- cgit v1.2.3-59-g8ed1b From 5dba0826999683fe39aa8b49480b0e953afd117a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Feb 2009 20:06:34 -0800 Subject: Staging: p9auth: fix credential logic current->uid is no longer allowed in the 2.6.29 kernel, so use the proper credential api to be able to alter the uid and euid values. Note, this now builds properly, hopefully still works properly, would be good for someone to test it out... Cc: Ashwin Ganti Signed-off-by: Greg Kroah-Hartman --- drivers/staging/p9auth/p9auth.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/staging/p9auth/p9auth.c') diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c index 6704d97194a8..4f079faeb8a1 100644 --- a/drivers/staging/p9auth/p9auth.c +++ b/drivers/staging/p9auth/p9auth.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include "p9auth.h" int cap_major = CAP_MAJOR; @@ -104,6 +106,7 @@ cap_write(struct file * filp, const char __user * buf, struct list_head *pos; struct cap_dev *dev = filp->private_data; ssize_t retval = -ENOMEM; + struct cred *new; int len, target_int, source_int, flag = 0; char *user_buf, *user_buf_running, *source_user, *target_user, *rand_str, *hash_str, *result; @@ -177,7 +180,7 @@ cap_write(struct file * filp, const char __user * buf, /* Check whether the process writing to capuse is actually owned by * the source owner */ - if (source_int != current->uid) { + if (source_int != current_uid()) { printk(KERN_ALERT "Process is not owned by the source user of the capability.\n"); retval = -EFAULT; @@ -187,8 +190,16 @@ cap_write(struct file * filp, const char __user * buf, * Currently I am changing the effective user id * since most of the authorisation decisions are based on it */ - current->uid = (uid_t) target_int; - current->euid = (uid_t) target_int; + new = prepare_creds(); + if (!new) { + retval = -ENOMEM; + goto out; + } + new->uid = (uid_t) target_int; + new->euid = (uid_t) target_int; + retval = commit_creds(new); + if (retval) + goto out; /* Remove the capability from the list and break */ tmp = -- cgit v1.2.3-59-g8ed1b From 4bf0438332d5173836fdc2d6471fec526d0a14a8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Feb 2009 20:11:39 -0800 Subject: Staging: p9auth: remove unneeded header file The p9auth.h file is not needed, move the stuff into p9auth.c file and delete it. Cc: Ashwin Ganti Signed-off-by: Greg Kroah-Hartman --- drivers/staging/p9auth/p9auth.c | 33 ++++++++++++++++++++++++++++++++- drivers/staging/p9auth/p9auth.h | 35 ----------------------------------- 2 files changed, 32 insertions(+), 36 deletions(-) delete mode 100644 drivers/staging/p9auth/p9auth.h (limited to 'drivers/staging/p9auth/p9auth.c') diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c index 4f079faeb8a1..5824c7f88cca 100644 --- a/drivers/staging/p9auth/p9auth.c +++ b/drivers/staging/p9auth/p9auth.c @@ -33,7 +33,38 @@ #include #include #include -#include "p9auth.h" + +#ifndef CAP_MAJOR +#define CAP_MAJOR 0 +#endif + +#ifndef CAP_NR_DEVS +#define CAP_NR_DEVS 2 /* caphash and capuse */ +#endif + +#ifndef CAP_NODE_SIZE +#define CAP_NODE_SIZE 20 +#endif + +#define MAX_DIGEST_SIZE 20 + +struct cap_node { + char data[CAP_NODE_SIZE]; + struct list_head list; +}; + +struct cap_dev { + struct cap_node *head; + int node_size; + unsigned long size; + struct semaphore sem; + struct cdev cdev; +}; + +int cap_trim(struct cap_dev *); +ssize_t cap_write(struct file *, const char __user *, size_t, loff_t *); +char *cap_hash(char *plain_text, unsigned int plain_text_size, char *key, unsigned int key_size); +void hex_dump(unsigned char * buf, unsigned int len); int cap_major = CAP_MAJOR; int cap_minor = 0; diff --git a/drivers/staging/p9auth/p9auth.h b/drivers/staging/p9auth/p9auth.h deleted file mode 100644 index 285d1d8c9176..000000000000 --- a/drivers/staging/p9auth/p9auth.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef CAP_MAJOR -#define CAP_MAJOR 0 -#endif - -#ifndef CAP_NR_DEVS -#define CAP_NR_DEVS 2 /* caphash and capuse */ -#endif - -#ifndef CAP_NODE_SIZE -#define CAP_NODE_SIZE 20 -#endif - -#define MAX_DIGEST_SIZE 20 - -struct cap_node { - char data[CAP_NODE_SIZE]; - struct list_head list; -}; - -struct cap_dev { - struct cap_node *head; - int node_size; - unsigned long size; - struct semaphore sem; - struct cdev cdev; -}; - -extern int cap_major; -extern int cap_nr_devs; -extern int cap_node_size; - -int cap_trim(struct cap_dev *); -ssize_t cap_write(struct file *, const char __user *, size_t, loff_t *); -char *cap_hash(char *plain_text, unsigned int plain_text_size, char *key, unsigned int key_size); -void hex_dump(unsigned char * buf, unsigned int len); -- cgit v1.2.3-59-g8ed1b From 77dc1139f4a125d46e03fdbb3ac8ab8737ab67d6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Feb 2009 20:21:55 -0800 Subject: Staging: p9auth: fix up codingstyle issues This fixes up a number of scripts/codingstyle.pl warnings and errors Cc: Ashwin Ganti Signed-off-by: Greg Kroah-Hartman --- drivers/staging/p9auth/p9auth.c | 90 ++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 41 deletions(-) (limited to 'drivers/staging/p9auth/p9auth.c') diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c index 5824c7f88cca..c1e5bc4f30ae 100644 --- a/drivers/staging/p9auth/p9auth.c +++ b/drivers/staging/p9auth/p9auth.c @@ -18,8 +18,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -33,6 +32,7 @@ #include #include #include +#include #ifndef CAP_MAJOR #define CAP_MAJOR 0 @@ -61,13 +61,11 @@ struct cap_dev { struct cdev cdev; }; -int cap_trim(struct cap_dev *); -ssize_t cap_write(struct file *, const char __user *, size_t, loff_t *); -char *cap_hash(char *plain_text, unsigned int plain_text_size, char *key, unsigned int key_size); -void hex_dump(unsigned char * buf, unsigned int len); +char *cap_hash(char *plain_text, unsigned int plain_text_size, char *key, + unsigned int key_size); int cap_major = CAP_MAJOR; -int cap_minor = 0; +int cap_minor; int cap_nr_devs = CAP_NR_DEVS; int cap_node_size = CAP_NODE_SIZE; @@ -116,9 +114,7 @@ int cap_open(struct inode *inode, struct file *filp) } /* initialise the head if it is NULL */ if (dev->head == NULL) { - dev->head = - (struct cap_node *) kmalloc(sizeof(struct cap_node), - GFP_KERNEL); + dev->head = kmalloc(sizeof(struct cap_node), GFP_KERNEL); INIT_LIST_HEAD(&(dev->head->list)); } return 0; @@ -129,9 +125,8 @@ int cap_release(struct inode *inode, struct file *filp) return 0; } -ssize_t -cap_write(struct file * filp, const char __user * buf, - size_t count, loff_t * f_pos) +ssize_t cap_write(struct file *filp, const char __user *buf, size_t count, + loff_t *f_pos) { struct cap_node *node_ptr, *tmp; struct list_head *pos; @@ -145,10 +140,8 @@ cap_write(struct file * filp, const char __user * buf, if (down_interruptible(&dev->sem)) return -ERESTARTSYS; - node_ptr = - (struct cap_node *) kmalloc(sizeof(struct cap_node), - GFP_KERNEL); - user_buf = (char *) kmalloc(count, GFP_KERNEL); + node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL); + user_buf = kmalloc(count, GFP_KERNEL); memset(user_buf, 0, count); if (copy_from_user(user_buf, buf, count)) { @@ -156,7 +149,8 @@ cap_write(struct file * filp, const char __user * buf, goto out; } - /* If the minor number is 0 ( /dev/caphash ) then simply add the + /* + * If the minor number is 0 ( /dev/caphash ) then simply add the * hashed capability supplied by the user to the list of hashes */ if (0 == iminor(filp->f_dentry->d_inode)) { @@ -165,9 +159,11 @@ cap_write(struct file * filp, const char __user * buf, memcpy(node_ptr->data, user_buf, count); list_add(&(node_ptr->list), &(dev->head->list)); } else { - /* break the supplied string into tokens with @ as the delimiter - If the string is "user1@user2@randomstring" we need to split it - and hash 'user1@user2' using 'randomstring' as the key + /* + * break the supplied string into tokens with @ as the + * delimiter If the string is "user1@user2@randomstring" we + * need to split it and hash 'user1@user2' using 'randomstring' + * as the key. */ user_buf_running = kstrdup(user_buf, GFP_KERNEL); source_user = strsep(&user_buf_running, "@"); @@ -176,7 +172,7 @@ cap_write(struct file * filp, const char __user * buf, /* hash the string user1@user2 with rand_str as the key */ len = strlen(source_user) + strlen(target_user) + 1; - hash_str = (char *) kmalloc(len, GFP_KERNEL); + hash_str = kmalloc(len, GFP_KERNEL); memset(hash_str, 0, len); strcat(hash_str, source_user); strcat(hash_str, "@"); @@ -196,7 +192,10 @@ cap_write(struct file * filp, const char __user * buf, * list of hashes */ list_for_each(pos, &(cap_devices->head->list)) { - /* Change the user id of the process if the hashes match */ + /* + * Change the user id of the process if the hashes + * match + */ if (0 == memcmp(result, list_entry(pos, struct cap_node, @@ -208,8 +207,9 @@ cap_write(struct file * filp, const char __user * buf, simple_strtol(source_user, NULL, 0); flag = 1; - /* Check whether the process writing to capuse is actually owned by - * the source owner + /* + * Check whether the process writing to capuse + * is actually owned by the source owner */ if (source_int != current_uid()) { printk(KERN_ALERT @@ -217,9 +217,11 @@ cap_write(struct file * filp, const char __user * buf, retval = -EFAULT; goto out; } - /* What all id's need to be changed here? uid, euid, fsid, savedids ?? - * Currently I am changing the effective user id - * since most of the authorisation decisions are based on it + /* + * What all id's need to be changed here? uid, + * euid, fsid, savedids ?? Currently I am + * changing the effective user id since most of + * the authorisation decisions are based on it */ new = prepare_creds(); if (!new) { @@ -232,16 +234,21 @@ cap_write(struct file * filp, const char __user * buf, if (retval) goto out; - /* Remove the capability from the list and break */ - tmp = - list_entry(pos, struct cap_node, list); + /* + * Remove the capability from the list and + * break + */ + tmp = list_entry(pos, struct cap_node, list); list_del(pos); kfree(tmp); break; } } if (0 == flag) { - /* The capability is not present in the list of the hashes stored, hence return failure */ + /* + * The capability is not present in the list of the + * hashes stored, hence return failure + */ printk(KERN_ALERT "Invalid capabiliy written to /dev/capuse \n"); retval = -EFAULT; @@ -254,12 +261,12 @@ cap_write(struct file * filp, const char __user * buf, if (dev->size < *f_pos) dev->size = *f_pos; - out: +out: up(&dev->sem); return retval; } -struct file_operations cap_fops = { +const struct file_operations cap_fops = { .owner = THIS_MODULE, .write = cap_write, .open = cap_open, @@ -332,7 +339,7 @@ int cap_init_module(void) return 0; - fail: +fail: cap_cleanup_module(); return result; } @@ -344,14 +351,15 @@ char *cap_hash(char *plain_text, unsigned int plain_text_size, char *key, unsigned int key_size) { struct scatterlist sg; - char *result = (char *) kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL); + char *result = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL); struct crypto_hash *tfm; struct hash_desc desc; int ret; tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { - printk("failed to load transform for hmac(sha1): %ld\n", + printk(KERN_ERR + "failed to load transform for hmac(sha1): %ld\n", PTR_ERR(tfm)); kfree(result); return NULL; @@ -365,7 +373,7 @@ char *cap_hash(char *plain_text, unsigned int plain_text_size, ret = crypto_hash_setkey(tfm, key, key_size); if (ret) { - printk("setkey() failed ret=%d\n", ret); + printk(KERN_ERR "setkey() failed ret=%d\n", ret); kfree(result); result = NULL; goto out; @@ -373,17 +381,17 @@ char *cap_hash(char *plain_text, unsigned int plain_text_size, ret = crypto_hash_digest(&desc, &sg, plain_text_size, result); if (ret) { - printk("digest () failed ret=%d\n", ret); + printk(KERN_ERR "digest () failed ret=%d\n", ret); kfree(result); result = NULL; goto out; } - printk("crypto hash digest size %d\n", + printk(KERN_DEBUG "crypto hash digest size %d\n", crypto_hash_digestsize(tfm)); hexdump(result, MAX_DIGEST_SIZE); - out: +out: crypto_free_hash(tfm); return result; } -- cgit v1.2.3-59-g8ed1b From 0f386e2b4c6109164e82277513a9570fc9ec644c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Feb 2009 20:25:02 -0800 Subject: Staging: p9auth: fix up sparse warnings Everything needs to be static, as sparse complains and you don't want to polute the global kernel symbol namespace. So mark everything as such and move one function around to prevent a forward declaration from being needed. Cc: Ashwin Ganti Signed-off-by: Greg Kroah-Hartman --- drivers/staging/p9auth/p9auth.c | 133 +++++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 69 deletions(-) (limited to 'drivers/staging/p9auth/p9auth.c') diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c index c1e5bc4f30ae..a6078bb813cb 100644 --- a/drivers/staging/p9auth/p9auth.c +++ b/drivers/staging/p9auth/p9auth.c @@ -61,13 +61,10 @@ struct cap_dev { struct cdev cdev; }; -char *cap_hash(char *plain_text, unsigned int plain_text_size, char *key, - unsigned int key_size); - -int cap_major = CAP_MAJOR; -int cap_minor; -int cap_nr_devs = CAP_NR_DEVS; -int cap_node_size = CAP_NODE_SIZE; +static int cap_major = CAP_MAJOR; +static int cap_minor; +static int cap_nr_devs = CAP_NR_DEVS; +static int cap_node_size = CAP_NODE_SIZE; module_param(cap_major, int, S_IRUGO); module_param(cap_minor, int, S_IRUGO); @@ -76,16 +73,65 @@ module_param(cap_nr_devs, int, S_IRUGO); MODULE_AUTHOR("Ashwin Ganti"); MODULE_LICENSE("GPL"); -struct cap_dev *cap_devices; +static struct cap_dev *cap_devices; -void hexdump(unsigned char *buf, unsigned int len) +static void hexdump(unsigned char *buf, unsigned int len) { while (len--) printk("%02x", *buf++); printk("\n"); } -int cap_trim(struct cap_dev *dev) +static char *cap_hash(char *plain_text, unsigned int plain_text_size, + char *key, unsigned int key_size) +{ + struct scatterlist sg; + char *result = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL); + struct crypto_hash *tfm; + struct hash_desc desc; + int ret; + + tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(tfm)) { + printk(KERN_ERR + "failed to load transform for hmac(sha1): %ld\n", + PTR_ERR(tfm)); + kfree(result); + return NULL; + } + + desc.tfm = tfm; + desc.flags = 0; + + memset(result, 0, MAX_DIGEST_SIZE); + sg_set_buf(&sg, plain_text, plain_text_size); + + ret = crypto_hash_setkey(tfm, key, key_size); + if (ret) { + printk(KERN_ERR "setkey() failed ret=%d\n", ret); + kfree(result); + result = NULL; + goto out; + } + + ret = crypto_hash_digest(&desc, &sg, plain_text_size, result); + if (ret) { + printk(KERN_ERR "digest () failed ret=%d\n", ret); + kfree(result); + result = NULL; + goto out; + } + + printk(KERN_DEBUG "crypto hash digest size %d\n", + crypto_hash_digestsize(tfm)); + hexdump(result, MAX_DIGEST_SIZE); + +out: + crypto_free_hash(tfm); + return result; +} + +static int cap_trim(struct cap_dev *dev) { struct cap_node *tmp; struct list_head *pos, *q; @@ -99,7 +145,7 @@ int cap_trim(struct cap_dev *dev) return 0; } -int cap_open(struct inode *inode, struct file *filp) +static int cap_open(struct inode *inode, struct file *filp) { struct cap_dev *dev; dev = container_of(inode->i_cdev, struct cap_dev, cdev); @@ -120,13 +166,13 @@ int cap_open(struct inode *inode, struct file *filp) return 0; } -int cap_release(struct inode *inode, struct file *filp) +static int cap_release(struct inode *inode, struct file *filp) { return 0; } -ssize_t cap_write(struct file *filp, const char __user *buf, size_t count, - loff_t *f_pos) +static ssize_t cap_write(struct file *filp, const char __user *buf, + size_t count, loff_t *f_pos) { struct cap_node *node_ptr, *tmp; struct list_head *pos; @@ -181,8 +227,7 @@ ssize_t cap_write(struct file *filp, const char __user *buf, size_t count, printk(KERN_ALERT "the source user is %s \n", source_user); printk(KERN_ALERT "the target user is %s \n", target_user); - result = - cap_hash(hash_str, len, rand_str, strlen(rand_str)); + result = cap_hash(hash_str, len, rand_str, strlen(rand_str)); if (NULL == result) { retval = -EFAULT; goto out; @@ -266,15 +311,14 @@ out: return retval; } -const struct file_operations cap_fops = { +static const struct file_operations cap_fops = { .owner = THIS_MODULE, .write = cap_write, .open = cap_open, .release = cap_release, }; - -void cap_cleanup_module(void) +static void cap_cleanup_module(void) { int i; dev_t devno = MKDEV(cap_major, cap_minor); @@ -289,7 +333,6 @@ void cap_cleanup_module(void) } - static void cap_setup_cdev(struct cap_dev *dev, int index) { int err, devno = MKDEV(cap_major, cap_minor + index); @@ -301,8 +344,7 @@ static void cap_setup_cdev(struct cap_dev *dev, int index) printk(KERN_NOTICE "Error %d adding cap%d", err, index); } - -int cap_init_module(void) +static int cap_init_module(void) { int result, i; dev_t dev = 0; @@ -347,51 +389,4 @@ fail: module_init(cap_init_module); module_exit(cap_cleanup_module); -char *cap_hash(char *plain_text, unsigned int plain_text_size, - char *key, unsigned int key_size) -{ - struct scatterlist sg; - char *result = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL); - struct crypto_hash *tfm; - struct hash_desc desc; - int ret; - - tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) { - printk(KERN_ERR - "failed to load transform for hmac(sha1): %ld\n", - PTR_ERR(tfm)); - kfree(result); - return NULL; - } - - desc.tfm = tfm; - desc.flags = 0; - - memset(result, 0, MAX_DIGEST_SIZE); - sg_set_buf(&sg, plain_text, plain_text_size); - - ret = crypto_hash_setkey(tfm, key, key_size); - if (ret) { - printk(KERN_ERR "setkey() failed ret=%d\n", ret); - kfree(result); - result = NULL; - goto out; - } - - ret = crypto_hash_digest(&desc, &sg, plain_text_size, result); - if (ret) { - printk(KERN_ERR "digest () failed ret=%d\n", ret); - kfree(result); - result = NULL; - goto out; - } - - printk(KERN_DEBUG "crypto hash digest size %d\n", - crypto_hash_digestsize(tfm)); - hexdump(result, MAX_DIGEST_SIZE); -out: - crypto_free_hash(tfm); - return result; -} -- cgit v1.2.3-59-g8ed1b From 6d0d63bd7a9c0a6373c7759cb55580b806269dae Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Feb 2009 20:31:39 -0800 Subject: Staging: p9auth: use kzalloc It's nicer than doing kmalloc/memset. Also check the return value of all allocations, one was previously not being checked properly. Cc: Ashwin Ganti Signed-off-by: Greg Kroah-Hartman --- drivers/staging/p9auth/p9auth.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers/staging/p9auth/p9auth.c') diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c index a6078bb813cb..e2a8753ecd0c 100644 --- a/drivers/staging/p9auth/p9auth.c +++ b/drivers/staging/p9auth/p9auth.c @@ -86,7 +86,7 @@ static char *cap_hash(char *plain_text, unsigned int plain_text_size, char *key, unsigned int key_size) { struct scatterlist sg; - char *result = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL); + char *result; struct crypto_hash *tfm; struct hash_desc desc; int ret; @@ -96,14 +96,18 @@ static char *cap_hash(char *plain_text, unsigned int plain_text_size, printk(KERN_ERR "failed to load transform for hmac(sha1): %ld\n", PTR_ERR(tfm)); - kfree(result); return NULL; } desc.tfm = tfm; desc.flags = 0; - memset(result, 0, MAX_DIGEST_SIZE); + result = kzalloc(MAX_DIGEST_SIZE, GFP_KERNEL); + if (!result) { + printk(KERN_ERR "out of memory!\n"); + goto out; + } + sg_set_buf(&sg, plain_text, plain_text_size); ret = crypto_hash_setkey(tfm, key, key_size); @@ -187,8 +191,7 @@ static ssize_t cap_write(struct file *filp, const char __user *buf, return -ERESTARTSYS; node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL); - user_buf = kmalloc(count, GFP_KERNEL); - memset(user_buf, 0, count); + user_buf = kzalloc(count, GFP_KERNEL); if (copy_from_user(user_buf, buf, count)) { retval = -EFAULT; @@ -218,8 +221,7 @@ static ssize_t cap_write(struct file *filp, const char __user *buf, /* hash the string user1@user2 with rand_str as the key */ len = strlen(source_user) + strlen(target_user) + 1; - hash_str = kmalloc(len, GFP_KERNEL); - memset(hash_str, 0, len); + hash_str = kzalloc(len, GFP_KERNEL); strcat(hash_str, source_user); strcat(hash_str, "@"); strcat(hash_str, target_user); @@ -364,13 +366,12 @@ static int cap_init_module(void) return result; } - cap_devices = - kmalloc(cap_nr_devs * sizeof(struct cap_dev), GFP_KERNEL); + cap_devices = kzalloc(cap_nr_devs * sizeof(struct cap_dev), + GFP_KERNEL); if (!cap_devices) { result = -ENOMEM; goto fail; } - memset(cap_devices, 0, cap_nr_devs * sizeof(struct cap_dev)); /* Initialize each device. */ for (i = 0; i < cap_nr_devs; i++) { -- cgit v1.2.3-59-g8ed1b From 2418a628ff9d1cfc4fecd9899f915326ff6e7b96 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Feb 2009 20:37:55 -0800 Subject: Staging: p9auth: clean up #includes Not all of these files needed to be included, clean up the list. Cc: Ashwin Ganti Signed-off-by: Greg Kroah-Hartman --- drivers/staging/p9auth/p9auth.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers/staging/p9auth/p9auth.c') diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c index e2a8753ecd0c..3cac89b26faf 100644 --- a/drivers/staging/p9auth/p9auth.c +++ b/drivers/staging/p9auth/p9auth.c @@ -6,33 +6,23 @@ * Released under the GPLv2 * */ -#include -#include #include #include +#include #include #include #include -#include -#include #include #include -#include #include #include -#include #include #include #include #include -#include -#include -#include #include -#include #include #include -#include #ifndef CAP_MAJOR #define CAP_MAJOR 0 -- cgit v1.2.3-59-g8ed1b