tree: https://github.com/lunn/linux.git v5.1-rc1-cable-test head: b9bb5e57b75afd80ddd0915ffbf68724645e5717 commit: b1e164cd0b8cfd588738d646298e44264c72e16f [12/53] ethtool: provide string sets with GET_STRSET request
New smatch warnings: net/ethtool/strset.c:187 parse_strset() error: we previously assumed 'info' could be null (see line 157) net/ethtool/strset.c:279 prepare_strset() error: we previously assumed 'dev' could be null (see line 257) # https://github.com/lunn/linux/commit/b1e164cd0b8cfd588738d646298e44264c72e16f git remote add lunn https://github.com/lunn/linux.git git remote update lunn git checkout b1e164cd0b8cfd588738d646298e44264c72e16f vim +/PTR_ERR +168 net/ethtool/strset.c b1e164cd Michal Kubecek 2018-07-23 146 b1e164cd Michal Kubecek 2018-07-23 147 /* parse_request() handler */ b1e164cd Michal Kubecek 2018-07-23 148 static int parse_strset(struct common_req_info *req_info, struct sk_buff *skb, b1e164cd Michal Kubecek 2018-07-23 149 struct genl_info *info, const struct nlmsghdr *nlhdr) b1e164cd Michal Kubecek 2018-07-23 150 { b1e164cd Michal Kubecek 2018-07-23 151 struct strset_data *data = b1e164cd Michal Kubecek 2018-07-23 152 container_of(req_info, struct strset_data, reqinfo_base); b1e164cd Michal Kubecek 2018-07-23 153 struct nlattr *attr; b1e164cd Michal Kubecek 2018-07-23 154 int rem, ret; b1e164cd Michal Kubecek 2018-07-23 155 b1e164cd Michal Kubecek 2018-07-23 156 ret = nlmsg_validate(nlhdr, GENL_HDRLEN, ETHA_STRSET_MAX, b1e164cd Michal Kubecek 2018-07-23 @157 get_strset_policy, info ? info->extack : NULL); ^^^^ b1e164cd Michal Kubecek 2018-07-23 158 if (ret < 0) b1e164cd Michal Kubecek 2018-07-23 159 return ret; b1e164cd Michal Kubecek 2018-07-23 160 b1e164cd Michal Kubecek 2018-07-23 161 nlmsg_for_each_attr(attr, nlhdr, GENL_HDRLEN, rem) { b1e164cd Michal Kubecek 2018-07-23 162 u32 id; b1e164cd Michal Kubecek 2018-07-23 163 b1e164cd Michal Kubecek 2018-07-23 164 switch (nla_type(attr)) { b1e164cd Michal Kubecek 2018-07-23 165 case ETHA_STRSET_DEV: b1e164cd Michal Kubecek 2018-07-23 166 req_info->dev = ethnl_dev_get(info, attr); b1e164cd Michal Kubecek 2018-07-23 167 if (IS_ERR(req_info->dev)) { b1e164cd Michal Kubecek 2018-07-23 168 ret = PTR_ERR(req_info->dev); b1e164cd Michal Kubecek 2018-07-23 169 req_info->dev = NULL; b1e164cd Michal Kubecek 2018-07-23 170 return ret; b1e164cd Michal Kubecek 2018-07-23 171 } b1e164cd Michal Kubecek 2018-07-23 172 break; b1e164cd Michal Kubecek 2018-07-23 173 case ETHA_STRSET_COUNTS: b1e164cd Michal Kubecek 2018-07-23 174 data->counts_only = true; b1e164cd Michal Kubecek 2018-07-23 175 break; b1e164cd Michal Kubecek 2018-07-23 176 case ETHA_STRSET_STRINGSET: b1e164cd Michal Kubecek 2018-07-23 177 ret = get_strset_id(attr, &id, info); b1e164cd Michal Kubecek 2018-07-23 178 if (ret < 0) b1e164cd Michal Kubecek 2018-07-23 179 return ret; b1e164cd Michal Kubecek 2018-07-23 180 if (ret >= ETH_SS_COUNT) b1e164cd Michal Kubecek 2018-07-23 181 return -EOPNOTSUPP; b1e164cd Michal Kubecek 2018-07-23 182 data->req_ids |= (1U << id); b1e164cd Michal Kubecek 2018-07-23 183 break; b1e164cd Michal Kubecek 2018-07-23 184 default: b1e164cd Michal Kubecek 2018-07-23 185 ETHNL_SET_ERRMSG(info, b1e164cd Michal Kubecek 2018-07-23 186 "unexpected attribute in ETHNL_CMD_GET_STRSET message"); b1e164cd Michal Kubecek 2018-07-23 @187 return genl_err_attr(info, -EINVAL, attr); ^^^^ Presumably dereferenced inside the function call. b1e164cd Michal Kubecek 2018-07-23 188 } b1e164cd Michal Kubecek 2018-07-23 189 } b1e164cd Michal Kubecek 2018-07-23 190 b1e164cd Michal Kubecek 2018-07-23 191 return 0; b1e164cd Michal Kubecek 2018-07-23 192 } b1e164cd Michal Kubecek 2018-07-23 193 b1e164cd Michal Kubecek 2018-07-23 194 static void free_strset(struct strset_data *data) b1e164cd Michal Kubecek 2018-07-23 195 { b1e164cd Michal Kubecek 2018-07-23 196 unsigned int i; b1e164cd Michal Kubecek 2018-07-23 197 b1e164cd Michal Kubecek 2018-07-23 198 for (i = 0; i < ETH_SS_COUNT; i++) b1e164cd Michal Kubecek 2018-07-23 199 if (data->info[i].free_data) { b1e164cd Michal Kubecek 2018-07-23 200 kfree(data->info[i].data.ptr); b1e164cd Michal Kubecek 2018-07-23 201 data->info[i].data.ptr = NULL; b1e164cd Michal Kubecek 2018-07-23 202 data->info[i].free_data = false; b1e164cd Michal Kubecek 2018-07-23 203 } b1e164cd Michal Kubecek 2018-07-23 204 } b1e164cd Michal Kubecek 2018-07-23 205 b1e164cd Michal Kubecek 2018-07-23 206 static int prepare_one_stringset(struct strset_info *info, b1e164cd Michal Kubecek 2018-07-23 207 struct net_device *dev, unsigned int id, b1e164cd Michal Kubecek 2018-07-23 208 bool counts_only) b1e164cd Michal Kubecek 2018-07-23 209 { b1e164cd Michal Kubecek 2018-07-23 210 const struct ethtool_ops *ops = dev->ethtool_ops; b1e164cd Michal Kubecek 2018-07-23 211 void *strings; b1e164cd Michal Kubecek 2018-07-23 212 int count, ret; b1e164cd Michal Kubecek 2018-07-23 213 b1e164cd Michal Kubecek 2018-07-23 214 if (id == ETH_SS_PHY_STATS && dev->phydev && b1e164cd Michal Kubecek 2018-07-23 215 !ops->get_ethtool_phy_stats) b1e164cd Michal Kubecek 2018-07-23 216 ret = phy_ethtool_get_sset_count(dev->phydev); b1e164cd Michal Kubecek 2018-07-23 217 else if (ops->get_sset_count && ops->get_strings) b1e164cd Michal Kubecek 2018-07-23 218 ret = ops->get_sset_count(dev, id); b1e164cd Michal Kubecek 2018-07-23 219 else b1e164cd Michal Kubecek 2018-07-23 220 ret = -EOPNOTSUPP; b1e164cd Michal Kubecek 2018-07-23 221 if (ret <= 0) { b1e164cd Michal Kubecek 2018-07-23 222 info->count = 0; b1e164cd Michal Kubecek 2018-07-23 223 return 0; b1e164cd Michal Kubecek 2018-07-23 224 } b1e164cd Michal Kubecek 2018-07-23 225 b1e164cd Michal Kubecek 2018-07-23 226 count = ret; b1e164cd Michal Kubecek 2018-07-23 227 if (!counts_only) { b1e164cd Michal Kubecek 2018-07-23 228 strings = kcalloc(count, ETH_GSTRING_LEN, GFP_KERNEL); b1e164cd Michal Kubecek 2018-07-23 229 if (!strings) b1e164cd Michal Kubecek 2018-07-23 230 return -ENOMEM; b1e164cd Michal Kubecek 2018-07-23 231 if (id == ETH_SS_PHY_STATS && dev->phydev && b1e164cd Michal Kubecek 2018-07-23 232 !ops->get_ethtool_phy_stats) b1e164cd Michal Kubecek 2018-07-23 233 phy_ethtool_get_strings(dev->phydev, strings); b1e164cd Michal Kubecek 2018-07-23 234 else b1e164cd Michal Kubecek 2018-07-23 235 ops->get_strings(dev, id, strings); b1e164cd Michal Kubecek 2018-07-23 236 info->data.legacy = strings; b1e164cd Michal Kubecek 2018-07-23 237 info->free_data = true; b1e164cd Michal Kubecek 2018-07-23 238 } b1e164cd Michal Kubecek 2018-07-23 239 info->count = count; b1e164cd Michal Kubecek 2018-07-23 240 b1e164cd Michal Kubecek 2018-07-23 241 return 0; b1e164cd Michal Kubecek 2018-07-23 242 } b1e164cd Michal Kubecek 2018-07-23 243 b1e164cd Michal Kubecek 2018-07-23 244 /* prepare_data() handler */ b1e164cd Michal Kubecek 2018-07-23 245 static int prepare_strset(struct common_req_info *req_info, b1e164cd Michal Kubecek 2018-07-23 246 struct genl_info *info) b1e164cd Michal Kubecek 2018-07-23 247 { b1e164cd Michal Kubecek 2018-07-23 248 struct strset_data *data = b1e164cd Michal Kubecek 2018-07-23 249 container_of(req_info, struct strset_data, reqinfo_base); b1e164cd Michal Kubecek 2018-07-23 250 struct net_device *dev = data->repdata_base.dev; b1e164cd Michal Kubecek 2018-07-23 251 unsigned int i; b1e164cd Michal Kubecek 2018-07-23 252 int ret; b1e164cd Michal Kubecek 2018-07-23 253 b1e164cd Michal Kubecek 2018-07-23 254 BUILD_BUG_ON(ARRAY_SIZE(info_template) != ETH_SS_COUNT); b1e164cd Michal Kubecek 2018-07-23 255 memcpy(&data->info, &info_template, sizeof(data->info)); b1e164cd Michal Kubecek 2018-07-23 256 b1e164cd Michal Kubecek 2018-07-23 @257 if (!dev) { ^^^^ b1e164cd Michal Kubecek 2018-07-23 258 for (i = 0; i < ETH_SS_COUNT; i++) { b1e164cd Michal Kubecek 2018-07-23 259 if (id_requested(data, i) && b1e164cd Michal Kubecek 2018-07-23 260 data->info[i].per_dev) { b1e164cd Michal Kubecek 2018-07-23 261 ETHNL_SET_ERRMSG(info, b1e164cd Michal Kubecek 2018-07-23 262 "requested per device strings without dev"); b1e164cd Michal Kubecek 2018-07-23 263 return -EINVAL; b1e164cd Michal Kubecek 2018-07-23 264 } b1e164cd Michal Kubecek 2018-07-23 265 } b1e164cd Michal Kubecek 2018-07-23 266 } b1e164cd Michal Kubecek 2018-07-23 267 b1e164cd Michal Kubecek 2018-07-23 268 ret = ethnl_before_ops(dev); b1e164cd Michal Kubecek 2018-07-23 269 if (ret < 0) b1e164cd Michal Kubecek 2018-07-23 270 goto err_strset; b1e164cd Michal Kubecek 2018-07-23 271 for (i = 0; i < ETH_SS_COUNT; i++) { b1e164cd Michal Kubecek 2018-07-23 272 if (!include_set(data, i) || !data->info[i].per_dev) b1e164cd Michal Kubecek 2018-07-23 273 continue; b1e164cd Michal Kubecek 2018-07-23 274 if (WARN_ONCE(data->info[i].type != ETH_SS_TYPE_LEGACY, b1e164cd Michal Kubecek 2018-07-23 275 "unexpected string set type %u", b1e164cd Michal Kubecek 2018-07-23 276 data->info[i].type)) b1e164cd Michal Kubecek 2018-07-23 277 goto err_ops; b1e164cd Michal Kubecek 2018-07-23 278 b1e164cd Michal Kubecek 2018-07-23 @279 ret = prepare_one_stringset(&data->info[i], dev, i, ^^^ Smatch thinks it's dereferenced here, but not above in ethnl_before_ops(). I haven't looked at the code, only at this auto-generated email. b1e164cd Michal Kubecek 2018-07-23 280 data->counts_only); b1e164cd Michal Kubecek 2018-07-23 281 if (ret < 0) b1e164cd Michal Kubecek 2018-07-23 282 goto err_ops; b1e164cd Michal Kubecek 2018-07-23 283 } b1e164cd Michal Kubecek 2018-07-23 284 ethnl_after_ops(dev); b1e164cd Michal Kubecek 2018-07-23 285 b1e164cd Michal Kubecek 2018-07-23 286 return 0; b1e164cd Michal Kubecek 2018-07-23 287 err_ops: b1e164cd Michal Kubecek 2018-07-23 288 ethnl_after_ops(dev); b1e164cd Michal Kubecek 2018-07-23 289 err_strset: b1e164cd Michal Kubecek 2018-07-23 290 free_strset(data); b1e164cd Michal Kubecek 2018-07-23 291 return ret; b1e164cd Michal Kubecek 2018-07-23 292 } --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation _______________________________________________ kbuild mailing list kbuild@lists.01.org https://lists.01.org/mailman/listinfo/kbuild