> @@ -13354,6 +13367,42 @@ static int parse_tid_conf(struct cfg80211_registered_device *rdev, > nla_get_u8(attrs[NL80211_ATTR_TID_CONFIG_RTSCTS_CTRL]); > } > > + if (attrs[NL80211_ATTR_TID_CONFIG_TX_RATES_TYPE]) { > + int idx; > + enum nl80211_attrs attr; > + > + if (!wiphy_ext_feature_isset(&rdev->wiphy, > + NL80211_EXT_FEATURE_PER_TID_TX_BITRATE_MASK)) > + return -EOPNOTSUPP; > + > + if (peer && > + !wiphy_ext_feature_isset(&rdev->wiphy, > + NL80211_EXT_FEATURE_PER_STA_TX_BITRATE_MASK)) > + return -EOPNOTSUPP; > + > + idx = NL80211_ATTR_TID_CONFIG_TX_RATES_TYPE; > + tid_conf->txrate_type = nla_get_u8(attrs[idx]); > + > + tid_conf->tid_conf_mask |= IEEE80211_TID_CONF_TX_BITRATE; > + if (tid_conf->txrate_type != NL80211_TX_RATE_AUTOMATIC) { > + tid_conf->mask = > + kzalloc(sizeof(struct cfg80211_bitrate_mask), > + GFP_KERNEL); You leak this > + if (!tid_conf->mask) > + return -ENOMEM; > + > + attr = NL80211_ATTR_TID_CONFIG_TX_RATES; > + ret = nl80211_parse_tx_bitrate_mask(attrs, rdev, attr, > + tid_conf->mask); > + if (ret) { > + kfree(tid_conf->mask); > + return ret; > + } > + } else { > + tid_conf->mask = NULL; > + } > + } > + > return 0; > } > > @@ -13407,7 +13456,7 @@ static int nl80211_set_tid_config(struct sk_buff *skb, > } > > ret = parse_tid_conf(rdev, attrs, &tid_conf->tid_conf[conf_idx], > - tid_conf->peer); > + info, tid_conf->peer); > if (ret) > goto bad_tid_conf; Practically everywhere, but particularly in the bad case in the next loop iteration etc? johannes