Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netlink: factor out policy range helpers

Add helpers to get the policy's signed/unsigned range
validation data.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Johannes Berg and committed by
David S. Miller
2c28ae48 c7721c05

+79 -21
+5
include/net/netlink.h
··· 1928 1928 return nla->nla_len == rem; 1929 1929 } 1930 1930 1931 + void nla_get_range_unsigned(const struct nla_policy *pt, 1932 + struct netlink_range_validation *range); 1933 + void nla_get_range_signed(const struct nla_policy *pt, 1934 + struct netlink_range_validation_signed *range); 1935 + 1931 1936 #endif
+74 -21
lib/nlattr.c
··· 111 111 return 0; 112 112 } 113 113 114 - static int nla_validate_int_range_unsigned(const struct nla_policy *pt, 115 - const struct nlattr *nla, 116 - struct netlink_ext_ack *extack) 114 + void nla_get_range_unsigned(const struct nla_policy *pt, 115 + struct netlink_range_validation *range) 117 116 { 118 - struct netlink_range_validation _range = { 119 - .min = 0, 120 - .max = U64_MAX, 121 - }, *range = &_range; 122 - u64 value; 123 - 124 117 WARN_ON_ONCE(pt->validation_type != NLA_VALIDATE_RANGE_PTR && 125 118 (pt->min < 0 || pt->max < 0)); 119 + 120 + range->min = 0; 121 + 122 + switch (pt->type) { 123 + case NLA_U8: 124 + range->max = U8_MAX; 125 + break; 126 + case NLA_U16: 127 + range->max = U16_MAX; 128 + break; 129 + case NLA_U32: 130 + range->max = U32_MAX; 131 + break; 132 + case NLA_U64: 133 + case NLA_MSECS: 134 + range->max = U64_MAX; 135 + break; 136 + default: 137 + WARN_ON_ONCE(1); 138 + return; 139 + } 126 140 127 141 switch (pt->validation_type) { 128 142 case NLA_VALIDATE_RANGE: ··· 144 130 range->max = pt->max; 145 131 break; 146 132 case NLA_VALIDATE_RANGE_PTR: 147 - range = pt->range; 133 + *range = *pt->range; 148 134 break; 149 135 case NLA_VALIDATE_MIN: 150 136 range->min = pt->min; ··· 152 138 case NLA_VALIDATE_MAX: 153 139 range->max = pt->max; 154 140 break; 141 + default: 142 + break; 155 143 } 144 + } 145 + 146 + static int nla_validate_int_range_unsigned(const struct nla_policy *pt, 147 + const struct nlattr *nla, 148 + struct netlink_ext_ack *extack) 149 + { 150 + struct netlink_range_validation range; 151 + u64 value; 156 152 157 153 switch (pt->type) { 158 154 case NLA_U8: ··· 182 158 return -EINVAL; 183 159 } 184 160 185 - if (value < range->min || value > range->max) { 161 + nla_get_range_unsigned(pt, &range); 162 + 163 + if (value < range.min || value > range.max) { 186 164 NL_SET_ERR_MSG_ATTR(extack, nla, 187 165 "integer out of range"); 188 166 return -ERANGE; ··· 193 167 return 0; 194 168 } 195 169 196 - static int nla_validate_int_range_signed(const struct nla_policy *pt, 197 - const struct nlattr *nla, 198 - struct netlink_ext_ack *extack) 170 + void nla_get_range_signed(const struct nla_policy *pt, 171 + struct netlink_range_validation_signed *range) 199 172 { 200 - struct netlink_range_validation_signed _range = { 201 - .min = S64_MIN, 202 - .max = S64_MAX, 203 - }, *range = &_range; 204 - s64 value; 173 + switch (pt->type) { 174 + case NLA_S8: 175 + range->min = S8_MIN; 176 + range->max = S8_MAX; 177 + break; 178 + case NLA_S16: 179 + range->min = S16_MIN; 180 + range->max = S16_MAX; 181 + break; 182 + case NLA_S32: 183 + range->min = S32_MIN; 184 + range->max = S32_MAX; 185 + break; 186 + case NLA_S64: 187 + range->min = S64_MIN; 188 + range->max = S64_MAX; 189 + break; 190 + default: 191 + WARN_ON_ONCE(1); 192 + return; 193 + } 205 194 206 195 switch (pt->validation_type) { 207 196 case NLA_VALIDATE_RANGE: ··· 224 183 range->max = pt->max; 225 184 break; 226 185 case NLA_VALIDATE_RANGE_PTR: 227 - range = pt->range_signed; 186 + *range = *pt->range_signed; 228 187 break; 229 188 case NLA_VALIDATE_MIN: 230 189 range->min = pt->min; ··· 232 191 case NLA_VALIDATE_MAX: 233 192 range->max = pt->max; 234 193 break; 194 + default: 195 + break; 235 196 } 197 + } 198 + 199 + static int nla_validate_int_range_signed(const struct nla_policy *pt, 200 + const struct nlattr *nla, 201 + struct netlink_ext_ack *extack) 202 + { 203 + struct netlink_range_validation_signed range; 204 + s64 value; 236 205 237 206 switch (pt->type) { 238 207 case NLA_S8: ··· 261 210 return -EINVAL; 262 211 } 263 212 264 - if (value < range->min || value > range->max) { 213 + nla_get_range_signed(pt, &range); 214 + 215 + if (value < range.min || value > range.max) { 265 216 NL_SET_ERR_MSG_ATTR(extack, nla, 266 217 "integer out of range"); 267 218 return -ERANGE;