Commit feba3900cabb8e7c87368faa28e7a6936809ba22

Authored by Martijn Coenen
Committed by Greg Kroah-Hartman
1 parent 8fa8bea728

binder: Split flat_binder_object

flat_binder_object is used for both handling
binder objects and file descriptors, even though
the two are mostly independent. Since we'll
have more fixup objects in binder in the future,
instead of extending flat_binder_object again,
split out file descriptors to their own object
while retaining backwards compatibility to
existing user-space clients. All binder objects
just share a header.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Martijn Coenen <maco@google.com>
Cc: Arve Hjønnevåg <arve@android.com>
Cc: Amit Pundir <amit.pundir@linaro.org>
Cc: Serban Constantinescu <serban.constantinescu@arm.com>
Cc: Dmitry Shmidt <dimitrysh@google.com>
Cc: Rom Lemarchand <romlem@google.com>
Cc: Android Kernel Team <kernel-team@android.com>
Signed-off-by: Martijn Coenen <maco@google.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 2 changed files with 137 additions and 52 deletions Side-by-side Diff

drivers/android/binder.c
... ... @@ -145,6 +145,11 @@
145 145 binder_stop_on_user_error = 2; \
146 146 } while (0)
147 147  
  148 +#define to_flat_binder_object(hdr) \
  149 + container_of(hdr, struct flat_binder_object, hdr)
  150 +
  151 +#define to_binder_fd_object(hdr) container_of(hdr, struct binder_fd_object, hdr)
  152 +
148 153 enum binder_stat_types {
149 154 BINDER_STAT_PROC,
150 155 BINDER_STAT_THREAD,
... ... @@ -1240,6 +1245,47 @@
1240 1245 }
1241 1246 }
1242 1247  
  1248 +/**
  1249 + * binder_validate_object() - checks for a valid metadata object in a buffer.
  1250 + * @buffer: binder_buffer that we're parsing.
  1251 + * @offset: offset in the buffer at which to validate an object.
  1252 + *
  1253 + * Return: If there's a valid metadata object at @offset in @buffer, the
  1254 + * size of that object. Otherwise, it returns zero.
  1255 + */
  1256 +static size_t binder_validate_object(struct binder_buffer *buffer, u64 offset)
  1257 +{
  1258 + /* Check if we can read a header first */
  1259 + struct binder_object_header *hdr;
  1260 + size_t object_size = 0;
  1261 +
  1262 + if (offset > buffer->data_size - sizeof(*hdr) ||
  1263 + buffer->data_size < sizeof(*hdr) ||
  1264 + !IS_ALIGNED(offset, sizeof(u32)))
  1265 + return 0;
  1266 +
  1267 + /* Ok, now see if we can read a complete object. */
  1268 + hdr = (struct binder_object_header *)(buffer->data + offset);
  1269 + switch (hdr->type) {
  1270 + case BINDER_TYPE_BINDER:
  1271 + case BINDER_TYPE_WEAK_BINDER:
  1272 + case BINDER_TYPE_HANDLE:
  1273 + case BINDER_TYPE_WEAK_HANDLE:
  1274 + object_size = sizeof(struct flat_binder_object);
  1275 + break;
  1276 + case BINDER_TYPE_FD:
  1277 + object_size = sizeof(struct binder_fd_object);
  1278 + break;
  1279 + default:
  1280 + return 0;
  1281 + }
  1282 + if (offset <= buffer->data_size - object_size &&
  1283 + buffer->data_size >= object_size)
  1284 + return object_size;
  1285 + else
  1286 + return 0;
  1287 +}
  1288 +
