已合并
esp: fix skb leak with espintcp and async crypto #390
chenyangw创建于 5月28日
esp: fix skb leak with espintcp and async crypto #390
已合并
共 30 个文件变更+222-83
| @@ -15,7 +15,6 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | - | ||
| 19 | 18 | ||
| 20 | 19 | ||
| 21 | 20 | ||
| @@ -2282,8 +2282,11 @@ static void btusb_work(struct work_struct *work) | |||
| 2282 | if (data->air_mode == HCI_NOTIFY_ENABLE_SCO_CVSD) { | 2282 | if (data->air_mode == HCI_NOTIFY_ENABLE_SCO_CVSD) { |
| 2283 | if (hdev->voice_setting & 0x0020) { | 2283 | if (hdev->voice_setting & 0x0020) { |
| 2284 | static const int alts[3] = { 2, 4, 5 }; | 2284 | static const int alts[3] = { 2, 4, 5 }; |
| 2285 | + unsigned int sco_idx; | ||
| 2285 | 2286 | ||
| 2286 | - new_alts = alts[data->sco_num - 1]; | 2287 | + sco_idx = min_t(unsigned int, data->sco_num - 1, |
| 2288 | + ARRAY_SIZE(alts) - 1); | ||
| 2289 | + new_alts = alts[sco_idx]; | ||
| 2287 | } else { | 2290 | } else { |
| 2288 | new_alts = data->sco_num; | 2291 | new_alts = data->sco_num; |
| 2289 | } | 2292 | } |
| @@ -1351,7 +1351,15 @@ EXPORT_SYMBOL_GPL(hid_snto32); | |||
| 1351 | 1351 | ||
| 1352 | static u32 s32ton(__s32 value, unsigned n) | 1352 | static u32 s32ton(__s32 value, unsigned n) |
| 1353 | { | 1353 | { |
| 1354 | - s32 a = value >> (n - 1); | 1354 | + s32 a; |
| 1355 | + | ||
| 1356 | + if (!value || !n) | ||
| 1357 | + return 0; | ||
| 1358 | + | ||
| 1359 | + if (n > 32) | ||
| 1360 | + n = 32; | ||
| 1361 | + | ||
| 1362 | + a = value >> (n - 1); | ||
| 1355 | if (a && a != -1) | 1363 | if (a && a != -1) |
| 1356 | return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; | 1364 | return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; |
| 1357 | return value & ((1 << n) - 1); | 1365 | return value & ((1 << n) - 1); |
| @@ -57,6 +57,7 @@ struct uinput_device { | |||
| 57 | struct input_dev *dev; | 57 | struct input_dev *dev; |
| 58 | struct mutex mutex; | 58 | struct mutex mutex; |
| 59 | enum uinput_state state; | 59 | enum uinput_state state; |
| 60 | + spinlock_t state_lock; | ||
| 60 | wait_queue_head_t waitq; | 61 | wait_queue_head_t waitq; |
| 61 | unsigned char ready; | 62 | unsigned char ready; |
| 62 | unsigned char head; | 63 | unsigned char head; |
| @@ -146,19 +147,15 @@ static void uinput_request_release_slot(struct uinput_device *udev, | |||
| 146 | static int uinput_request_send(struct uinput_device *udev, | 147 | static int uinput_request_send(struct uinput_device *udev, |
| 147 | struct uinput_request *request) | 148 | struct uinput_request *request) |
| 148 | { | 149 | { |
| 149 | - int retval; | 150 | + int retval = 0; |
| 150 | 151 | ||
| 151 | - retval = mutex_lock_interruptible(&udev->mutex); | 152 | + spin_lock(&udev->state_lock); |
| 152 | - if (retval) | ||
| 153 | - return retval; | ||
| 154 | 153 | ||
| 155 | if (udev->state != UIST_CREATED) { | 154 | if (udev->state != UIST_CREATED) { |
| 156 | retval = -ENODEV; | 155 | retval = -ENODEV; |
| 157 | goto out; | 156 | goto out; |
| 158 | } | 157 | } |
| 159 | 158 | ||
| 160 | - init_completion(&request->done); | ||
| 161 | - | ||
| 162 | /* | 159 | /* |
| 163 | * Tell our userspace application about this new request | 160 | * Tell our userspace application about this new request |
| 164 | * by queueing an input event. | 161 | * by queueing an input event. |
| @@ -166,7 +163,7 @@ static int uinput_request_send(struct uinput_device *udev, | |||
| 166 | uinput_dev_event(udev->dev, EV_UINPUT, request->code, request->id); | 163 | uinput_dev_event(udev->dev, EV_UINPUT, request->code, request->id); |
| 167 | 164 | ||
| 168 | out: | 165 | out: |
| 169 | - mutex_unlock(&udev->mutex); | 166 | + spin_unlock(&udev->state_lock); |
| 170 | return retval; | 167 | return retval; |
| 171 | } | 168 | } |
| 172 | 169 | ||
| @@ -175,6 +172,13 @@ static int uinput_request_submit(struct uinput_device *udev, | |||
| 175 | { | 172 | { |
| 176 | int retval; | 173 | int retval; |
| 177 | 174 | ||
| 175 | + /* | ||
| 176 | + * Initialize completion before allocating the request slot. | ||
| 177 | + * Once the slot is allocated, uinput_flush_requests() may | ||
| 178 | + * complete it at any time, so it must be initialized first. | ||
| 179 | + */ | ||
| 180 | + init_completion(&request->done); | ||
| 181 | + | ||
| 178 | retval = uinput_request_reserve_slot(udev, request); | 182 | retval = uinput_request_reserve_slot(udev, request); |
| 179 | if (retval) | 183 | if (retval) |
| 180 | return retval; | 184 | return retval; |
| @@ -289,7 +293,14 @@ static void uinput_destroy_device(struct uinput_device *udev) | |||
| 289 | struct input_dev *dev = udev->dev; | 293 | struct input_dev *dev = udev->dev; |
| 290 | enum uinput_state old_state = udev->state; | 294 | enum uinput_state old_state = udev->state; |
| 291 | 295 | ||
| 296 | + /* | ||
| 297 | + * Update state under state_lock so that concurrent | ||
| 298 | + * uinput_request_send() sees the state change before we | ||
| 299 | + * flush pending requests and tear down the device. | ||
| 300 | + */ | ||
| 301 | + spin_lock(&udev->state_lock); | ||
| 292 | udev->state = UIST_NEW_DEVICE; | 302 | udev->state = UIST_NEW_DEVICE; |
| 303 | + spin_unlock(&udev->state_lock); | ||
| 293 | 304 | ||
| 294 | if (dev) { | 305 | if (dev) { |
| 295 | name = dev->name; | 306 | name = dev->name; |
| @@ -366,7 +377,9 @@ static int uinput_create_device(struct uinput_device *udev) | |||
| 366 | if (error) | 377 | if (error) |
| 367 | goto fail2; | 378 | goto fail2; |
| 368 | 379 | ||
| 380 | + spin_lock(&udev->state_lock); | ||
| 369 | udev->state = UIST_CREATED; | 381 | udev->state = UIST_CREATED; |
| 382 | + spin_unlock(&udev->state_lock); | ||
| 370 | 383 | ||
| 371 | return 0; | 384 | return 0; |
| 372 | 385 | ||
| @@ -384,6 +397,7 @@ static int uinput_open(struct inode *inode, struct file *file) | |||
| 384 | return -ENOMEM; | 397 | return -ENOMEM; |
| 385 | 398 | ||
| 386 | mutex_init(&newdev->mutex); | 399 | mutex_init(&newdev->mutex); |
| 400 | + spin_lock_init(&newdev->state_lock); | ||
| 387 | spin_lock_init(&newdev->requests_lock); | 401 | spin_lock_init(&newdev->requests_lock); |
| 388 | init_waitqueue_head(&newdev->requests_waitq); | 402 | init_waitqueue_head(&newdev->requests_waitq); |
| 389 | init_waitqueue_head(&newdev->waitq); | 403 | init_waitqueue_head(&newdev->waitq); |
| @@ -180,6 +180,7 @@ | |||
| 180 | 180 | ||
| 181 | 181 | ||
| 182 | 182 | ||
| 183 | + | ||
| 183 | 184 | ||
| 184 | 185 | ||
| 185 | 186 | ||
| @@ -1853,8 +1854,15 @@ static int check_command_size_in_blocks(struct fsg_common *common, | |||
| 1853 | int cmnd_size, enum data_direction data_dir, | 1854 | int cmnd_size, enum data_direction data_dir, |
| 1854 | unsigned int mask, int needs_medium, const char *name) | 1855 | unsigned int mask, int needs_medium, const char *name) |
| 1855 | { | 1856 | { |
| 1856 | - if (common->curlun) | 1857 | + if (common->curlun) { |
| 1857 | - common->data_size_from_cmnd <<= common->curlun->blkbits; | 1858 | + if (check_shl_overflow(common->data_size_from_cmnd, |
| 1859 | + common->curlun->blkbits, | ||
| 1860 | + &common->data_size_from_cmnd)) { | ||
| 1861 | + common->phase_error = 1; | ||
| 1862 | + return -EINVAL; | ||
| 1863 | + } | ||
| 1864 | + } | ||
| 1865 | + | ||
| 1858 | return check_command(common, cmnd_size, data_dir, | 1866 | return check_command(common, cmnd_size, data_dir, |
| 1859 | mask, needs_medium, name); | 1867 | mask, needs_medium, name); |
| 1860 | } | 1868 | } |
| @@ -997,7 +997,7 @@ static int ext4_fc_submit_inode_data_all(journal_t *journal) | |||
| 997 | finish_wait(&ei->i_fc_wait, &wait); | 997 | finish_wait(&ei->i_fc_wait, &wait); |
| 998 | } | 998 | } |
| 999 | spin_unlock(&sbi->s_fc_lock); | 999 | spin_unlock(&sbi->s_fc_lock); |
| 1000 | - ret = jbd2_submit_inode_data(journal, ei->jinode); | 1000 | + ret = jbd2_submit_inode_data(journal, READ_ONCE(ei->jinode)); |
| 1001 | if (ret) | 1001 | if (ret) |
| 1002 | return ret; | 1002 | return ret; |
| 1003 | spin_lock(&sbi->s_fc_lock); | 1003 | spin_lock(&sbi->s_fc_lock); |
| @@ -1022,7 +1022,7 @@ static int ext4_fc_wait_inode_data_all(journal_t *journal) | |||
| 1022 | continue; | 1022 | continue; |
| 1023 | spin_unlock(&sbi->s_fc_lock); | 1023 | spin_unlock(&sbi->s_fc_lock); |
| 1024 | 1024 | ||
| 1025 | - ret = jbd2_wait_inode_data(journal, pos->jinode); | 1025 | + ret = jbd2_wait_inode_data(journal, READ_ONCE(pos->jinode)); |
| 1026 | if (ret) | 1026 | if (ret) |
| 1027 | return ret; | 1027 | return ret; |
| 1028 | spin_lock(&sbi->s_fc_lock); | 1028 | spin_lock(&sbi->s_fc_lock); |
| @@ -123,6 +123,8 @@ void ext4_inode_csum_set(struct inode *inode, struct ext4_inode *raw, | |||
| 123 | static inline int ext4_begin_ordered_truncate(struct inode *inode, | 123 | static inline int ext4_begin_ordered_truncate(struct inode *inode, |
| 124 | loff_t new_size) | 124 | loff_t new_size) |
| 125 | { | 125 | { |
| 126 | + struct jbd2_inode *jinode = READ_ONCE(EXT4_I(inode)->jinode); | ||
| 127 | + | ||
| 126 | trace_ext4_begin_ordered_truncate(inode, new_size); | 128 | trace_ext4_begin_ordered_truncate(inode, new_size); |
| 127 | /* | 129 | /* |
| 128 | * If jinode is zero, then we never opened the file for | 130 | * If jinode is zero, then we never opened the file for |
| @@ -130,10 +132,10 @@ static inline int ext4_begin_ordered_truncate(struct inode *inode, | |||
| 130 | * jbd2_journal_begin_ordered_truncate() since there's no | 132 | * jbd2_journal_begin_ordered_truncate() since there's no |
| 131 | * outstanding writes we need to flush. | 133 | * outstanding writes we need to flush. |
| 132 | */ | 134 | */ |
| 133 | - if (!EXT4_I(inode)->jinode) | 135 | + if (!jinode) |
| 134 | return 0; | 136 | return 0; |
| 135 | return jbd2_journal_begin_ordered_truncate(EXT4_JOURNAL(inode), | 137 | return jbd2_journal_begin_ordered_truncate(EXT4_JOURNAL(inode), |
| 136 | - EXT4_I(inode)->jinode, | 138 | + jinode, |
| 137 | new_size); | 139 | new_size); |
| 138 | } | 140 | } |
| 139 | 141 | ||
| @@ -4154,8 +4156,13 @@ int ext4_inode_attach_jinode(struct inode *inode) | |||
| 4154 | spin_unlock(&inode->i_lock); | 4156 | spin_unlock(&inode->i_lock); |
| 4155 | return -ENOMEM; | 4157 | return -ENOMEM; |
| 4156 | } | 4158 | } |
| 4157 | - ei->jinode = jinode; | 4159 | + jbd2_journal_init_jbd_inode(jinode, inode); |
| 4158 | - jbd2_journal_init_jbd_inode(ei->jinode, inode); | 4160 | + /* |
| 4161 | + * Publish ->jinode only after it is fully initialized so that | ||
| 4162 | + * readers never observe a partially initialized jbd2_inode. | ||
| 4163 | + */ | ||
| 4164 | + smp_wmb(); | ||
| 4165 | + WRITE_ONCE(ei->jinode, jinode); | ||
| 4159 | jinode = NULL; | 4166 | jinode = NULL; |
| 4160 | } | 4167 | } |
| 4161 | spin_unlock(&inode->i_lock); | 4168 | spin_unlock(&inode->i_lock); |
| @@ -3667,6 +3667,13 @@ int ext4_feature_set_ok(struct super_block *sb, int readonly) | |||
| 3667 | "extents feature\n"); | 3667 | "extents feature\n"); |
| 3668 | return 0; | 3668 | return 0; |
| 3669 | } | 3669 | } |
| 3670 | + if (ext4_has_feature_bigalloc(sb) && | ||
| 3671 | + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) { | ||
| 3672 | + ext4_msg(sb, KERN_WARNING, | ||
| 3673 | + "bad geometry: bigalloc file system with non-zero " | ||
| 3674 | + "first_data_block\n"); | ||
| 3675 | + return 0; | ||
| 3676 | + } | ||
| 3670 | 3677 | ||
| 3671 | 3678 | ||
| 3672 | if (!readonly && (ext4_has_feature_quota(sb) || | 3679 | if (!readonly && (ext4_has_feature_quota(sb) || |
| @@ -4773,6 +4773,8 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, | |||
| 4773 | /* align next xattr entry at 4 byte bundary */ | 4773 | /* align next xattr entry at 4 byte bundary */ |
| 4774 | alignment_bytes = ((next_offset + 3) & ~3) - next_offset; | 4774 | alignment_bytes = ((next_offset + 3) & ~3) - next_offset; |
| 4775 | if (alignment_bytes) { | 4775 | if (alignment_bytes) { |
| 4776 | + if (buf_free_len < alignment_bytes) | ||
| 4777 | + break; | ||
| 4776 | memset(ptr, '\0', alignment_bytes); | 4778 | memset(ptr, '\0', alignment_bytes); |
| 4777 | ptr += alignment_bytes; | 4779 | ptr += alignment_bytes; |
| 4778 | next_offset += alignment_bytes; | 4780 | next_offset += alignment_bytes; |
| @@ -125,6 +125,7 @@ xfs_qm_dquot_logitem_push( | |||
| 125 | { | 125 | { |
| 126 | struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; | 126 | struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot; |
| 127 | struct xfs_buf *bp = lip->li_buf; | 127 | struct xfs_buf *bp = lip->li_buf; |
| 128 | + struct xfs_ail *ailp = lip->li_ailp; | ||
| 128 | uint rval = XFS_ITEM_SUCCESS; | 129 | uint rval = XFS_ITEM_SUCCESS; |
| 129 | int error; | 130 | int error; |
| 130 | 131 | ||
| @@ -153,7 +154,7 @@ xfs_qm_dquot_logitem_push( | |||
| 153 | goto out_unlock; | 154 | goto out_unlock; |
| 154 | } | 155 | } |
| 155 | 156 | ||
| 156 | - spin_unlock(&lip->li_ailp->ail_lock); | 157 | + spin_unlock(&ailp->ail_lock); |
| 157 | 158 | ||
| 158 | error = xfs_qm_dqflush(dqp, &bp); | 159 | error = xfs_qm_dqflush(dqp, &bp); |
| 159 | if (!error) { | 160 | if (!error) { |
| @@ -163,7 +164,11 @@ xfs_qm_dquot_logitem_push( | |||
| 163 | } else if (error == -EAGAIN) | 164 | } else if (error == -EAGAIN) |
| 164 | rval = XFS_ITEM_LOCKED; | 165 | rval = XFS_ITEM_LOCKED; |
| 165 | 166 | ||
| 166 | - spin_lock(&lip->li_ailp->ail_lock); | 167 | + /* |
| 168 | + * The buffer no longer protects the log item from reclaim, so | ||
| 169 | + * do not reference lip after this point. | ||
| 170 | + */ | ||
| 171 | + spin_lock(&ailp->ail_lock); | ||
| 167 | out_unlock: | 172 | out_unlock: |
| 168 | xfs_dqunlock(dqp); | 173 | xfs_dqunlock(dqp); |
| 169 | return rval; | 174 | return rval; |
| @@ -727,6 +727,7 @@ xfs_inode_item_push( | |||
| 727 | struct xfs_inode_log_item *iip = INODE_ITEM(lip); | 727 | struct xfs_inode_log_item *iip = INODE_ITEM(lip); |
| 728 | struct xfs_inode *ip = iip->ili_inode; | 728 | struct xfs_inode *ip = iip->ili_inode; |
| 729 | struct xfs_buf *bp = lip->li_buf; | 729 | struct xfs_buf *bp = lip->li_buf; |
| 730 | + struct xfs_ail *ailp = lip->li_ailp; | ||
| 730 | uint rval = XFS_ITEM_SUCCESS; | 731 | uint rval = XFS_ITEM_SUCCESS; |
| 731 | int error; | 732 | int error; |
| 732 | 733 | ||
| @@ -749,7 +750,7 @@ xfs_inode_item_push( | |||
| 749 | if (!xfs_buf_trylock(bp)) | 750 | if (!xfs_buf_trylock(bp)) |
| 750 | return XFS_ITEM_LOCKED; | 751 | return XFS_ITEM_LOCKED; |
| 751 | 752 | ||
| 752 | - spin_unlock(&lip->li_ailp->ail_lock); | 753 | + spin_unlock(&ailp->ail_lock); |
| 753 | 754 | ||
| 754 | /* | 755 | /* |
| 755 | * We need to hold a reference for flushing the cluster buffer as it may | 756 | * We need to hold a reference for flushing the cluster buffer as it may |
| @@ -773,7 +774,11 @@ xfs_inode_item_push( | |||
| 773 | rval = XFS_ITEM_LOCKED; | 774 | rval = XFS_ITEM_LOCKED; |
| 774 | } | 775 | } |
| 775 | 776 | ||
| 776 | - spin_lock(&lip->li_ailp->ail_lock); | 777 | + /* |
| 778 | + * The buffer no longer protects the log item from reclaim, so | ||
| 779 | + * do not reference lip after this point. | ||
| 780 | + */ | ||
| 781 | + spin_lock(&ailp->ail_lock); | ||
| 777 | return rval; | 782 | return rval; |
| 778 | } | 783 | } |
| 779 | 784 | ||
| @@ -756,13 +756,23 @@ static inline bool skb_skip_tc_classify(struct sk_buff *skb) | |||
| 756 | static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) | 756 | static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) |
| 757 | { | 757 | { |
| 758 | struct Qdisc *qdisc; | 758 | struct Qdisc *qdisc; |
| 759 | + bool nolock; | ||
| 759 | 760 | ||
| 760 | for (; i < dev->num_tx_queues; i++) { | 761 | for (; i < dev->num_tx_queues; i++) { |
| 761 | qdisc = rtnl_dereference(netdev_get_tx_queue(dev, i)->qdisc); | 762 | qdisc = rtnl_dereference(netdev_get_tx_queue(dev, i)->qdisc); |
| 762 | if (qdisc) { | 763 | if (qdisc) { |
| 764 | + nolock = qdisc->flags & TCQ_F_NOLOCK; | ||
| 765 | + | ||
| 766 | + if (nolock) | ||
| 767 | + spin_lock_bh(&qdisc->seqlock); | ||
| 763 | spin_lock_bh(qdisc_lock(qdisc)); | 768 | spin_lock_bh(qdisc_lock(qdisc)); |
| 764 | qdisc_reset(qdisc); | 769 | qdisc_reset(qdisc); |
| 765 | spin_unlock_bh(qdisc_lock(qdisc)); | 770 | spin_unlock_bh(qdisc_lock(qdisc)); |
| 771 | + if (nolock) { | ||
| 772 | + clear_bit(__QDISC_STATE_MISSED, &qdisc->state); | ||
| 773 | + clear_bit(__QDISC_STATE_DRAINING, &qdisc->state); | ||
| 774 | + spin_unlock_bh(&qdisc->seqlock); | ||
| 775 | + } | ||
| 766 | } | 776 | } |
| 767 | } | 777 | } |
| 768 | } | 778 | } |
| @@ -159,5 +159,9 @@ enum ip_conntrack_expect_events { | |||
| 159 | 159 | ||
| 160 | 160 | ||
| 161 | 161 | ||
| 162 | + | ||
| 163 | + | ||
| 164 | + NF_CT_EXPECT_USERSPACE) | ||
| 165 | + | ||
| 162 | 166 | ||
| 163 | 167 | ||
| @@ -1422,6 +1422,13 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) | |||
| 1422 | break; | 1422 | break; |
| 1423 | 1423 | ||
| 1424 | default: | 1424 | default: |
| 1425 | + if (sym[i].st_shndx >= info->hdr->e_shnum) { | ||
| 1426 | + pr_err("%s: Symbol %s has an invalid section index %u (max %u)\n", | ||
| 1427 | + mod->name, name, sym[i].st_shndx, info->hdr->e_shnum - 1); | ||
| 1428 | + ret = -ENOEXEC; | ||
| 1429 | + break; | ||
| 1430 | + } | ||
| 1431 | + | ||
| 1425 | /* Divert to percpu allocation if a percpu var. */ | 1432 | /* Divert to percpu allocation if a percpu var. */ |
| 1426 | if (sym[i].st_shndx == info->index.pcpu) | 1433 | if (sym[i].st_shndx == info->index.pcpu) |
| 1427 | secbase = (unsigned long)mod_percpu(mod); | 1434 | secbase = (unsigned long)mod_percpu(mod); |
| @@ -2381,6 +2381,9 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, | |||
| 2381 | /* Remote device may have requested smaller PDUs */ | 2381 | /* Remote device may have requested smaller PDUs */ |
| 2382 | pdu_len = min_t(size_t, pdu_len, chan->remote_mps); | 2382 | pdu_len = min_t(size_t, pdu_len, chan->remote_mps); |
| 2383 | 2383 | ||
| 2384 | + if (!pdu_len) | ||
| 2385 | + return -EINVAL; | ||
| 2386 | + | ||
| 2384 | if (len <= pdu_len) { | 2387 | if (len <= pdu_len) { |
| 2385 | sar = L2CAP_SAR_UNSEGMENTED; | 2388 | sar = L2CAP_SAR_UNSEGMENTED; |
| 2386 | sdu_len = 0; | 2389 | sdu_len = 0; |
| @@ -4279,14 +4282,16 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, | |||
| 4279 | if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) { | 4282 | if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) { |
| 4280 | set_default_fcs(chan); | 4283 | set_default_fcs(chan); |
| 4281 | 4284 | ||
| 4282 | - if (chan->mode == L2CAP_MODE_ERTM || | 4285 | + if (chan->state != BT_CONNECTED) { |
| 4283 | - chan->mode == L2CAP_MODE_STREAMING) | 4286 | + if (chan->mode == L2CAP_MODE_ERTM || |
| 4284 | - err = l2cap_ertm_init(chan); | 4287 | + chan->mode == L2CAP_MODE_STREAMING) |
| 4288 | + err = l2cap_ertm_init(chan); | ||
| 4285 | 4289 | ||
| 4286 | - if (err < 0) | 4290 | + if (err < 0) |
| 4287 | - l2cap_send_disconn_req(chan, -err); | 4291 | + l2cap_send_disconn_req(chan, -err); |
| 4288 | - else | 4292 | + else |
| 4289 | - l2cap_chan_ready(chan); | 4293 | + l2cap_chan_ready(chan); |
| 4294 | + } | ||
| 4290 | 4295 | ||
| 4291 | goto unlock; | 4296 | goto unlock; |
| 4292 | } | 4297 | } |
| @@ -6596,6 +6601,11 @@ static int l2cap_ecred_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) | |||
| 6596 | if (!chan->sdu) { | 6601 | if (!chan->sdu) { |
| 6597 | u16 sdu_len; | 6602 | u16 sdu_len; |
| 6598 | 6603 | ||
| 6604 | + if (!pskb_may_pull(skb, L2CAP_SDULEN_SIZE)) { | ||
| 6605 | + err = -EINVAL; | ||
| 6606 | + goto failed; | ||
| 6607 | + } | ||
| 6608 | + | ||
| 6599 | sdu_len = get_unaligned_le16(skb->data); | 6609 | sdu_len = get_unaligned_le16(skb->data); |
| 6600 | skb_pull(skb, L2CAP_SDULEN_SIZE); | 6610 | skb_pull(skb, L2CAP_SDULEN_SIZE); |
| 6601 | 6611 | ||
| @@ -1655,6 +1655,9 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan) | |||
| 1655 | struct sock *sk = chan->data; | 1655 | struct sock *sk = chan->data; |
| 1656 | struct sock *parent; | 1656 | struct sock *parent; |
| 1657 | 1657 | ||
| 1658 | + if (!sk) | ||
| 1659 | + return; | ||
| 1660 | + | ||
| 1658 | lock_sock(sk); | 1661 | lock_sock(sk); |
| 1659 | 1662 | ||
| 1660 | parent = bt_sk(sk)->parent; | 1663 | parent = bt_sk(sk)->parent; |
| @@ -233,10 +233,13 @@ static void esp_output_done(void *data, int err) | |||
| 233 | xfrm_dev_resume(skb); | 233 | xfrm_dev_resume(skb); |
| 234 | } else { | 234 | } else { |
| 235 | if (!err && | 235 | if (!err && |
| 236 | - x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP) | 236 | + x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP) { |
| 237 | - esp_output_tail_tcp(x, skb); | 237 | + err = esp_output_tail_tcp(x, skb); |
| 238 | - else | 238 | + if (err != -EINPROGRESS) |
| 239 | - xfrm_output_resume(skb->sk, skb, err); | 239 | + kfree_skb(skb); |
| 240 | + } else { | ||
| 241 | + xfrm_output_resume(skb_to_full_sk(skb), skb, err); | ||
| 242 | + } | ||
| 240 | } | 243 | } |
| 241 | } | 244 | } |
| 242 | 245 | ||
| @@ -269,10 +269,13 @@ static void esp_output_done(void *data, int err) | |||
| 269 | xfrm_dev_resume(skb); | 269 | xfrm_dev_resume(skb); |
| 270 | } else { | 270 | } else { |
| 271 | if (!err && | 271 | if (!err && |
| 272 | - x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP) | 272 | + x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP) { |
| 273 | - esp_output_tail_tcp(x, skb); | 273 | + err = esp_output_tail_tcp(x, skb); |
| 274 | - else | 274 | + if (err != -EINPROGRESS) |
| 275 | - xfrm_output_resume(skb->sk, skb, err); | 275 | + kfree_skb(skb); |
| 276 | + } else { | ||
| 277 | + xfrm_output_resume(skb_to_full_sk(skb), skb, err); | ||
| 278 | + } | ||
| 276 | } | 279 | } |
| 277 | } | 280 | } |
| 278 | 281 | ||
| @@ -377,6 +377,10 @@ static int ipv6_srh_rcv(struct sk_buff *skb) | |||
| 377 | hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb); | 377 | hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb); |
| 378 | 378 | ||
| 379 | idev = __in6_dev_get(skb->dev); | 379 | idev = __in6_dev_get(skb->dev); |
| 380 | + if (!idev) { | ||
| 381 | + kfree_skb(skb); | ||
| 382 | + return -1; | ||
| 383 | + } | ||
| 380 | 384 | ||
| 381 | accept_seg6 = net->ipv6.devconf_all->seg6_enabled; | 385 | accept_seg6 = net->ipv6.devconf_all->seg6_enabled; |
| 382 | if (accept_seg6 > idev->cnf.seg6_enabled) | 386 | if (accept_seg6 > idev->cnf.seg6_enabled) |
| @@ -133,11 +133,6 @@ static void fl_release(struct ip6_flowlabel *fl) | |||
| 133 | if (time_after(ttd, fl->expires)) | 133 | if (time_after(ttd, fl->expires)) |
| 134 | fl->expires = ttd; | 134 | fl->expires = ttd; |
| 135 | ttd = fl->expires; | 135 | ttd = fl->expires; |
| 136 | - if (fl->opt && fl->share == IPV6_FL_S_EXCL) { | ||
| 137 | - struct ipv6_txoptions *opt = fl->opt; | ||
| 138 | - fl->opt = NULL; | ||
| 139 | - kfree(opt); | ||
| 140 | - } | ||
| 141 | if (!timer_pending(&ip6_fl_gc_timer) || | 136 | if (!timer_pending(&ip6_fl_gc_timer) || |
| 142 | time_after(ip6_fl_gc_timer.expires, ttd)) | 137 | time_after(ip6_fl_gc_timer.expires, ttd)) |
| 143 | mod_timer(&ip6_fl_gc_timer, ttd); | 138 | mod_timer(&ip6_fl_gc_timer, ttd); |
| @@ -243,6 +243,8 @@ bool seg6_hmac_validate_skb(struct sk_buff *skb) | |||
| 243 | struct inet6_dev *idev; | 243 | struct inet6_dev *idev; |
| 244 | 244 | ||
| 245 | idev = __in6_dev_get(skb->dev); | 245 | idev = __in6_dev_get(skb->dev); |
| 246 | + if (!idev) | ||
| 247 | + return false; | ||
| 246 | 248 | ||
| 247 | srh = (struct ipv6_sr_hdr *)skb_transport_header(skb); | 249 | srh = (struct ipv6_sr_hdr *)skb_transport_header(skb); |
| 248 | 250 | ||
| @@ -48,7 +48,8 @@ static size_t seg6_lwt_headroom(struct seg6_iptunnel_encap *tuninfo) | |||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | struct seg6_lwt { | 50 | struct seg6_lwt { |
| 51 | - struct dst_cache cache; | 51 | + struct dst_cache cache_input; |
| 52 | + struct dst_cache cache_output; | ||
| 52 | struct seg6_iptunnel_encap tuninfo[]; | 53 | struct seg6_iptunnel_encap tuninfo[]; |
| 53 | }; | 54 | }; |
| 54 | 55 | ||
| @@ -486,7 +487,7 @@ static int seg6_input_core(struct net *net, struct sock *sk, | |||
| 486 | slwt = seg6_lwt_lwtunnel(lwtst); | 487 | slwt = seg6_lwt_lwtunnel(lwtst); |
| 487 | 488 | ||
| 488 | local_bh_disable(); | 489 | local_bh_disable(); |
| 489 | - dst = dst_cache_get(&slwt->cache); | 490 | + dst = dst_cache_get(&slwt->cache_input); |
| 490 | local_bh_enable(); | 491 | local_bh_enable(); |
| 491 | 492 | ||
| 492 | err = seg6_do_srh(skb, dst); | 493 | err = seg6_do_srh(skb, dst); |
| @@ -500,7 +501,7 @@ static int seg6_input_core(struct net *net, struct sock *sk, | |||
| 500 | /* cache only if we don't create a dst reference loop */ | 501 | /* cache only if we don't create a dst reference loop */ |
| 501 | if (!dst->error && lwtst != dst->lwtstate) { | 502 | if (!dst->error && lwtst != dst->lwtstate) { |
| 502 | local_bh_disable(); | 503 | local_bh_disable(); |
| 503 | - dst_cache_set_ip6(&slwt->cache, dst, | 504 | + dst_cache_set_ip6(&slwt->cache_input, dst, |
| 504 | &ipv6_hdr(skb)->saddr); | 505 | &ipv6_hdr(skb)->saddr); |
| 505 | local_bh_enable(); | 506 | local_bh_enable(); |
| 506 | } | 507 | } |
| @@ -560,7 +561,7 @@ static int seg6_output_core(struct net *net, struct sock *sk, | |||
| 560 | slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); | 561 | slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); |
| 561 | 562 | ||
| 562 | local_bh_disable(); | 563 | local_bh_disable(); |
| 563 | - dst = dst_cache_get(&slwt->cache); | 564 | + dst = dst_cache_get(&slwt->cache_output); |
| 564 | local_bh_enable(); | 565 | local_bh_enable(); |
| 565 | 566 | ||
| 566 | err = seg6_do_srh(skb, dst); | 567 | err = seg6_do_srh(skb, dst); |
| @@ -585,9 +586,12 @@ static int seg6_output_core(struct net *net, struct sock *sk, | |||
| 585 | goto drop; | 586 | goto drop; |
| 586 | } | 587 | } |
| 587 | 588 | ||
| 588 | - local_bh_disable(); | 589 | + /* cache only if we don't create a dst reference loop */ |
| 589 | - dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr); | 590 | + if (orig_dst->lwtstate != dst->lwtstate) { |
| 590 | - local_bh_enable(); | 591 | + local_bh_disable(); |
| 592 | + dst_cache_set_ip6(&slwt->cache_output, dst, &fl6.saddr); | ||
| 593 | + local_bh_enable(); | ||
| 594 | + } | ||
| 591 | 595 | ||
| 592 | err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); | 596 | err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); |
| 593 | if (unlikely(err)) | 597 | if (unlikely(err)) |
| @@ -694,11 +698,13 @@ static int seg6_build_state(struct net *net, struct nlattr *nla, | |||
| 694 | 698 | ||
| 695 | slwt = seg6_lwt_lwtunnel(newts); | 699 | slwt = seg6_lwt_lwtunnel(newts); |
| 696 | 700 | ||
| 697 | - err = dst_cache_init(&slwt->cache, GFP_ATOMIC); | 701 | + err = dst_cache_init(&slwt->cache_input, GFP_ATOMIC); |
| 698 | - if (err) { | 702 | + if (err) |
| 699 | - kfree(newts); | 703 | + goto err_free_newts; |
| 700 | - return err; | 704 | + |
| 701 | - } | 705 | + err = dst_cache_init(&slwt->cache_output, GFP_ATOMIC); |
| 706 | + if (err) | ||
| 707 | + goto err_destroy_input; | ||
| 702 | 708 | ||
| 703 | memcpy(&slwt->tuninfo, tuninfo, tuninfo_len); | 709 | memcpy(&slwt->tuninfo, tuninfo, tuninfo_len); |
| 704 | 710 | ||
| @@ -713,11 +719,20 @@ static int seg6_build_state(struct net *net, struct nlattr *nla, | |||
| 713 | *ts = newts; | 719 | *ts = newts; |
| 714 | 720 | ||
| 715 | return 0; | 721 | return 0; |
| 722 | + | ||
| 723 | +err_destroy_input: | ||
| 724 | + dst_cache_destroy(&slwt->cache_input); | ||
| 725 | +err_free_newts: | ||
| 726 | + kfree(newts); | ||
| 727 | + return err; | ||
| 716 | } | 728 | } |
| 717 | 729 | ||
| 718 | static void seg6_destroy_state(struct lwtunnel_state *lwt) | 730 | static void seg6_destroy_state(struct lwtunnel_state *lwt) |
| 719 | { | 731 | { |
| 720 | - dst_cache_destroy(&seg6_lwt_lwtunnel(lwt)->cache); | 732 | + struct seg6_lwt *slwt = seg6_lwt_lwtunnel(lwt); |
| 733 | + | ||
| 734 | + dst_cache_destroy(&slwt->cache_input); | ||
| 735 | + dst_cache_destroy(&slwt->cache_output); | ||
| 721 | } | 736 | } |
| 722 | 737 | ||
| 723 | static int seg6_fill_encap_info(struct sk_buff *skb, | 738 | static int seg6_fill_encap_info(struct sk_buff *skb, |
| @@ -3533,7 +3533,7 @@ static int set_sadb_kmaddress(struct sk_buff *skb, const struct xfrm_kmaddress * | |||
| 3533 | 3533 | ||
| 3534 | static int set_ipsecrequest(struct sk_buff *skb, | 3534 | static int set_ipsecrequest(struct sk_buff *skb, |
| 3535 | uint8_t proto, uint8_t mode, int level, | 3535 | uint8_t proto, uint8_t mode, int level, |
| 3536 | - uint32_t reqid, uint8_t family, | 3536 | + uint32_t reqid, sa_family_t family, |
| 3537 | const xfrm_address_t *src, const xfrm_address_t *dst) | 3537 | const xfrm_address_t *src, const xfrm_address_t *dst) |
| 3538 | { | 3538 | { |
| 3539 | struct sadb_x_ipsecrequest *rq; | 3539 | struct sadb_x_ipsecrequest *rq; |
| @@ -3598,12 +3598,17 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, | |||
| 3598 | 3598 | ||
| 3599 | /* ipsecrequests */ | 3599 | /* ipsecrequests */ |
| 3600 | for (i = 0, mp = m; i < num_bundles; i++, mp++) { | 3600 | for (i = 0, mp = m; i < num_bundles; i++, mp++) { |
| 3601 | - /* old locator pair */ | 3601 | + int pair_size; |
| 3602 | - size_pol += sizeof(struct sadb_x_ipsecrequest) + | 3602 | + |
| 3603 | - pfkey_sockaddr_pair_size(mp->old_family); | 3603 | + pair_size = pfkey_sockaddr_pair_size(mp->old_family); |
| 3604 | - /* new locator pair */ | 3604 | + if (!pair_size) |
| 3605 | - size_pol += sizeof(struct sadb_x_ipsecrequest) + | 3605 | + return -EINVAL; |
| 3606 | - pfkey_sockaddr_pair_size(mp->new_family); | 3606 | + size_pol += sizeof(struct sadb_x_ipsecrequest) + pair_size; |
| 3607 | + | ||
| 3608 | + pair_size = pfkey_sockaddr_pair_size(mp->new_family); | ||
| 3609 | + if (!pair_size) | ||
| 3610 | + return -EINVAL; | ||
| 3611 | + size_pol += sizeof(struct sadb_x_ipsecrequest) + pair_size; | ||
| 3607 | } | 3612 | } |
| 3608 | 3613 | ||
| 3609 | size += sizeof(struct sadb_msg) + size_pol; | 3614 | size += sizeof(struct sadb_msg) + size_pol; |
| @@ -635,11 +635,15 @@ static int exp_seq_show(struct seq_file *s, void *v) | |||
| 635 | { | 635 | { |
| 636 | struct nf_conntrack_expect *expect; | 636 | struct nf_conntrack_expect *expect; |
| 637 | struct nf_conntrack_helper *helper; | 637 | struct nf_conntrack_helper *helper; |
| 638 | + struct net *net = seq_file_net(s); | ||
| 638 | struct hlist_node *n = v; | 639 | struct hlist_node *n = v; |
| 639 | char *delim = ""; | 640 | char *delim = ""; |
| 640 | 641 | ||
| 641 | expect = hlist_entry(n, struct nf_conntrack_expect, hnode); | 642 | expect = hlist_entry(n, struct nf_conntrack_expect, hnode); |
| 642 | 643 | ||
| 644 | + if (!net_eq(nf_ct_exp_net(expect), net)) | ||
| 645 | + return 0; | ||
| 646 | + | ||
| 643 | if (expect->timeout.function) | 647 | if (expect->timeout.function) |
| 644 | seq_printf(s, "%ld ", timer_pending(&expect->timeout) | 648 | seq_printf(s, "%ld ", timer_pending(&expect->timeout) |
| 645 | ? (long)(expect->timeout.expires - jiffies)/HZ : 0); | 649 | ? (long)(expect->timeout.expires - jiffies)/HZ : 0); |
| @@ -885,8 +885,8 @@ struct ctnetlink_filter { | |||
| 885 | }; | 885 | }; |
| 886 | 886 | ||
| 887 | static const struct nla_policy cta_filter_nla_policy[CTA_FILTER_MAX + 1] = { | 887 | static const struct nla_policy cta_filter_nla_policy[CTA_FILTER_MAX + 1] = { |
| 888 | - [CTA_FILTER_ORIG_FLAGS] = { .type = NLA_U32 }, | 888 | + [CTA_FILTER_ORIG_FLAGS] = NLA_POLICY_MASK(NLA_U32, CTA_FILTER_F_ALL), |
| 889 | - [CTA_FILTER_REPLY_FLAGS] = { .type = NLA_U32 }, | 889 | + [CTA_FILTER_REPLY_FLAGS] = NLA_POLICY_MASK(NLA_U32, CTA_FILTER_F_ALL), |
| 890 | }; | 890 | }; |
| 891 | 891 | ||
| 892 | static int ctnetlink_parse_filter(const struct nlattr *attr, | 892 | static int ctnetlink_parse_filter(const struct nlattr *attr, |
| @@ -900,17 +900,11 @@ static int ctnetlink_parse_filter(const struct nlattr *attr, | |||
| 900 | if (ret) | 900 | if (ret) |
| 901 | return ret; | 901 | return ret; |
| 902 | 902 | ||
| 903 | - if (tb[CTA_FILTER_ORIG_FLAGS]) { | 903 | + if (tb[CTA_FILTER_ORIG_FLAGS]) |
| 904 | filter->orig_flags = nla_get_u32(tb[CTA_FILTER_ORIG_FLAGS]); | 904 | filter->orig_flags = nla_get_u32(tb[CTA_FILTER_ORIG_FLAGS]); |
| 905 | - if (filter->orig_flags & ~CTA_FILTER_F_ALL) | ||
| 906 | - return -EOPNOTSUPP; | ||
| 907 | - } | ||
| 908 | 905 | ||
| 909 | - if (tb[CTA_FILTER_REPLY_FLAGS]) { | 906 | + if (tb[CTA_FILTER_REPLY_FLAGS]) |
| 910 | filter->reply_flags = nla_get_u32(tb[CTA_FILTER_REPLY_FLAGS]); | 907 | filter->reply_flags = nla_get_u32(tb[CTA_FILTER_REPLY_FLAGS]); |
| 911 | - if (filter->reply_flags & ~CTA_FILTER_F_ALL) | ||
| 912 | - return -EOPNOTSUPP; | ||
| 913 | - } | ||
| 914 | 908 | ||
| 915 | return 0; | 909 | return 0; |
| 916 | } | 910 | } |
| @@ -2620,7 +2614,7 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = { | |||
| 2620 | [CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING, | 2614 | [CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING, |
| 2621 | .len = NF_CT_HELPER_NAME_LEN - 1 }, | 2615 | .len = NF_CT_HELPER_NAME_LEN - 1 }, |
| 2622 | [CTA_EXPECT_ZONE] = { .type = NLA_U16 }, | 2616 | [CTA_EXPECT_ZONE] = { .type = NLA_U16 }, |
| 2623 | - [CTA_EXPECT_FLAGS] = { .type = NLA_U32 }, | 2617 | + [CTA_EXPECT_FLAGS] = NLA_POLICY_MASK(NLA_BE32, NF_CT_EXPECT_MASK), |
| 2624 | [CTA_EXPECT_CLASS] = { .type = NLA_U32 }, | 2618 | [CTA_EXPECT_CLASS] = { .type = NLA_U32 }, |
| 2625 | [CTA_EXPECT_NAT] = { .type = NLA_NESTED }, | 2619 | [CTA_EXPECT_NAT] = { .type = NLA_NESTED }, |
| 2626 | [CTA_EXPECT_FN] = { .type = NLA_NUL_STRING }, | 2620 | [CTA_EXPECT_FN] = { .type = NLA_NUL_STRING }, |
| @@ -1384,9 +1384,9 @@ static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla, | |||
| 1384 | } | 1384 | } |
| 1385 | 1385 | ||
| 1386 | static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = { | 1386 | static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = { |
| 1387 | - [CTA_PROTOINFO_TCP_STATE] = { .type = NLA_U8 }, | 1387 | + [CTA_PROTOINFO_TCP_STATE] = NLA_POLICY_MAX(NLA_U8, TCP_CONNTRACK_SYN_SENT2), |
| 1388 | - [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = { .type = NLA_U8 }, | 1388 | + [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = NLA_POLICY_MAX(NLA_U8, TCP_MAX_WSCALE), |
| 1389 | - [CTA_PROTOINFO_TCP_WSCALE_REPLY] = { .type = NLA_U8 }, | 1389 | + [CTA_PROTOINFO_TCP_WSCALE_REPLY] = NLA_POLICY_MAX(NLA_U8, TCP_MAX_WSCALE), |
| 1390 | [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL] = { .len = sizeof(struct nf_ct_tcp_flags) }, | 1390 | [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL] = { .len = sizeof(struct nf_ct_tcp_flags) }, |
| 1391 | [CTA_PROTOINFO_TCP_FLAGS_REPLY] = { .len = sizeof(struct nf_ct_tcp_flags) }, | 1391 | [CTA_PROTOINFO_TCP_FLAGS_REPLY] = { .len = sizeof(struct nf_ct_tcp_flags) }, |
| 1392 | }; | 1392 | }; |
| @@ -1413,10 +1413,6 @@ static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct) | |||
| 1413 | if (err < 0) | 1413 | if (err < 0) |
| 1414 | return err; | 1414 | return err; |
| 1415 | 1415 | ||
| 1416 | - if (tb[CTA_PROTOINFO_TCP_STATE] && | ||
| 1417 | - nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]) >= TCP_CONNTRACK_MAX) | ||
| 1418 | - return -EINVAL; | ||
| 1419 | - | ||
| 1420 | spin_lock_bh(&ct->lock); | 1416 | spin_lock_bh(&ct->lock); |
| 1421 | if (tb[CTA_PROTOINFO_TCP_STATE]) | 1417 | if (tb[CTA_PROTOINFO_TCP_STATE]) |
| 1422 | ct->proto.tcp.state = nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]); | 1418 | ct->proto.tcp.state = nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]); |
| @@ -501,6 +501,17 @@ int xt_check_match(struct xt_mtchk_param *par, | |||
| 501 | par->match->table, par->table); | 501 | par->match->table, par->table); |
| 502 | return -EINVAL; | 502 | return -EINVAL; |
| 503 | } | 503 | } |
| 504 | + | ||
| 505 | + /* NFPROTO_UNSPEC implies NF_INET_* hooks which do not overlap with | ||
| 506 | + * NF_ARP_IN,OUT,FORWARD, allow explicit extensions with NFPROTO_ARP | ||
| 507 | + * support. | ||
| 508 | + */ | ||
| 509 | + if (par->family == NFPROTO_ARP && | ||
| 510 | + par->match->family != NFPROTO_ARP) { | ||
| 511 | + pr_info_ratelimited("%s_tables: %s match: not valid for this family\n", | ||
| 512 | + xt_prefix[par->family], par->match->name); | ||
| 513 | + return -EINVAL; | ||
| 514 | + } | ||
| 504 | if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) { | 515 | if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) { |
| 505 | char used[64], allow[64]; | 516 | char used[64], allow[64]; |
| 506 | 517 | ||
| @@ -1016,6 +1027,18 @@ int xt_check_target(struct xt_tgchk_param *par, | |||
| 1016 | par->target->table, par->table); | 1027 | par->target->table, par->table); |
| 1017 | return -EINVAL; | 1028 | return -EINVAL; |
| 1018 | } | 1029 | } |
| 1030 | + | ||
| 1031 | + /* NFPROTO_UNSPEC implies NF_INET_* hooks which do not overlap with | ||
| 1032 | + * NF_ARP_IN,OUT,FORWARD, allow explicit extensions with NFPROTO_ARP | ||
| 1033 | + * support. | ||
| 1034 | + */ | ||
| 1035 | + if (par->family == NFPROTO_ARP && | ||
| 1036 | + par->target->family != NFPROTO_ARP) { | ||
| 1037 | + pr_info_ratelimited("%s_tables: %s target: not valid for this family\n", | ||
| 1038 | + xt_prefix[par->family], par->target->name); | ||
| 1039 | + return -EINVAL; | ||
| 1040 | + } | ||
| 1041 | + | ||
| 1019 | if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) { | 1042 | if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) { |
| 1020 | char used[64], allow[64]; | 1043 | char used[64], allow[64]; |
| 1021 | 1044 | ||
| @@ -239,14 +239,14 @@ int ieee80211_radiotap_iterator_next( | |||
| 239 | default: | 239 | default: |
| 240 | if (!iterator->current_namespace || | 240 | if (!iterator->current_namespace || |
| 241 | iterator->_arg_index >= iterator->current_namespace->n_bits) { | 241 | iterator->_arg_index >= iterator->current_namespace->n_bits) { |
| 242 | - if (iterator->current_namespace == &radiotap_ns) | ||
| 243 | - return -ENOENT; | ||
| 244 | align = 0; | 242 | align = 0; |
| 245 | } else { | 243 | } else { |
| 246 | align = iterator->current_namespace->align_size[iterator->_arg_index].align; | 244 | align = iterator->current_namespace->align_size[iterator->_arg_index].align; |
| 247 | size = iterator->current_namespace->align_size[iterator->_arg_index].size; | 245 | size = iterator->current_namespace->align_size[iterator->_arg_index].size; |
| 248 | } | 246 | } |
| 249 | if (!align) { | 247 | if (!align) { |
| 248 | + if (iterator->current_namespace == &radiotap_ns) | ||
| 249 | + return -ENOENT; | ||
| 250 | /* skip all subsequent data */ | 250 | /* skip all subsequent data */ |
| 251 | iterator->_arg = iterator->_next_ns_data; | 251 | iterator->_arg = iterator->_next_ns_data; |
| 252 | /* give up on this namespace */ | 252 | /* give up on this namespace */ |
| @@ -3588,6 +3588,8 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, | |||
| 3588 | return err; | 3588 | return err; |
| 3589 | } | 3589 | } |
| 3590 | upe->hard = !!hard; | 3590 | upe->hard = !!hard; |
| 3591 | + /* clear the padding bytes */ | ||
| 3592 | + memset_after(upe, 0, hard); | ||
| 3591 | 3593 | ||
| 3592 | nlmsg_end(skb, nlh); | 3594 | nlmsg_end(skb, nlh); |
| 3593 | return 0; | 3595 | return 0; |
| @@ -3745,6 +3747,7 @@ static int build_report(struct sk_buff *skb, u8 proto, | |||
| 3745 | return -EMSGSIZE; | 3747 | return -EMSGSIZE; |
| 3746 | 3748 | ||
| 3747 | ur = nlmsg_data(nlh); | 3749 | ur = nlmsg_data(nlh); |
| 3750 | + memset(ur, 0, sizeof(*ur)); | ||
| 3748 | ur->proto = proto; | 3751 | ur->proto = proto; |
| 3749 | memcpy(&ur->sel, sel, sizeof(ur->sel)); | 3752 | memcpy(&ur->sel, sel, sizeof(ur->sel)); |
| 3750 | 3753 | ||
| @@ -15,7 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | -#define CT_PTP_NUM 4 /* num of device page table pages */ | 18 | +#define CT_PTP_NUM 1 /* num of device page table pages */ |
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | 21 | ||
已提供测试报告