diff options
| author | razorloves <razorloves@gmail.com> | 2017-07-05 21:10:52 -0500 |
|---|---|---|
| committer | razorloves <razorloves@gmail.com> | 2017-07-05 21:10:52 -0500 |
| commit | a74e5dc7f6579c916ecb8f0f0993fb1a3a0c44d6 (patch) | |
| tree | 294b007531faec4d613ce61e1e793aac5108fb30 | |
| parent | 2003ee960e185f5ae3dec497a65d4e19b5681054 (diff) | |
| parent | fa2246232e88eb8dd0c2bfe502cd9a3781eac406 (diff) | |
Merge branch 'aosp/android-tegra-flounder-3.10-nougat-mr1.1' into cm-14.1n7.1
N9F27F 7.1.1_r0.64 July 2017
| -rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_common.c | 12 | ||||
| -rw-r--r-- | drivers/net/wireless/bcmdhd/wl_cfg80211.c | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/bcmdhd/wl_cfgvendor.c | 36 | ||||
| -rw-r--r-- | drivers/video/tegra/dc/dsi_debug.c | 35 | ||||
| -rw-r--r-- | fs/f2fs/super.c | 34 | ||||
| -rw-r--r-- | fs/timerfd.c | 17 | ||||
| -rw-r--r-- | fs/udf/inode.c | 13 | ||||
| -rw-r--r-- | fs/udf/symlink.c | 9 | ||||
| -rw-r--r-- | include/linux/f2fs_fs.h | 6 | ||||
| -rw-r--r-- | net/packet/af_packet.c | 8 |
10 files changed, 140 insertions, 34 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c index 7125148a0f7..7270c6fc235 100644 --- a/drivers/net/wireless/bcmdhd/dhd_common.c +++ b/drivers/net/wireless/bcmdhd/dhd_common.c @@ -2076,7 +2076,7 @@ dhd_aoe_arp_clr(dhd_pub_t *dhd, int idx) if (dhd->arp_version == 1) idx = 0; - ret = dhd_iovar(dhd, 0, "arp_table_clear", NULL, 0, NULL, 0, TRUE); + ret = dhd_iovar(dhd, idx, "arp_table_clear", NULL, 0, NULL, 0, TRUE); if (ret) DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); } @@ -2090,7 +2090,7 @@ dhd_aoe_hostip_clr(dhd_pub_t *dhd, int idx) if (dhd->arp_version == 1) idx = 0; - ret = dhd_iovar(dhd, 0, "arp_hostip_clear", NULL, 0, NULL, 0, TRUE); + ret = dhd_iovar(dhd, idx, "arp_hostip_clear", NULL, 0, NULL, 0, TRUE); if (ret) DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); } @@ -2104,7 +2104,7 @@ dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr, int idx) if (dhd->arp_version == 1) idx = 0; - ret = dhd_iovar(dhd, 0, "arp_hostip", (char *)&ipaddr, sizeof(ipaddr), + ret = dhd_iovar(dhd, idx, "arp_hostip", (char *)&ipaddr, sizeof(ipaddr), NULL, 0, TRUE); if (ret) DHD_TRACE(("%s: ARP ip addr add failed, ret = %d\n", @@ -2127,7 +2127,7 @@ dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen, int idx) if (dhd->arp_version == 1) idx = 0; - ret = dhd_iovar(dhd, 0, "arp_hostip", NULL, 0, (char *)buf, buflen, + ret = dhd_iovar(dhd, idx, "arp_hostip", NULL, 0, (char *)buf, buflen, FALSE); if (ret) { DHD_TRACE(("%s: ioctl WLC_GET_VAR error %d\n", @@ -2187,7 +2187,7 @@ dhd_ndo_add_ip(dhd_pub_t *dhd, char* ipv6addr, int idx) if (dhd == NULL) return -1; - ret = dhd_iovar(dhd, 0, "nd_hostip", (char *)ipv6addr, IPV6_ADDR_LEN, + ret = dhd_iovar(dhd, idx, "nd_hostip", (char *)ipv6addr, IPV6_ADDR_LEN, NULL, 0, TRUE); if (ret) @@ -2211,7 +2211,7 @@ dhd_ndo_remove_ip(dhd_pub_t *dhd, int idx) if (dhd == NULL) return -1; - ret = dhd_iovar(dhd, 0, "nd_hostip_clear", NULL, 0, NULL, 0, TRUE); + ret = dhd_iovar(dhd, idx, "nd_hostip_clear", NULL, 0, NULL, 0, TRUE); if (ret) DHD_ERROR(("%s: ndo ip addr remove failed, ret = %d\n", __FUNCTION__, ret)); diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c index 9cb06a3c83b..b99c0ec1841 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c @@ -5830,6 +5830,10 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, WL_DBG(("Enter \n")); + if (len > (ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN)) { + WL_ERR(("bad length:%zu\n", len)); + return BCME_BADARG; + } dev = cfgdev_to_wlc_ndev(cfgdev, cfg); /* set bsscfg idx for iovar (wlan0: P2PAPI_BSSCFG_PRIMARY, p2p: P2PAPI_BSSCFG_DEVICE) */ diff --git a/drivers/net/wireless/bcmdhd/wl_cfgvendor.c b/drivers/net/wireless/bcmdhd/wl_cfgvendor.c index 420cb2fb04b..5aa3616366a 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfgvendor.c +++ b/drivers/net/wireless/bcmdhd/wl_cfgvendor.c @@ -1094,11 +1094,17 @@ static int wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy, const struct nlattr *outer, *inner, *iter; uint8 flush = 0; wl_pfn_significant_bssid_t *pbssid; + uint16 num_bssid = 0; + + /* gscan_swc_params_t has one wl_pfn_significant_bssid_t inside */ + uint16 max_buf_size = sizeof(gscan_swc_params_t) + + sizeof(wl_pfn_significant_bssid_t) * (PFN_SWC_MAX_NUM_APS - 1); + + significant_params = kzalloc(max_buf_size, GFP_KERNEL); - significant_params = (gscan_swc_params_t *) kzalloc(len, GFP_KERNEL); if (!significant_params) { - WL_ERR(("Cannot Malloc mem to parse config commands size - %d bytes \n", len)); - return -1; + WL_ERR(("Cannot Malloc mem size:%d\n", len)); + return BCME_NOMEM; } @@ -1118,9 +1124,27 @@ static int wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy, case GSCAN_ATTRIBUTE_MIN_BREACHING: significant_params->swc_threshold = nla_get_u16(iter); break; + case GSCAN_ATTRIBUTE_NUM_BSSID: + num_bssid = nla_get_u16(iter); + if (num_bssid > PFN_SWC_MAX_NUM_APS) { + WL_ERR(("ovar max SWC bssids:%d\n", + num_bssid)); + err = BCME_BADARG; + goto exit; + } + break; case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS: + if (num_bssid == 0) { + WL_ERR(("num_bssid : 0\n")); + err = BCME_BADARG; + goto exit; + } pbssid = significant_params->bssid_elem_list; nla_for_each_nested(outer, iter, tmp) { + if (j >= num_bssid) { + j++; + break; + } nla_for_each_nested(inner, outer, tmp1) { switch (nla_type(inner)) { case GSCAN_ATTRIBUTE_BSSID: @@ -1143,6 +1167,12 @@ static int wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy, break; } } + if (j != num_bssid) { + WL_ERR(("swc bssids count:%d not matched to num_bssid:%d\n", + j, num_bssid)); + err = BCME_BADARG; + goto exit; + } significant_params->nbssid = j; if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg), diff --git a/drivers/video/tegra/dc/dsi_debug.c b/drivers/video/tegra/dc/dsi_debug.c index 9e3288be4cc..cba8512513e 100644 --- a/drivers/video/tegra/dc/dsi_debug.c +++ b/drivers/video/tegra/dc/dsi_debug.c @@ -31,6 +31,8 @@ #ifdef CONFIG_DEBUG_FS +#define MAX_PANEL_REG_READ_SIZE 300 + static int dbg_dsi_show(struct seq_file *s, void *unused) { struct tegra_dc_dsi_data *dsi = s->private; @@ -152,36 +154,33 @@ static int read_panel_get(struct seq_file *s, void *unused) struct tegra_dc_dsi_data *dsi = s->private; struct tegra_dc *dc = dsi->dc; int err = 0; - u8 buf[300] = {0}; + u8 buf[MAX_PANEL_REG_READ_SIZE] = {0}; int j = 0 , b = 0 , k; u32 payload_size = 0; if (!dsi->enabled) { dev_info(&dc->ndev->dev, " controller suspended\n"); - return -EINVAL; -} + return -EINVAL; + } seq_printf(s, "max ret payload size:0x%x\npanel reg addr:0x%x\n", max_ret_payload_size, panel_reg_addr); - if (max_ret_payload_size == 0) { - seq_puts(s, "echo was not successful\n"); - return err; -} + + if ((max_ret_payload_size > MAX_PANEL_REG_READ_SIZE) || + (max_ret_payload_size == 0)) { + seq_printf(s, "Invalid max_ret_payload_size %d\n", + max_ret_payload_size); + return err; + } + err = tegra_dsi_read_data(dsi->dc, dsi, max_ret_payload_size, panel_reg_addr, buf); - seq_printf(s, " Read data[%d] ", b); - - for (b = 1; b < (max_ret_payload_size+1); b++) { - j = (b*4)-1; - for (k = j; k > (j-4); k--) - if ((k%4) == 0 && b != max_ret_payload_size) { - seq_printf(s, " %x ", buf[k]); - seq_printf(s, "\n Read data[%d] ", b); - } - else - seq_printf(s, " %x ", buf[k]); + for (b = 0; b < max_ret_payload_size; b += 4) { + seq_printf(s, "%s Read data[%d] ", b ? "\n" : "", j++); + for (k = b+4; k > b; k--) + seq_printf(s, " %x ", buf[k-1]); } seq_puts(s, "\n"); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 5456dc11f6e..3c93f837d91 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -884,6 +884,14 @@ static int sanity_check_raw_super(struct super_block *sb, return 1; } + /* check log blocks per segment */ + if (le32_to_cpu(raw_super->log_blocks_per_seg) != 9) { + f2fs_msg(sb, KERN_INFO, + "Invalid log blocks per segment (%u)\n", + le32_to_cpu(raw_super->log_blocks_per_seg)); + return 1; + } + /* Currently, support 512/1024/2048/4096 bytes sector size */ if (le32_to_cpu(raw_super->log_sectorsize) > F2FS_MAX_LOG_SECTOR_SIZE || @@ -902,6 +910,14 @@ static int sanity_check_raw_super(struct super_block *sb, le32_to_cpu(raw_super->log_sectorsize)); return 1; } + + if (le32_to_cpu(raw_super->segment_count) > F2FS_MAX_SEGMENT) { + f2fs_msg(sb, KERN_INFO, + "Invalid segment count (%u)", + le32_to_cpu(raw_super->segment_count)); + return 1; + } + return 0; } @@ -910,6 +926,8 @@ static int sanity_check_ckpt(struct f2fs_sb_info *sbi) unsigned int total, fsmeta; struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); + unsigned int main_segs, blocks_per_seg; + int i; total = le32_to_cpu(raw_super->segment_count); fsmeta = le32_to_cpu(raw_super->segment_count_ckpt); @@ -921,6 +939,22 @@ static int sanity_check_ckpt(struct f2fs_sb_info *sbi) if (unlikely(fsmeta >= total)) return 1; + main_segs = le32_to_cpu(sbi->raw_super->segment_count_main); + blocks_per_seg = sbi->blocks_per_seg; + + for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) { + if (le32_to_cpu(ckpt->cur_node_segno[i]) >= main_segs || + le16_to_cpu(ckpt->cur_node_blkoff[i]) >= blocks_per_seg) { + return 1; + } + } + for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) { + if (le32_to_cpu(ckpt->cur_data_segno[i]) >= main_segs || + le16_to_cpu(ckpt->cur_data_blkoff[i]) >= blocks_per_seg) { + return 1; + } + } + if (unlikely(f2fs_cp_error(sbi))) { f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck"); return 1; diff --git a/fs/timerfd.c b/fs/timerfd.c index 0013142c047..0db5b6c1b10 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -39,6 +39,7 @@ struct timerfd_ctx { int clockid; struct rcu_head rcu; struct list_head clist; + spinlock_t cancel_lock; bool might_cancel; }; @@ -111,7 +112,7 @@ void timerfd_clock_was_set(void) rcu_read_unlock(); } -static void timerfd_remove_cancel(struct timerfd_ctx *ctx) +static void __timerfd_remove_cancel(struct timerfd_ctx *ctx) { if (ctx->might_cancel) { ctx->might_cancel = false; @@ -121,6 +122,13 @@ static void timerfd_remove_cancel(struct timerfd_ctx *ctx) } } +static void timerfd_remove_cancel(struct timerfd_ctx *ctx) +{ + spin_lock(&ctx->cancel_lock); + __timerfd_remove_cancel(ctx); + spin_unlock(&ctx->cancel_lock); +} + static bool timerfd_canceled(struct timerfd_ctx *ctx) { if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX) @@ -131,6 +139,7 @@ static bool timerfd_canceled(struct timerfd_ctx *ctx) static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) { + spin_lock(&ctx->cancel_lock); if ((ctx->clockid == CLOCK_REALTIME || ctx->clockid == CLOCK_REALTIME_ALARM) && (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) { @@ -140,9 +149,10 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) list_add_rcu(&ctx->clist, &cancel_list); spin_unlock(&cancel_lock); } - } else if (ctx->might_cancel) { - timerfd_remove_cancel(ctx); + } else { + __timerfd_remove_cancel(ctx); } + spin_unlock(&ctx->cancel_lock); } static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx) @@ -326,6 +336,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) return -ENOMEM; init_waitqueue_head(&ctx->wqh); + spin_lock_init(&ctx->cancel_lock); ctx->clockid = clockid; if (isalarm(ctx)) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 5c1120a5fa4..b2340f805fa 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1504,6 +1504,19 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) /* Now do exact checks */ if (udf_file_entry_alloc_offset(inode) + iinfo->i_lenAlloc > inode->i_sb->s_blocksize) return; + /* Sanity checks for files in ICB so that we don't get confused later */ + if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { + /* + * For file in ICB data is stored in allocation descriptor + * so sizes should match + */ + if (iinfo->i_lenAlloc != inode->i_size) + return; + /* File in ICB has to fit in there... */ + if (inode->i_size > inode->i_sb->s_blocksize - + udf_file_entry_alloc_offset(inode)) + return; + } switch (fe->icbTag.fileType) { case ICBTAG_FILE_TYPE_DIRECTORY: diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index d89f324bc38..0445eb94188 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c @@ -39,14 +39,17 @@ static void udf_pc_to_char(struct super_block *sb, unsigned char *from, while (elen < fromlen) { pc = (struct pathComponent *)(from + elen); + elen += sizeof(struct pathComponent); switch (pc->componentType) { case 1: /* * Symlink points to some place which should be agreed * upon between originator and receiver of the media. Ignore. */ - if (pc->lengthComponentIdent > 0) + if (pc->lengthComponentIdent > 0) { + elen += pc->lengthComponentIdent; break; + } /* Fall through */ case 2: p = to; @@ -62,12 +65,14 @@ static void udf_pc_to_char(struct super_block *sb, unsigned char *from, /* that would be . - just ignore */ break; case 5: + elen += pc->lengthComponentIdent; + if (elen > fromlen) + return -EIO; p += udf_get_filename(sb, pc->componentIdent, p, pc->lengthComponentIdent); *p++ = '/'; break; } - elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; } if (p > to + 1) p[-1] = '\0'; diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 860313a33a4..2df22eab98e 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -269,6 +269,12 @@ struct f2fs_nat_block { #define SIT_ENTRY_PER_BLOCK (PAGE_CACHE_SIZE / sizeof(struct f2fs_sit_entry)) /* + * F2FS uses 4 bytes to represent block address. As a result, supported size of + * disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments. + */ +#define F2FS_MAX_SEGMENT ((16 * 1024 * 1024) / 2) + +/* * Note that f2fs_sit_entry->vblocks has the following bit-field information. * [15:10] : allocation type such as CURSEG_XXXX_TYPE * [9:0] : valid block count diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index c200b1d5946..fea27ae4535 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -3165,6 +3165,8 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv return -EBUSY; if (copy_from_user(&val, optval, sizeof(val))) return -EFAULT; + if (val > INT_MAX) + return -EINVAL; po->tp_reserve = val; return 0; } @@ -3650,8 +3652,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, if (unlikely(req->tp_block_size & (PAGE_SIZE - 1))) goto out; if (po->tp_version >= TPACKET_V3 && - (int)(req->tp_block_size - - BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0) + req->tp_block_size <= + BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv)) goto out; if (unlikely(req->tp_frame_size < po->tp_hdrlen + po->tp_reserve)) @@ -3662,6 +3664,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, rb->frames_per_block = req->tp_block_size/req->tp_frame_size; if (unlikely(rb->frames_per_block <= 0)) goto out; + if (unlikely(req->tp_block_size > UINT_MAX / req->tp_block_nr)) + goto out; if (unlikely((rb->frames_per_block * req->tp_block_nr) != req->tp_frame_nr)) goto out; |