1243 1289 static void binder_transaction_buffer_release(struct binder_proc *proc,
1244 1290 struct binder_buffer *buffer,
1245 1291 binder_size_t *failed_at)
1246 1292  
1247 1293  
1248 1294  
1249 1295  
... ... @@ -1262,21 +1308,23 @@
1262 1308 else
1263 1309 off_end = (void *)offp + buffer->offsets_size;
1264 1310 for (; offp < off_end; offp++) {
1265   - struct flat_binder_object *fp;
  1311 + struct binder_object_header *hdr;
  1312 + size_t object_size = binder_validate_object(buffer, *offp);
1266 1313  
1267   - if (*offp > buffer->data_size - sizeof(*fp) ||
1268   - buffer->data_size < sizeof(*fp) ||
1269   - !IS_ALIGNED(*offp, sizeof(u32))) {
1270   - pr_err("transaction release %d bad offset %lld, size %zd\n",
  1314 + if (object_size == 0) {
  1315 + pr_err("transaction release %d bad object at offset %lld, size %zd\n",
1271 1316 debug_id, (u64)*offp, buffer->data_size);
1272 1317 continue;
1273 1318 }
1274   - fp = (struct flat_binder_object *)(buffer->data + *offp);
1275   - switch (fp->type) {
  1319 + hdr = (struct binder_object_header *)(buffer->data + *offp);
  1320 + switch (hdr->type) {
1276 1321 case BINDER_TYPE_BINDER:
1277 1322 case BINDER_TYPE_WEAK_BINDER: {
1278   - struct binder_node *node = binder_get_node(proc, fp->binder);
  1323 + struct flat_binder_object *fp;
  1324 + struct binder_node *node;
1279 1325  
  1326 + fp = to_flat_binder_object(hdr);
  1327 + node = binder_get_node(proc, fp->binder);
1280 1328 if (node == NULL) {
1281 1329 pr_err("transaction release %d bad node %016llx\n",
1282 1330 debug_id, (u64)fp->binder);
1283 1331  
1284 1332  
1285 1333  
... ... @@ -1285,15 +1333,17 @@
1285 1333 binder_debug(BINDER_DEBUG_TRANSACTION,
1286 1334 " node %d u%016llx\n",
1287 1335 node->debug_id, (u64)node->ptr);
1288   - binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0);
  1336 + binder_dec_node(node, hdr->type == BINDER_TYPE_BINDER,
  1337 + 0);
1289 1338 } break;
1290 1339 case BINDER_TYPE_HANDLE:
1291 1340 case BINDER_TYPE_WEAK_HANDLE: {
  1341 + struct flat_binder_object *fp;
1292 1342 struct binder_ref *ref;
1293 1343  
  1344 + fp = to_flat_binder_object(hdr);
1294 1345 ref = binder_get_ref(proc, fp->handle,
1295   - fp->type == BINDER_TYPE_HANDLE);
1296   -
  1346 + hdr->type == BINDER_TYPE_HANDLE);
1297 1347 if (ref == NULL) {
1298 1348 pr_err("transaction release %d bad handle %d\n",
1299 1349 debug_id, fp->handle);
1300 1350  
1301 1351  
1302 1352  
1303 1353  
... ... @@ -1302,19 +1352,21 @@
1302 1352 binder_debug(BINDER_DEBUG_TRANSACTION,
1303 1353 " ref %d desc %d (node %d)\n",
1304 1354 ref->debug_id, ref->desc, ref->node->debug_id);
1305   - binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE);
  1355 + binder_dec_ref(ref, hdr->type == BINDER_TYPE_HANDLE);
1306 1356 } break;
1307 1357  
1308   - case BINDER_TYPE_FD:
  1358 + case BINDER_TYPE_FD: {
  1359 + struct binder_fd_object *fp = to_binder_fd_object(hdr);
  1360 +
1309 1361 binder_debug(BINDER_DEBUG_TRANSACTION,
1310   - " fd %d\n", fp->handle);
  1362 + " fd %d\n", fp->fd);
1311 1363 if (failed_at)
1312   - task_close_fd(proc, fp->handle);
1313   - break;
  1364 + task_close_fd(proc, fp->fd);
  1365 + } break;
1314 1366  
1315 1367 default:
1316 1368 pr_err("transaction release %d bad object type %x\n",
1317   - debug_id, fp->type);
  1369 + debug_id, hdr->type);
1318 1370 break;
1319 1371 }
1320 1372 }
1321 1373  
1322 1374  
1323 1375  
1324 1376  
1325 1377  
1326 1378  
... ... @@ -1531,28 +1583,29 @@
1531 1583 off_end = (void *)offp + tr->offsets_size;
1532 1584 off_min = 0;
1533 1585 for (; offp < off_end; offp++) {
1534   - struct flat_binder_object *fp;
  1586 + struct binder_object_header *hdr;
  1587 + size_t object_size = binder_validate_object(t->buffer, *offp);
1535 1588  
1536   - if (*offp > t->buffer->data_size - sizeof(*fp) ||
1537   - *offp < off_min ||
1538   - t->buffer->data_size < sizeof(*fp) ||
1539   - !IS_ALIGNED(*offp, sizeof(u32))) {
1540   - binder_user_error("%d:%d got transaction with invalid offset, %lld (min %lld, max %lld)\n",
  1589 + if (object_size == 0 || *offp < off_min) {
  1590 + binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n",
1541 1591 proc->pid, thread->pid, (u64)*offp,
1542 1592 (u64)off_min,
1543   - (u64)(t->buffer->data_size -
1544   - sizeof(*fp)));
  1593 + (u64)t->buffer->data_size);
1545 1594 return_error = BR_FAILED_REPLY;
1546 1595 goto err_bad_offset;
1547 1596 }
1548   - fp = (struct flat_binder_object *)(t->buffer->data + *offp);
1549   - off_min = *offp + sizeof(struct flat_binder_object);
1550   - switch (fp->type) {
  1597 +
  1598 + hdr = (struct binder_object_header *)(t->buffer->data + *offp);
  1599 + off_min = *offp + object_size;
  1600 + switch (hdr->type) {
1551 1601 case BINDER_TYPE_BINDER:
1552 1602 case BINDER_TYPE_WEAK_BINDER: {
  1603 + struct flat_binder_object *fp;
  1604 + struct binder_node *node;
1553 1605 struct binder_ref *ref;
1554   - struct binder_node *node = binder_get_node(proc, fp->binder);
1555 1606  
  1607 + fp = to_flat_binder_object(hdr);
  1608 + node = binder_get_node(proc, fp->binder);
1556 1609 if (node == NULL) {
1557 1610 node = binder_new_node(proc, fp->binder, fp->cookie);
1558 1611 if (node == NULL) {
1559 1612  
1560 1613  
... ... @@ -1580,14 +1633,14 @@
1580 1633 return_error = BR_FAILED_REPLY;
1581 1634 goto err_binder_get_ref_for_node_failed;
1582 1635 }
1583   - if (fp->type == BINDER_TYPE_BINDER)
1584   - fp->type = BINDER_TYPE_HANDLE;
  1636 + if (hdr->type == BINDER_TYPE_BINDER)
  1637 + hdr->type = BINDER_TYPE_HANDLE;
1585 1638 else
1586   - fp->type = BINDER_TYPE_WEAK_HANDLE;
  1639 + hdr->type = BINDER_TYPE_WEAK_HANDLE;
1587 1640 fp->binder = 0;
1588 1641 fp->handle = ref->desc;
1589 1642 fp->cookie = 0;
1590   - binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE,
  1643 + binder_inc_ref(ref, hdr->type == BINDER_TYPE_HANDLE,
1591 1644 &thread->todo);
1592 1645  
1593 1646 trace_binder_transaction_node_to_ref(t, node, ref);
1594 1647  
1595 1648  
... ... @@ -1598,11 +1651,12 @@
1598 1651 } break;
1599 1652 case BINDER_TYPE_HANDLE:
1600 1653 case BINDER_TYPE_WEAK_HANDLE: {
  1654 + struct flat_binder_object *fp;
1601 1655 struct binder_ref *ref;
1602 1656  
  1657 + fp = to_flat_binder_object(hdr);
1603 1658 ref = binder_get_ref(proc, fp->handle,
1604   - fp->type == BINDER_TYPE_HANDLE);
1605   -
  1659 + hdr->type == BINDER_TYPE_HANDLE);
1606 1660 if (ref == NULL) {
1607 1661 binder_user_error("%d:%d got transaction with invalid handle, %d\n",
1608 1662 proc->pid,
1609 1663  
1610 1664  
... ... @@ -1616,13 +1670,15 @@
1616 1670 goto err_binder_get_ref_failed;
1617 1671 }
1618 1672 if (ref->node->proc == target_proc) {
1619   - if (fp->type == BINDER_TYPE_HANDLE)
1620   - fp->type = BINDER_TYPE_BINDER;
  1673 + if (hdr->type == BINDER_TYPE_HANDLE)
  1674 + hdr->type = BINDER_TYPE_BINDER;
1621 1675 else
1622   - fp->type = BINDER_TYPE_WEAK_BINDER;
  1676 + hdr->type = BINDER_TYPE_WEAK_BINDER;
1623 1677 fp->binder = ref->node->ptr;
1624 1678 fp->cookie = ref->node->cookie;
1625   - binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
  1679 + binder_inc_node(ref->node,
  1680 + hdr->type == BINDER_TYPE_BINDER,
  1681 + 0, NULL);
1626 1682 trace_binder_transaction_ref_to_node(t, ref);
1627 1683 binder_debug(BINDER_DEBUG_TRANSACTION,
1628 1684 " ref %d desc %d -> node %d u%016llx\n",
... ... @@ -1639,7 +1695,9 @@
1639 1695 fp->binder = 0;
1640 1696 fp->handle = new_ref->desc;
1641 1697 fp->cookie = 0;
1642   - binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
  1698 + binder_inc_ref(new_ref,
  1699 + hdr->type == BINDER_TYPE_HANDLE,
  1700 + NULL);
1643 1701 trace_binder_transaction_ref_to_ref(t, ref,
1644 1702 new_ref);
1645 1703 binder_debug(BINDER_DEBUG_TRANSACTION,
1646 1704  
1647 1705  
1648 1706  
1649 1707  
... ... @@ -1652,25 +1710,26 @@
1652 1710 case BINDER_TYPE_FD: {
1653 1711 int target_fd;
1654 1712 struct file *file;
  1713 + struct binder_fd_object *fp = to_binder_fd_object(hdr);
1655 1714  
1656 1715 if (reply) {
1657 1716 if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {
1658 1717 binder_user_error("%d:%d got reply with fd, %d, but target does not allow fds\n",
1659   - proc->pid, thread->pid, fp->handle);
  1718 + proc->pid, thread->pid, fp->fd);
1660 1719 return_error = BR_FAILED_REPLY;
1661 1720 goto err_fd_not_allowed;
1662 1721 }
1663 1722 } else if (!target_node->accept_fds) {
1664 1723 binder_user_error("%d:%d got transaction with fd, %d, but target does not allow fds\n",
1665   - proc->pid, thread->pid, fp->handle);
  1724 + proc->pid, thread->pid, fp->fd);
1666 1725 return_error = BR_FAILED_REPLY;
1667 1726 goto err_fd_not_allowed;
1668 1727 }
1669 1728  
1670   - file = fget(fp->handle);
  1729 + file = fget(fp->fd);
1671 1730 if (file == NULL) {
1672 1731 binder_user_error("%d:%d got transaction with invalid fd, %d\n",
1673   - proc->pid, thread->pid, fp->handle);
  1732 + proc->pid, thread->pid, fp->fd);
1674 1733 return_error = BR_FAILED_REPLY;
1675 1734 goto err_fget_failed;
1676 1735 }
1677 1736  
1678 1737  
1679 1738  
... ... @@ -1688,17 +1747,18 @@
1688 1747 goto err_get_unused_fd_failed;
1689 1748 }
1690 1749 task_fd_install(target_proc, target_fd, file);
1691   - trace_binder_transaction_fd(t, fp->handle, target_fd);
  1750 + trace_binder_transaction_fd(t, fp->fd, target_fd);
1692 1751 binder_debug(BINDER_DEBUG_TRANSACTION,
1693   - " fd %d -> %d\n", fp->handle, target_fd);
  1752 + " fd %d -> %d\n", fp->fd,
  1753 + target_fd);
1694 1754 /* TODO: fput? */
1695   - fp->binder = 0;
1696   - fp->handle = target_fd;
  1755 + fp->pad_binder = 0;
  1756 + fp->fd = target_fd;
1697 1757 } break;
1698 1758  
1699 1759 default:
1700 1760 binder_user_error("%d:%d got transaction with invalid object type, %x\n",
1701   - proc->pid, thread->pid, fp->type);
  1761 + proc->pid, thread->pid, hdr->type);
1702 1762 return_error = BR_FAILED_REPLY;
1703 1763 goto err_bad_object_type;
1704 1764 }
include/uapi/linux/android/binder.h
... ... @@ -48,6 +48,14 @@
48 48 typedef __u64 binder_uintptr_t;
49 49 #endif
50 50  
  51 +/**
  52 + * struct binder_object_header - header shared by all binder metadata objects.
  53 + * @type: type of the object
  54 + */
  55 +struct binder_object_header {
  56 + __u32 type;
  57 +};
  58 +
51 59 /*
52 60 * This is the flattened representation of a Binder object for transfer
53 61 * between processes. The 'offsets' supplied as part of a binder transaction
... ... @@ -56,9 +64,8 @@
56 64 * between processes.
57 65 */
58 66 struct flat_binder_object {
59   - /* 8 bytes for large_flat_header. */
60   - __u32 type;
61   - __u32 flags;
  67 + struct binder_object_header hdr;
  68 + __u32 flags;
62 69  
63 70 /* 8 bytes of data. */
64 71 union {
... ... @@ -70,6 +77,24 @@
70 77 binder_uintptr_t cookie;
71 78 };
72 79  
  80 +/**
  81 + * struct binder_fd_object - describes a filedescriptor to be fixed up.
  82 + * @hdr: common header structure
  83 + * @pad_flags: padding to remain compatible with old userspace code
  84 + * @pad_binder: padding to remain compatible with old userspace code
  85 + * @fd: file descriptor
  86 + * @cookie: opaque data, used by user-space
  87 + */
  88 +struct binder_fd_object {
  89 + struct binder_object_header hdr;
  90 + __u32 pad_flags;
  91 + union {
  92 + binder_uintptr_t pad_binder;
  93 + __u32 fd;
  94 + };
  95 +
  96 + binder_uintptr_t cookie;
  97 +};
73 98 /*
74 99 * On 64-bit platforms where user code may run in 32-bits the driver must
75 100 * translate the buffer (and local binder) addresses appropriately.