Skip to content

Commit 378fee2

Browse files
committed
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
2 parents b34e5c1 + f0fe2c0 commit 378fee2

File tree

5 files changed

+31
-8
lines changed

5 files changed

+31
-8
lines changed

drivers/android/binder.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5228,6 +5228,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
52285228
binder_dev = container_of(filp->private_data,
52295229
struct binder_device, miscdev);
52305230
}
5231+
refcount_inc(&binder_dev->ref);
52315232
proc->context = &binder_dev->context;
52325233
binder_alloc_init(&proc->alloc);
52335234

@@ -5405,6 +5406,7 @@ static int binder_node_release(struct binder_node *node, int refs)
54055406
static void binder_deferred_release(struct binder_proc *proc)
54065407
{
54075408
struct binder_context *context = proc->context;
5409+
struct binder_device *device;
54085410
struct rb_node *n;
54095411
int threads, nodes, incoming_refs, outgoing_refs, active_transactions;
54105412

@@ -5421,6 +5423,12 @@ static void binder_deferred_release(struct binder_proc *proc)
54215423
context->binder_context_mgr_node = NULL;
54225424
}
54235425
mutex_unlock(&context->context_mgr_node_lock);
5426+
device = container_of(proc->context, struct binder_device, context);
5427+
if (refcount_dec_and_test(&device->ref)) {
5428+
kfree(context->name);
5429+
kfree(device);
5430+
}
5431+
proc->context = NULL;
54245432
binder_inner_proc_lock(proc);
54255433
/*
54265434
* Make sure proc stays alive after we
@@ -6077,6 +6085,7 @@ static int __init init_binder_device(const char *name)
60776085
binder_device->miscdev.minor = MISC_DYNAMIC_MINOR;
60786086
binder_device->miscdev.name = name;
60796087

6088+
refcount_set(&binder_device->ref, 1);
60806089
binder_device->context.binder_context_mgr_uid = INVALID_UID;
60816090
binder_device->context.name = name;
60826091
mutex_init(&binder_device->context.context_mgr_node_lock);

drivers/android/binder_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/list.h>
99
#include <linux/miscdevice.h>
1010
#include <linux/mutex.h>
11+
#include <linux/refcount.h>
1112
#include <linux/stddef.h>
1213
#include <linux/types.h>
1314
#include <linux/uidgid.h>
@@ -33,6 +34,7 @@ struct binder_device {
3334
struct miscdevice miscdev;
3435
struct binder_context context;
3536
struct inode *binderfs_inode;
37+
refcount_t ref;
3638
};
3739

3840
/**

drivers/android/binderfs.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
154154
if (!name)
155155
goto err;
156156

157+
refcount_set(&device->ref, 1);
157158
device->binderfs_inode = inode;
158159
device->context.binder_context_mgr_uid = INVALID_UID;
159160
device->context.name = name;
@@ -257,8 +258,10 @@ static void binderfs_evict_inode(struct inode *inode)
257258
ida_free(&binderfs_minors, device->miscdev.minor);
258259
mutex_unlock(&binderfs_minors_mutex);
259260

260-
kfree(device->context.name);
261-
kfree(device);
261+
if (refcount_dec_and_test(&device->ref)) {
262+
kfree(device->context.name);
263+
kfree(device);
264+
}
262265
}
263266

264267
/**

drivers/interconnect/core.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,11 @@ struct icc_path *of_icc_get(struct device *dev, const char *name)
445445
path->name = kasprintf(GFP_KERNEL, "%s-%s",
446446
src_node->name, dst_node->name);
447447

448+
if (!path->name) {
449+
kfree(path);
450+
return ERR_PTR(-ENOMEM);
451+
}
452+
448453
return path;
449454
}
450455
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)
579584
}
580585

581586
path->name = kasprintf(GFP_KERNEL, "%s-%s", src->name, dst->name);
587+
if (!path->name) {
588+
kfree(path);
589+
path = ERR_PTR(-ENOMEM);
590+
}
582591
out:
583592
mutex_unlock(&icc_lock);
584593
return path;

drivers/misc/altera-stapl/altera.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,8 +2112,8 @@ static int altera_execute(struct altera_state *astate,
21122112
return status;
21132113
}
21142114

2115-
static int altera_get_note(u8 *p, s32 program_size,
2116-
s32 *offset, char *key, char *value, int length)
2115+
static int altera_get_note(u8 *p, s32 program_size, s32 *offset,
2116+
char *key, char *value, int keylen, int vallen)
21172117
/*
21182118
* Gets key and value of NOTE fields in the JBC file.
21192119
* 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,
21702170
&p[note_table + (8 * i) + 4])];
21712171

21722172
if (value != NULL)
2173-
strlcpy(value, value_ptr, length);
2173+
strlcpy(value, value_ptr, vallen);
21742174

21752175
}
21762176
}
@@ -2189,13 +2189,13 @@ static int altera_get_note(u8 *p, s32 program_size,
21892189
strlcpy(key, &p[note_strings +
21902190
get_unaligned_be32(
21912191
&p[note_table + (8 * i)])],
2192-
length);
2192+
keylen);
21932193

21942194
if (value != NULL)
21952195
strlcpy(value, &p[note_strings +
21962196
get_unaligned_be32(
21972197
&p[note_table + (8 * i) + 4])],
2198-
length);
2198+
vallen);
21992199

22002200
*offset = i + 1;
22012201
}
@@ -2449,7 +2449,7 @@ int altera_init(struct altera_config *config, const struct firmware *fw)
24492449
__func__, (format_version == 2) ? "Jam STAPL" :
24502450
"pre-standardized Jam 1.1");
24512451
while (altera_get_note((u8 *)fw->data, fw->size,
2452-
&offset, key, value, 256) == 0)
2452+
&offset, key, value, 32, 256) == 0)
24532453
printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n",
24542454
__func__, key, value);
24552455
}

0 commit comments

Comments
 (0)