= NULL;>> +>> +static int caphash_open(struct inode *inode, struct file *filp)>> +{>> + struct caphash_writer *tmp = NULL;>> + struct user_namespace *user_ns = current_user_ns();>> + int retval = 0;>> + struct list_head *pos, *q;>> +>> + /* make sure only one instance per namespace can be opened */>> + mutex_lock(&lock);>> +>> + list_for_each_safe(pos, q, &(caphash_writers)) {>> + tmp = list_entry(pos, struct caphash_writer, list);>> + if (tmp->user_ns == user_ns) {>> + pr_err("already locked in this namespace\n");>+static LIST_HEAD(caphash_writers); >> +>> +static DEFINE_MUTEX(lock);>> +>> +struct crypto_ahash *hmac_tfm
So, evil guy opens the device but does not close it, therefore the
whole service is blocked in a namespace?
In general, I think we should open that device in
kernel_init_freeable() and hand over the fd to init/systemd.
+static int caphash_release(struct inode *inode, struct file *filp)
+{
+ int retval = 0;
+ struct user_namespace *user_ns = current_user_ns();
Why not obtaining the user namespace from the open file?
That way one can close a caphash file hande she never opened.
Think of open, followed by nsenter, ...
+ list_for_each_safe(pos, q, &(caphash_writers)) {
+ tmp = list_entry(pos, struct caphash_entry, list);
list_for_each_entry.
+static ssize_t capuse_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ ssize_t retval = count;
+ char *rand_str, *src_uname, *dst_uname;
+ u8 hashval[SHA1_DIGEST_SIZE] = { 0 };
+ char *cmdbuf;
+
+ if (!(cmdbuf = kzalloc(count, GFP_KERNEL)))
count is unbound, please apply a limit check.
+ {
+ char *walk = cmdbuf;
cmdbuf is toxic, make sure it is at least nul-terminated.
+ if (hmac_tfm)
IS_ERR()? Otherwise you free a error value, if crypto_alloc_ahash() fails.