aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_common.c12
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c4
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfgvendor.c36
-rw-r--r--drivers/video/tegra/dc/dsi_debug.c35
-rw-r--r--fs/f2fs/super.c34
-rw-r--r--fs/timerfd.c17
-rw-r--r--fs/udf/inode.c13
-rw-r--r--fs/udf/symlink.c9
-rw-r--r--include/linux/f2fs_fs.h6
-rw-r--r--net/packet/af_packet.c8
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;