已合并
修复CVE漏洞 #269
chenyangw创建于 2月25日
修复CVE漏洞 #269
已合并
共 16 个文件变更+181-35
| @@ -257,13 +257,12 @@ static void eeh_pe_report_edev(struct eeh_dev *edev, eeh_report_fn fn, | |||
| 257 | struct pci_driver *driver; | 257 | struct pci_driver *driver; |
| 258 | enum pci_ers_result new_result; | 258 | enum pci_ers_result new_result; |
| 259 | 259 | ||
| 260 | - pci_lock_rescan_remove(); | ||
| 261 | pdev = edev->pdev; | 260 | pdev = edev->pdev; |
| 262 | if (pdev) | 261 | if (pdev) |
| 263 | get_device(&pdev->dev); | 262 | get_device(&pdev->dev); |
| 264 | - pci_unlock_rescan_remove(); | ||
| 265 | if (!pdev) { | 263 | if (!pdev) { |
| 266 | eeh_edev_info(edev, "no device"); | 264 | eeh_edev_info(edev, "no device"); |
| 265 | + *result = PCI_ERS_RESULT_DISCONNECT; | ||
| 267 | return; | 266 | return; |
| 268 | } | 267 | } |
| 269 | device_lock(&pdev->dev); | 268 | device_lock(&pdev->dev); |
| @@ -304,8 +303,9 @@ static void eeh_pe_report(const char *name, struct eeh_pe *root, | |||
| 304 | struct eeh_dev *edev, *tmp; | 303 | struct eeh_dev *edev, *tmp; |
| 305 | 304 | ||
| 306 | pr_info("EEH: Beginning: '%s'\n", name); | 305 | pr_info("EEH: Beginning: '%s'\n", name); |
| 307 | - eeh_for_each_pe(root, pe) eeh_pe_for_each_dev(pe, edev, tmp) | 306 | + eeh_for_each_pe(root, pe) |
| 308 | - eeh_pe_report_edev(edev, fn, result); | 307 | + eeh_pe_for_each_dev(pe, edev, tmp) |
| 308 | + eeh_pe_report_edev(edev, fn, result); | ||
| 309 | if (result) | 309 | if (result) |
| 310 | pr_info("EEH: Finished:'%s' with aggregate recovery state:'%s'\n", | 310 | pr_info("EEH: Finished:'%s' with aggregate recovery state:'%s'\n", |
| 311 | name, pci_ers_result_name(*result)); | 311 | name, pci_ers_result_name(*result)); |
| @@ -383,6 +383,8 @@ static void eeh_dev_restore_state(struct eeh_dev *edev, void *userdata) | |||
| 383 | if (!edev) | 383 | if (!edev) |
| 384 | return; | 384 | return; |
| 385 | 385 | ||
| 386 | + pci_lock_rescan_remove(); | ||
| 387 | + | ||
| 386 | /* | 388 | /* |
| 387 | * The content in the config space isn't saved because | 389 | * The content in the config space isn't saved because |
| 388 | * the blocked config space on some adapters. We have | 390 | * the blocked config space on some adapters. We have |
| @@ -393,14 +395,19 @@ static void eeh_dev_restore_state(struct eeh_dev *edev, void *userdata) | |||
| 393 | if (list_is_last(&edev->entry, &edev->pe->edevs)) | 395 | if (list_is_last(&edev->entry, &edev->pe->edevs)) |
| 394 | eeh_pe_restore_bars(edev->pe); | 396 | eeh_pe_restore_bars(edev->pe); |
| 395 | 397 | ||
| 398 | + pci_unlock_rescan_remove(); | ||
| 396 | return; | 399 | return; |
| 397 | } | 400 | } |
| 398 | 401 | ||
| 399 | pdev = eeh_dev_to_pci_dev(edev); | 402 | pdev = eeh_dev_to_pci_dev(edev); |
| 400 | - if (!pdev) | 403 | + if (!pdev) { |
| 404 | + pci_unlock_rescan_remove(); | ||
| 401 | return; | 405 | return; |
| 406 | + } | ||
| 402 | 407 | ||
| 403 | pci_restore_state(pdev); | 408 | pci_restore_state(pdev); |
| 409 | + | ||
| 410 | + pci_unlock_rescan_remove(); | ||
| 404 | } | 411 | } |
| 405 | 412 | ||
| 406 | /** | 413 | /** |
| @@ -647,9 +654,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus, | |||
| 647 | if (any_passed || driver_eeh_aware || (pe->type & EEH_PE_VF)) { | 654 | if (any_passed || driver_eeh_aware || (pe->type & EEH_PE_VF)) { |
| 648 | eeh_pe_dev_traverse(pe, eeh_rmv_device, rmv_data); | 655 | eeh_pe_dev_traverse(pe, eeh_rmv_device, rmv_data); |
| 649 | } else { | 656 | } else { |
| 650 | - pci_lock_rescan_remove(); | ||
| 651 | pci_hp_remove_devices(bus); | 657 | pci_hp_remove_devices(bus); |
| 652 | - pci_unlock_rescan_remove(); | ||
| 653 | } | 658 | } |
| 654 | 659 | ||
| 655 | /* | 660 | /* |
| @@ -665,8 +670,6 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus, | |||
| 665 | if (rc) | 670 | if (rc) |
| 666 | return rc; | 671 | return rc; |
| 667 | 672 | ||
| 668 | - pci_lock_rescan_remove(); | ||
| 669 | - | ||
| 670 | /* Restore PE */ | 673 | /* Restore PE */ |
| 671 | eeh_ops->configure_bridge(pe); | 674 | eeh_ops->configure_bridge(pe); |
| 672 | eeh_pe_restore_bars(pe); | 675 | eeh_pe_restore_bars(pe); |
| @@ -674,7 +677,6 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus, | |||
| 674 | /* Clear frozen state */ | 677 | /* Clear frozen state */ |
| 675 | rc = eeh_clear_pe_frozen_state(pe, false); | 678 | rc = eeh_clear_pe_frozen_state(pe, false); |
| 676 | if (rc) { | 679 | if (rc) { |
| 677 | - pci_unlock_rescan_remove(); | ||
| 678 | return rc; | 680 | return rc; |
| 679 | } | 681 | } |
| 680 | 682 | ||
| @@ -709,7 +711,6 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus, | |||
| 709 | pe->tstamp = tstamp; | 711 | pe->tstamp = tstamp; |
| 710 | pe->freeze_count = cnt; | 712 | pe->freeze_count = cnt; |
| 711 | 713 | ||
| 712 | - pci_unlock_rescan_remove(); | ||
| 713 | return 0; | 714 | return 0; |
| 714 | } | 715 | } |
| 715 | 716 | ||
| @@ -843,10 +844,13 @@ void eeh_handle_normal_event(struct eeh_pe *pe) | |||
| 843 | {LIST_HEAD_INIT(rmv_data.removed_vf_list), 0}; | 844 | {LIST_HEAD_INIT(rmv_data.removed_vf_list), 0}; |
| 844 | int devices = 0; | 845 | int devices = 0; |
| 845 | 846 | ||
| 847 | + pci_lock_rescan_remove(); | ||
| 848 | + | ||
| 846 | bus = eeh_pe_bus_get(pe); | 849 | bus = eeh_pe_bus_get(pe); |
| 847 | if (!bus) { | 850 | if (!bus) { |
| 848 | pr_err("%s: Cannot find PCI bus for PHB#%x-PE#%x\n", | 851 | pr_err("%s: Cannot find PCI bus for PHB#%x-PE#%x\n", |
| 849 | __func__, pe->phb->global_number, pe->addr); | 852 | __func__, pe->phb->global_number, pe->addr); |
| 853 | + pci_unlock_rescan_remove(); | ||
| 850 | return; | 854 | return; |
| 851 | } | 855 | } |
| 852 | 856 | ||
| @@ -1085,10 +1089,15 @@ void eeh_handle_normal_event(struct eeh_pe *pe) | |||
| 1085 | eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true); | 1089 | eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true); |
| 1086 | eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); | 1090 | eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); |
| 1087 | 1091 | ||
| 1088 | - pci_lock_rescan_remove(); | 1092 | + bus = eeh_pe_bus_get(pe); |
| 1089 | - pci_hp_remove_devices(bus); | 1093 | + if (bus) |
| 1090 | - pci_unlock_rescan_remove(); | 1094 | + pci_hp_remove_devices(bus); |
| 1095 | + else | ||
| 1096 | + pr_err("%s: PCI bus for PHB#%x-PE#%x disappeared\n", | ||
| 1097 | + __func__, pe->phb->global_number, pe->addr); | ||
| 1098 | + | ||
| 1091 | /* The passed PE should no longer be used */ | 1099 | /* The passed PE should no longer be used */ |
| 1100 | + pci_unlock_rescan_remove(); | ||
| 1092 | return; | 1101 | return; |
| 1093 | } | 1102 | } |
| 1094 | 1103 | ||
| @@ -1105,6 +1114,8 @@ void eeh_handle_normal_event(struct eeh_pe *pe) | |||
| 1105 | eeh_clear_slot_attention(edev->pdev); | 1114 | eeh_clear_slot_attention(edev->pdev); |
| 1106 | 1115 | ||
| 1107 | eeh_pe_state_clear(pe, EEH_PE_RECOVERING, true); | 1116 | eeh_pe_state_clear(pe, EEH_PE_RECOVERING, true); |
| 1117 | + | ||
| 1118 | + pci_unlock_rescan_remove(); | ||
| 1108 | } | 1119 | } |
| 1109 | 1120 | ||
| 1110 | /** | 1121 | /** |
| @@ -1123,6 +1134,7 @@ void eeh_handle_special_event(void) | |||
| 1123 | unsigned long flags; | 1134 | unsigned long flags; |
| 1124 | int rc; | 1135 | int rc; |
| 1125 | 1136 | ||
| 1137 | + pci_lock_rescan_remove(); | ||
| 1126 | 1138 | ||
| 1127 | do { | 1139 | do { |
| 1128 | rc = eeh_ops->next_error(&pe); | 1140 | rc = eeh_ops->next_error(&pe); |
| @@ -1162,10 +1174,12 @@ void eeh_handle_special_event(void) | |||
| 1162 | 1174 | ||
| 1163 | break; | 1175 | break; |
| 1164 | case EEH_NEXT_ERR_NONE: | 1176 | case EEH_NEXT_ERR_NONE: |
| 1177 | + pci_unlock_rescan_remove(); | ||
| 1165 | return; | 1178 | return; |
| 1166 | default: | 1179 | default: |
| 1167 | pr_warn("%s: Invalid value %d from next_error()\n", | 1180 | pr_warn("%s: Invalid value %d from next_error()\n", |
| 1168 | __func__, rc); | 1181 | __func__, rc); |
| 1182 | + pci_unlock_rescan_remove(); | ||
| 1169 | return; | 1183 | return; |
| 1170 | } | 1184 | } |
| 1171 | 1185 | ||
| @@ -1177,7 +1191,9 @@ void eeh_handle_special_event(void) | |||
| 1177 | if (rc == EEH_NEXT_ERR_FROZEN_PE || | 1191 | if (rc == EEH_NEXT_ERR_FROZEN_PE || |
| 1178 | rc == EEH_NEXT_ERR_FENCED_PHB) { | 1192 | rc == EEH_NEXT_ERR_FENCED_PHB) { |
| 1179 | eeh_pe_state_mark(pe, EEH_PE_RECOVERING); | 1193 | eeh_pe_state_mark(pe, EEH_PE_RECOVERING); |
| 1194 | + pci_unlock_rescan_remove(); | ||
| 1180 | eeh_handle_normal_event(pe); | 1195 | eeh_handle_normal_event(pe); |
| 1196 | + pci_lock_rescan_remove(); | ||
| 1181 | } else { | 1197 | } else { |
| 1182 | eeh_for_each_pe(pe, tmp_pe) | 1198 | eeh_for_each_pe(pe, tmp_pe) |
| 1183 | eeh_pe_for_each_dev(tmp_pe, edev, tmp_edev) | 1199 | eeh_pe_for_each_dev(tmp_pe, edev, tmp_edev) |
| @@ -1190,7 +1206,6 @@ void eeh_handle_special_event(void) | |||
| 1190 | eeh_report_failure, NULL); | 1206 | eeh_report_failure, NULL); |
| 1191 | eeh_set_channel_state(pe, pci_channel_io_perm_failure); | 1207 | eeh_set_channel_state(pe, pci_channel_io_perm_failure); |
| 1192 | 1208 | ||
| 1193 | - pci_lock_rescan_remove(); | ||
| 1194 | list_for_each_entry(hose, &hose_list, list_node) { | 1209 | list_for_each_entry(hose, &hose_list, list_node) { |
| 1195 | phb_pe = eeh_phb_pe_get(hose); | 1210 | phb_pe = eeh_phb_pe_get(hose); |
| 1196 | if (!phb_pe || | 1211 | if (!phb_pe || |
| @@ -1209,7 +1224,6 @@ void eeh_handle_special_event(void) | |||
| 1209 | } | 1224 | } |
| 1210 | pci_hp_remove_devices(bus); | 1225 | pci_hp_remove_devices(bus); |
| 1211 | } | 1226 | } |
| 1212 | - pci_unlock_rescan_remove(); | ||
| 1213 | } | 1227 | } |
| 1214 | 1228 | ||
| 1215 | /* | 1229 | /* |
| @@ -1219,4 +1233,6 @@ void eeh_handle_special_event(void) | |||
| 1219 | if (rc == EEH_NEXT_ERR_DEAD_IOC) | 1233 | if (rc == EEH_NEXT_ERR_DEAD_IOC) |
| 1220 | break; | 1234 | break; |
| 1221 | } while (rc != EEH_NEXT_ERR_NONE); | 1235 | } while (rc != EEH_NEXT_ERR_NONE); |
| 1236 | + | ||
| 1237 | + pci_unlock_rescan_remove(); | ||
| 1222 | } | 1238 | } |
| @@ -671,10 +671,12 @@ static void eeh_bridge_check_link(struct eeh_dev *edev) | |||
| 671 | eeh_ops->write_config(edev, cap + PCI_EXP_LNKCTL, 2, val); | 671 | eeh_ops->write_config(edev, cap + PCI_EXP_LNKCTL, 2, val); |
| 672 | 672 | ||
| 673 | /* Check link */ | 673 | /* Check link */ |
| 674 | - if (!edev->pdev->link_active_reporting) { | 674 | + if (edev->pdev) { |
| 675 | - eeh_edev_dbg(edev, "No link reporting capability\n"); | 675 | + if (!edev->pdev->link_active_reporting) { |
| 676 | - msleep(1000); | 676 | + eeh_edev_dbg(edev, "No link reporting capability\n"); |
| 677 | - return; | 677 | + msleep(1000); |
| 678 | + return; | ||
| 679 | + } | ||
| 678 | } | 680 | } |
| 679 | 681 | ||
| 680 | /* Wait the link is up until timeout (5s) */ | 682 | /* Wait the link is up until timeout (5s) */ |
| @@ -319,5 +319,8 @@ void ccp5_debugfs_setup(struct ccp_device *ccp) | |||
| 319 | 319 | ||
| 320 | void ccp5_debugfs_destroy(void) | 320 | void ccp5_debugfs_destroy(void) |
| 321 | { | 321 | { |
| 322 | + mutex_lock(&ccp_debugfs_lock); | ||
| 322 | debugfs_remove_recursive(ccp_debugfs_dir); | 323 | debugfs_remove_recursive(ccp_debugfs_dir); |
| 324 | + ccp_debugfs_dir = NULL; | ||
| 325 | + mutex_unlock(&ccp_debugfs_lock); | ||
| 323 | } | 326 | } |
| @@ -159,9 +159,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
| 159 | int len; | 159 | int len; |
| 160 | unsigned char *data; | 160 | unsigned char *data; |
| 161 | __u32 seq_recv; | 161 | __u32 seq_recv; |
| 162 | - | 162 | + struct rtable *rt = NULL; |
| 163 | - | ||
| 164 | - struct rtable *rt; | ||
| 165 | struct net_device *tdev; | 163 | struct net_device *tdev; |
| 166 | struct iphdr *iph; | 164 | struct iphdr *iph; |
| 167 | int max_headroom; | 165 | int max_headroom; |
| @@ -179,16 +177,20 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
| 179 | 177 | ||
| 180 | if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { | 178 | if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { |
| 181 | struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); | 179 | struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); |
| 182 | - if (!new_skb) { | 180 | + |
| 183 | - ip_rt_put(rt); | 181 | + if (!new_skb) |
| 184 | goto tx_error; | 182 | goto tx_error; |
| 185 | - } | 183 | + |
| 186 | if (skb->sk) | 184 | if (skb->sk) |
| 187 | skb_set_owner_w(new_skb, skb->sk); | 185 | skb_set_owner_w(new_skb, skb->sk); |
| 188 | consume_skb(skb); | 186 | consume_skb(skb); |
| 189 | skb = new_skb; | 187 | skb = new_skb; |
| 190 | } | 188 | } |
| 191 | 189 | ||
| 190 | + /* Ensure we can safely access protocol field and LCP code */ | ||
| 191 | + if (!pskb_may_pull(skb, 3)) | ||
| 192 | + goto tx_error; | ||
| 193 | + | ||
| 192 | data = skb->data; | 194 | data = skb->data; |
| 193 | islcp = ((data[0] << 8) + data[1]) == PPP_LCP && 1 <= data[2] && data[2] <= 7; | 195 | islcp = ((data[0] << 8) + data[1]) == PPP_LCP && 1 <= data[2] && data[2] <= 7; |
| 194 | 196 | ||
| @@ -262,6 +264,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
| 262 | return 1; | 264 | return 1; |
| 263 | 265 | ||
| 264 | tx_error: | 266 | tx_error: |
| 267 | + ip_rt_put(rt); | ||
| 265 | kfree_skb(skb); | 268 | kfree_skb(skb); |
| 266 | return 1; | 269 | return 1; |
| 267 | } | 270 | } |
| @@ -1319,6 +1319,10 @@ EXPORT_SYMBOL(ath11k_hal_srng_init); | |||
| 1319 | void ath11k_hal_srng_deinit(struct ath11k_base *ab) | 1319 | void ath11k_hal_srng_deinit(struct ath11k_base *ab) |
| 1320 | { | 1320 | { |
| 1321 | struct ath11k_hal *hal = &ab->hal; | 1321 | struct ath11k_hal *hal = &ab->hal; |
| 1322 | + int i; | ||
| 1323 | + | ||
| 1324 | + for (i = 0; i < HAL_SRNG_RING_ID_MAX; i++) | ||
| 1325 | + ab->hal.srng_list[i].initialized = 0; | ||
| 1322 | 1326 | ||
| 1323 | ath11k_hal_unregister_srng_key(ab); | 1327 | ath11k_hal_unregister_srng_key(ab); |
| 1324 | ath11k_hal_free_cont_rdp(ab); | 1328 | ath11k_hal_free_cont_rdp(ab); |
| @@ -1048,9 +1048,11 @@ static void iwl_bg_restart(struct work_struct *data) | |||
| 1048 | * | 1048 | * |
| 1049 | *****************************************************************************/ | 1049 | *****************************************************************************/ |
| 1050 | 1050 | ||
| 1051 | -static void iwl_setup_deferred_work(struct iwl_priv *priv) | 1051 | +static int iwl_setup_deferred_work(struct iwl_priv *priv) |
| 1052 | { | 1052 | { |
| 1053 | priv->workqueue = alloc_ordered_workqueue(DRV_NAME, 0); | 1053 | priv->workqueue = alloc_ordered_workqueue(DRV_NAME, 0); |
| 1054 | + if (!priv->workqueue) | ||
| 1055 | + return -ENOMEM; | ||
| 1054 | 1056 | ||
| 1055 | INIT_WORK(&priv->restart, iwl_bg_restart); | 1057 | INIT_WORK(&priv->restart, iwl_bg_restart); |
| 1056 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); | 1058 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); |
| @@ -1067,6 +1069,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
| 1067 | timer_setup(&priv->statistics_periodic, iwl_bg_statistics_periodic, 0); | 1069 | timer_setup(&priv->statistics_periodic, iwl_bg_statistics_periodic, 0); |
| 1068 | 1070 | ||
| 1069 | timer_setup(&priv->ucode_trace, iwl_bg_ucode_trace, 0); | 1071 | timer_setup(&priv->ucode_trace, iwl_bg_ucode_trace, 0); |
| 1072 | + | ||
| 1073 | + return 0; | ||
| 1070 | } | 1074 | } |
| 1071 | 1075 | ||
| 1072 | void iwl_cancel_deferred_work(struct iwl_priv *priv) | 1076 | void iwl_cancel_deferred_work(struct iwl_priv *priv) |
| @@ -1456,7 +1460,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
| 1456 | /******************** | 1460 | /******************** |
| 1457 | * 6. Setup services | 1461 | * 6. Setup services |
| 1458 | ********************/ | 1462 | ********************/ |
| 1459 | - iwl_setup_deferred_work(priv); | 1463 | + if (iwl_setup_deferred_work(priv)) |
| 1464 | + goto out_uninit_drv; | ||
| 1465 | + | ||
| 1460 | iwl_setup_rx_handlers(priv); | 1466 | iwl_setup_rx_handlers(priv); |
| 1461 | 1467 | ||
| 1462 | iwl_power_initialize(priv); | 1468 | iwl_power_initialize(priv); |
| @@ -1494,6 +1500,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
| 1494 | iwl_cancel_deferred_work(priv); | 1500 | iwl_cancel_deferred_work(priv); |
| 1495 | destroy_workqueue(priv->workqueue); | 1501 | destroy_workqueue(priv->workqueue); |
| 1496 | priv->workqueue = NULL; | 1502 | priv->workqueue = NULL; |
| 1503 | +out_uninit_drv: | ||
| 1497 | iwl_uninit_drv(priv); | 1504 | iwl_uninit_drv(priv); |
| 1498 | out_free_eeprom_blob: | 1505 | out_free_eeprom_blob: |
| 1499 | kfree(priv->eeprom_blob); | 1506 | kfree(priv->eeprom_blob); |
| @@ -1041,10 +1041,11 @@ static void rtl8187_stop(struct ieee80211_hw *dev) | |||
| 1041 | rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); | 1041 | rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); |
| 1042 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | 1042 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); |
| 1043 | 1043 | ||
| 1044 | + usb_kill_anchored_urbs(&priv->anchored); | ||
| 1045 | + | ||
| 1044 | while ((skb = skb_dequeue(&priv->b_tx_status.queue))) | 1046 | while ((skb = skb_dequeue(&priv->b_tx_status.queue))) |
| 1045 | dev_kfree_skb_any(skb); | 1047 | dev_kfree_skb_any(skb); |
| 1046 | 1048 | ||
| 1047 | - usb_kill_anchored_urbs(&priv->anchored); | ||
| 1048 | mutex_unlock(&priv->conf_mutex); | 1049 | mutex_unlock(&priv->conf_mutex); |
| 1049 | 1050 | ||
| 1050 | if (!priv->is_rtl8187b) | 1051 | if (!priv->is_rtl8187b) |
| @@ -744,6 +744,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, | |||
| 744 | return info; | 744 | return info; |
| 745 | 745 | ||
| 746 | release_framebuf: | 746 | release_framebuf: |
| 747 | + fb_deferred_io_cleanup(info); | ||
| 747 | framebuffer_release(info); | 748 | framebuffer_release(info); |
| 748 | 749 | ||
| 749 | alloc_fail: | 750 | alloc_fail: |
| @@ -288,7 +288,7 @@ static void f2fs_read_end_io(struct bio *bio) | |||
| 288 | { | 288 | { |
| 289 | struct f2fs_sb_info *sbi = F2FS_P_SB(bio_first_page_all(bio)); | 289 | struct f2fs_sb_info *sbi = F2FS_P_SB(bio_first_page_all(bio)); |
| 290 | struct bio_post_read_ctx *ctx; | 290 | struct bio_post_read_ctx *ctx; |
| 291 | - bool intask = in_task(); | 291 | + bool intask = in_task() && !irqs_disabled(); |
| 292 | 292 | ||
| 293 | iostat_update_and_unbind_ctx(bio); | 293 | iostat_update_and_unbind_ctx(bio); |
| 294 | ctx = bio->bi_private; | 294 | ctx = bio->bi_private; |
| @@ -66,14 +66,21 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid, | |||
| 66 | { | 66 | { |
| 67 | struct nfs_fattr *fattr = NULL; | 67 | struct nfs_fattr *fattr = NULL; |
| 68 | struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw); | 68 | struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw); |
| 69 | - size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size; | 69 | + size_t fh_size = offsetof(struct nfs_fh, data); |
| 70 | const struct nfs_rpc_ops *rpc_ops; | 70 | const struct nfs_rpc_ops *rpc_ops; |
| 71 | struct dentry *dentry; | 71 | struct dentry *dentry; |
| 72 | struct inode *inode; | 72 | struct inode *inode; |
| 73 | - int len = EMBED_FH_OFF + XDR_QUADLEN(fh_size); | 73 | + int len = EMBED_FH_OFF; |
| 74 | u32 *p = fid->raw; | 74 | u32 *p = fid->raw; |
| 75 | int ret; | 75 | int ret; |
| 76 | 76 | ||
| 77 | + /* Initial check of bounds */ | ||
| 78 | + if (fh_len < len + XDR_QUADLEN(fh_size) || | ||
| 79 | + fh_len > XDR_QUADLEN(NFS_MAXFHSIZE)) | ||
| 80 | + return NULL; | ||
| 81 | + /* Calculate embedded filehandle size */ | ||
| 82 | + fh_size += server_fh->size; | ||
| 83 | + len += XDR_QUADLEN(fh_size); | ||
| 77 | /* NULL translates to ESTALE */ | 84 | /* NULL translates to ESTALE */ |
| 78 | if (fh_len < len || fh_type != len) | 85 | if (fh_len < len || fh_type != len) |
| 79 | return NULL; | 86 | return NULL; |
| @@ -1610,11 +1610,24 @@ static int krb5_authenticate(struct ksmbd_work *work, | |||
| 1610 | 1610 | ||
| 1611 | rsp->SecurityBufferLength = cpu_to_le16(out_len); | 1611 | rsp->SecurityBufferLength = cpu_to_le16(out_len); |
| 1612 | 1612 | ||
| 1613 | - if ((conn->sign || server_conf.enforced_signing) || | 1613 | + /* |
| 1614 | + * If session state is SMB2_SESSION_VALID, We can assume | ||
| 1615 | + * that it is reauthentication. And the user/password | ||
| 1616 | + * has been verified, so return it here. | ||
| 1617 | + */ | ||
| 1618 | + if (sess->state == SMB2_SESSION_VALID) { | ||
| 1619 | + if (conn->binding) | ||
| 1620 | + goto binding_session; | ||
| 1621 | + return 0; | ||
| 1622 | + } | ||
| 1623 | + | ||
| 1624 | + if ((rsp->SessionFlags != SMB2_SESSION_FLAG_IS_GUEST_LE && | ||
| 1625 | + (conn->sign || server_conf.enforced_signing)) || | ||
| 1614 | (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) | 1626 | (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) |
| 1615 | sess->sign = true; | 1627 | sess->sign = true; |
| 1616 | 1628 | ||
| 1617 | - if (smb3_encryption_negotiated(conn)) { | 1629 | + if (smb3_encryption_negotiated(conn) && |
| 1630 | + !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) { | ||
| 1618 | retval = conn->ops->generate_encryptionkey(conn, sess); | 1631 | retval = conn->ops->generate_encryptionkey(conn, sess); |
| 1619 | if (retval) { | 1632 | if (retval) { |
| 1620 | ksmbd_debug(SMB, | 1633 | ksmbd_debug(SMB, |
| @@ -1627,6 +1640,7 @@ static int krb5_authenticate(struct ksmbd_work *work, | |||
| 1627 | sess->sign = false; | 1640 | sess->sign = false; |
| 1628 | } | 1641 | } |
| 1629 | 1642 | ||
| 1643 | +binding_session: | ||
| 1630 | if (conn->dialect >= SMB30_PROT_ID) { | 1644 | if (conn->dialect >= SMB30_PROT_ID) { |
| 1631 | chann = lookup_chann_list(sess, conn); | 1645 | chann = lookup_chann_list(sess, conn); |
| 1632 | if (!chann) { | 1646 | if (!chann) { |
| @@ -2877,6 +2877,29 @@ static inline void skb_reset_transport_header(struct sk_buff *skb) | |||
| 2877 | skb->transport_header = skb->data - skb->head; | 2877 | skb->transport_header = skb->data - skb->head; |
| 2878 | } | 2878 | } |
| 2879 | 2879 | ||
| 2880 | +/** | ||
| 2881 | + * skb_reset_transport_header_careful - conditionally reset transport header | ||
| 2882 | + * @skb: buffer to alter | ||
| 2883 | + * | ||
| 2884 | + * Hardened version of skb_reset_transport_header(). | ||
| 2885 | + * | ||
| 2886 | + * Returns: true if the operation was a success. | ||
| 2887 | + */ | ||
| 2888 | +static inline bool __must_check | ||
| 2889 | +skb_reset_transport_header_careful(struct sk_buff *skb) | ||
| 2890 | +{ | ||
| 2891 | + long offset = skb->data - skb->head; | ||
| 2892 | + | ||
| 2893 | + if (unlikely(offset != (typeof(skb->transport_header))offset)) | ||
| 2894 | + return false; | ||
| 2895 | + | ||
| 2896 | + if (unlikely(offset == (typeof(skb->transport_header))~0U)) | ||
| 2897 | + return false; | ||
| 2898 | + | ||
| 2899 | + skb->transport_header = offset; | ||
| 2900 | + return true; | ||
| 2901 | +} | ||
| 2902 | + | ||
| 2880 | static inline void skb_set_transport_header(struct sk_buff *skb, | 2903 | static inline void skb_set_transport_header(struct sk_buff *skb, |
| 2881 | const int offset) | 2904 | const int offset) |
| 2882 | { | 2905 | { |
| @@ -6499,11 +6499,21 @@ static void perf_mmap_close(struct vm_area_struct *vma) | |||
| 6499 | ring_buffer_put(rb); /* could be last */ | 6499 | ring_buffer_put(rb); /* could be last */ |
| 6500 | } | 6500 | } |
| 6501 | 6501 | ||
| 6502 | +static int perf_mmap_may_split(struct vm_area_struct *vma, unsigned long addr) | ||
| 6503 | +{ | ||
| 6504 | + /* | ||
| 6505 | + * Forbid splitting perf mappings to prevent refcount leaks due to | ||
| 6506 | + * the resulting non-matching offsets and sizes. See open()/close(). | ||
| 6507 | + */ | ||
| 6508 | + return -EINVAL; | ||
| 6509 | +} | ||
| 6510 | + | ||
| 6502 | static const struct vm_operations_struct perf_mmap_vmops = { | 6511 | static const struct vm_operations_struct perf_mmap_vmops = { |
| 6503 | .open = perf_mmap_open, | 6512 | .open = perf_mmap_open, |
| 6504 | .close = perf_mmap_close, /* non mergeable */ | 6513 | .close = perf_mmap_close, /* non mergeable */ |
| 6505 | .fault = perf_mmap_fault, | 6514 | .fault = perf_mmap_fault, |
| 6506 | .page_mkwrite = perf_mmap_fault, | 6515 | .page_mkwrite = perf_mmap_fault, |
| 6516 | + .may_split = perf_mmap_may_split, | ||
| 6507 | }; | 6517 | }; |
| 6508 | 6518 | ||
| 6509 | static int perf_mmap(struct file *file, struct vm_area_struct *vma) | 6519 | static int perf_mmap(struct file *file, struct vm_area_struct *vma) |
| @@ -150,7 +150,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
| 150 | 150 | ||
| 151 | ops = rcu_dereference(inet6_offloads[proto]); | 151 | ops = rcu_dereference(inet6_offloads[proto]); |
| 152 | if (likely(ops && ops->callbacks.gso_segment)) { | 152 | if (likely(ops && ops->callbacks.gso_segment)) { |
| 153 | - skb_reset_transport_header(skb); | 153 | + if (!skb_reset_transport_header_careful(skb)) |
| 154 | + goto out; | ||
| 155 | + | ||
| 154 | segs = ops->callbacks.gso_segment(skb, features); | 156 | segs = ops->callbacks.gso_segment(skb, features); |
| 155 | if (!segs) | 157 | if (!segs) |
| 156 | skb->network_header = skb_mac_header(skb) + nhoff - skb->head; | 158 | skb->network_header = skb_mac_header(skb) + nhoff - skb->head; |
| @@ -972,6 +972,41 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla, | |||
| 972 | return 0; | 972 | return 0; |
| 973 | } | 973 | } |
| 974 | 974 | ||
| 975 | +static const struct Qdisc_class_ops netem_class_ops; | ||
| 976 | + | ||
| 977 | +static int check_netem_in_tree(struct Qdisc *sch, bool duplicates, | ||
| 978 | + struct netlink_ext_ack *extack) | ||
| 979 | +{ | ||
| 980 | + struct Qdisc *root, *q; | ||
| 981 | + unsigned int i; | ||
| 982 | + | ||
| 983 | + root = qdisc_root_sleeping(sch); | ||
| 984 | + | ||
| 985 | + if (sch != root && root->ops->cl_ops == &netem_class_ops) { | ||
| 986 | + if (duplicates || | ||
| 987 | + ((struct netem_sched_data *)qdisc_priv(root))->duplicate) | ||
| 988 | + goto err; | ||
| 989 | + } | ||
| 990 | + | ||
| 991 | + if (!qdisc_dev(root)) | ||
| 992 | + return 0; | ||
| 993 | + | ||
| 994 | + hash_for_each(qdisc_dev(root)->qdisc_hash, i, q, hash) { | ||
| 995 | + if (sch != q && q->ops->cl_ops == &netem_class_ops) { | ||
| 996 | + if (duplicates || | ||
| 997 | + ((struct netem_sched_data *)qdisc_priv(q))->duplicate) | ||
| 998 | + goto err; | ||
| 999 | + } | ||
| 1000 | + } | ||
| 1001 | + | ||
| 1002 | + return 0; | ||
| 1003 | + | ||
| 1004 | +err: | ||
| 1005 | + NL_SET_ERR_MSG(extack, | ||
| 1006 | + "netem: cannot mix duplicating netems with other netems in tree"); | ||
| 1007 | + return -EINVAL; | ||
| 1008 | +} | ||
| 1009 | + | ||
| 975 | /* Parse netlink message to set options */ | 1010 | /* Parse netlink message to set options */ |
| 976 | static int netem_change(struct Qdisc *sch, struct nlattr *opt, | 1011 | static int netem_change(struct Qdisc *sch, struct nlattr *opt, |
| 977 | struct netlink_ext_ack *extack) | 1012 | struct netlink_ext_ack *extack) |
| @@ -1030,6 +1065,11 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt, | |||
| 1030 | q->gap = qopt->gap; | 1065 | q->gap = qopt->gap; |
| 1031 | q->counter = 0; | 1066 | q->counter = 0; |
| 1032 | q->loss = qopt->loss; | 1067 | q->loss = qopt->loss; |
| 1068 | + | ||
| 1069 | + ret = check_netem_in_tree(sch, qopt->duplicate, extack); | ||
| 1070 | + if (ret) | ||
| 1071 | + goto unlock; | ||
| 1072 | + | ||
| 1033 | q->duplicate = qopt->duplicate; | 1073 | q->duplicate = qopt->duplicate; |
| 1034 | 1074 | ||
| 1035 | /* for compatibility with earlier versions. | 1075 | /* for compatibility with earlier versions. |
| @@ -872,6 +872,19 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, | |||
| 872 | delta = msg->sg.size; | 872 | delta = msg->sg.size; |
| 873 | psock->eval = sk_psock_msg_verdict(sk, psock, msg); | 873 | psock->eval = sk_psock_msg_verdict(sk, psock, msg); |
| 874 | delta -= msg->sg.size; | 874 | delta -= msg->sg.size; |
| 875 | + | ||
| 876 | + if ((s32)delta > 0) { | ||
| 877 | + /* It indicates that we executed bpf_msg_pop_data(), | ||
| 878 | + * causing the plaintext data size to decrease. | ||
| 879 | + * Therefore the encrypted data size also needs to | ||
| 880 | + * correspondingly decrease. We only need to subtract | ||
| 881 | + * delta to calculate the new ciphertext length since | ||
| 882 | + * ktls does not support block encryption. | ||
| 883 | + */ | ||
| 884 | + struct sk_msg *enc = &ctx->open_rec->msg_encrypted; | ||
| 885 | + | ||
| 886 | + sk_msg_trim(sk, enc, enc->sg.size - delta); | ||
| 887 | + } | ||
| 875 | } | 888 | } |
| 876 | if (msg->cork_bytes && msg->cork_bytes > msg->sg.size && | 889 | if (msg->cork_bytes && msg->cork_bytes > msg->sg.size && |
| 877 | !enospc && !full_record) { | 890 | !enospc && !full_record) { |
魔鬼数字