Char/Misc fixes for 5.6-rc5
Here are 4 small char/misc driver fixes for reported issues for 5.6-rc5. These fixes are: - binder fix for a potential use-after-free problem found (took 2 tries to get it right) - interconnect core fix - altera-stapl driver fix All 4 of these have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCXmSzSg8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ymzLwCg2CKlHDefZEuCI7d4Pgd5cgknMKgAoLQdQLrO Pza+JqgZ8dSmUg8lyNw7 =3wFd -----END PGP SIGNATURE----- Merge tag 'char-misc-5.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char/misc fixes from Greg KH: "Here are four small char/misc driver fixes for reported issues for 5.6-rc5. These fixes are: - binder fix for a potential use-after-free problem found (took two tries to get it right) - interconnect core fix - altera-stapl driver fix All four of these have been in linux-next for a while with no reported issues" * tag 'char-misc-5.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: binder: prevent UAF for binderfs devices II interconnect: Handle memory allocation errors altera-stapl: altera_get_note: prevent write beyond end of 'key' binder: prevent UAF for binderfs devices
This commit is contained in:
commit
378fee2e6b
|
@ -5228,6 +5228,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
|
|||
binder_dev = container_of(filp->private_data,
|
||||
struct binder_device, miscdev);
|
||||
}
|
||||
refcount_inc(&binder_dev->ref);
|
||||
proc->context = &binder_dev->context;
|
||||
binder_alloc_init(&proc->alloc);
|
||||
|
||||
|
@ -5405,6 +5406,7 @@ static int binder_node_release(struct binder_node *node, int refs)
|
|||
static void binder_deferred_release(struct binder_proc *proc)
|
||||
{
|
||||
struct binder_context *context = proc->context;
|
||||
struct binder_device *device;
|
||||
struct rb_node *n;
|
||||
int threads, nodes, incoming_refs, outgoing_refs, active_transactions;
|
||||
|
||||
|
@ -5421,6 +5423,12 @@ static void binder_deferred_release(struct binder_proc *proc)
|
|||
context->binder_context_mgr_node = NULL;
|
||||
}
|
||||
mutex_unlock(&context->context_mgr_node_lock);
|
||||
device = container_of(proc->context, struct binder_device, context);
|
||||
if (refcount_dec_and_test(&device->ref)) {
|
||||
kfree(context->name);
|
||||
kfree(device);
|
||||
}
|
||||
proc->context = NULL;
|
||||
binder_inner_proc_lock(proc);
|
||||
/*
|
||||
* Make sure proc stays alive after we
|
||||
|
@ -6077,6 +6085,7 @@ static int __init init_binder_device(const char *name)
|
|||
binder_device->miscdev.minor = MISC_DYNAMIC_MINOR;
|
||||
binder_device->miscdev.name = name;
|
||||
|
||||
refcount_set(&binder_device->ref, 1);
|
||||
binder_device->context.binder_context_mgr_uid = INVALID_UID;
|
||||
binder_device->context.name = name;
|
||||
mutex_init(&binder_device->context.context_mgr_node_lock);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/list.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/uidgid.h>
|
||||
|
@ -33,6 +34,7 @@ struct binder_device {
|
|||
struct miscdevice miscdev;
|
||||
struct binder_context context;
|
||||
struct inode *binderfs_inode;
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -154,6 +154,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
|
|||
if (!name)
|
||||
goto err;
|
||||
|
||||
refcount_set(&device->ref, 1);
|
||||
device->binderfs_inode = inode;
|
||||
device->context.binder_context_mgr_uid = INVALID_UID;
|
||||
device->context.name = name;
|
||||
|
@ -257,8 +258,10 @@ static void binderfs_evict_inode(struct inode *inode)
|
|||
ida_free(&binderfs_minors, device->miscdev.minor);
|
||||
mutex_unlock(&binderfs_minors_mutex);
|
||||
|
||||
kfree(device->context.name);
|
||||
kfree(device);
|
||||
if (refcount_dec_and_test(&device->ref)) {
|
||||
kfree(device->context.name);
|
||||
kfree(device);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -445,6 +445,11 @@ struct icc_path *of_icc_get(struct device *dev, const char *name)
|
|||
path->name = kasprintf(GFP_KERNEL, "%s-%s",
|
||||
src_node->name, dst_node->name);
|
||||
|
||||
if (!path->name) {
|
||||
kfree(path);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_icc_get);
|
||||
|
@ -579,6 +584,10 @@ struct icc_path *icc_get(struct device *dev, const int src_id, const int dst_id)
|
|||
}
|
||||
|
||||
path->name = kasprintf(GFP_KERNEL, "%s-%s", src->name, dst->name);
|
||||
if (!path->name) {
|
||||
kfree(path);
|
||||
path = ERR_PTR(-ENOMEM);
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&icc_lock);
|
||||
return path;
|
||||
|
|
|
@ -2112,8 +2112,8 @@ exit_done:
|
|||
return status;
|
||||
}
|
||||
|
||||
static int altera_get_note(u8 *p, s32 program_size,
|
||||
s32 *offset, char *key, char *value, int length)
|
||||
static int altera_get_note(u8 *p, s32 program_size, s32 *offset,
|
||||
char *key, char *value, int keylen, int vallen)
|
||||
/*
|
||||
* Gets key and value of NOTE fields in the JBC file.
|
||||
* Can be called in two modes: if offset pointer is NULL,
|
||||
|
@ -2170,7 +2170,7 @@ static int altera_get_note(u8 *p, s32 program_size,
|
|||
&p[note_table + (8 * i) + 4])];
|
||||
|
||||
if (value != NULL)
|
||||
strlcpy(value, value_ptr, length);
|
||||
strlcpy(value, value_ptr, vallen);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2189,13 +2189,13 @@ static int altera_get_note(u8 *p, s32 program_size,
|
|||
strlcpy(key, &p[note_strings +
|
||||
get_unaligned_be32(
|
||||
&p[note_table + (8 * i)])],
|
||||
length);
|
||||
keylen);
|
||||
|
||||
if (value != NULL)
|
||||
strlcpy(value, &p[note_strings +
|
||||
get_unaligned_be32(
|
||||
&p[note_table + (8 * i) + 4])],
|
||||
length);
|
||||
vallen);
|
||||
|
||||
*offset = i + 1;
|
||||
}
|
||||
|
@ -2449,7 +2449,7 @@ int altera_init(struct altera_config *config, const struct firmware *fw)
|
|||
__func__, (format_version == 2) ? "Jam STAPL" :
|
||||
"pre-standardized Jam 1.1");
|
||||
while (altera_get_note((u8 *)fw->data, fw->size,
|
||||
&offset, key, value, 256) == 0)
|
||||
&offset, key, value, 32, 256) == 0)
|
||||
printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n",
|
||||
__func__, key, value);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue