Skip to content

Commit

Permalink
Merge tag 'char-misc-5.6-rc5' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/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
  • Loading branch information
Linus Torvalds committed Mar 8, 2020
2 parents b34e5c1 + f0fe2c0 commit 378fee2
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 8 deletions.
9 changes: 9 additions & 0 deletions drivers/android/binder.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;

Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions drivers/android/binder_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -33,6 +34,7 @@ struct binder_device {
struct miscdevice miscdev;
struct binder_context context;
struct inode *binderfs_inode;
refcount_t ref;
};

/**
Expand Down
7 changes: 5 additions & 2 deletions drivers/android/binderfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}

/**
Expand Down
9 changes: 9 additions & 0 deletions drivers/interconnect/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
12 changes: 6 additions & 6 deletions drivers/misc/altera-stapl/altera.c
Original file line number Diff line number Diff line change
Expand Up @@ -2112,8 +2112,8 @@ static int altera_execute(struct altera_state *astate,
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,
Expand Down Expand Up @@ -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);

}
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit 378fee2

Please sign in to comment.