brintos

brintos / linux-shallow public Read only

0
0
Text · 27.9 KiB · be9c576 Raw
1170 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * NETLINK      Netlink attributes4 *5 * 		Authors:	Thomas Graf <tgraf@suug.ch>6 * 				Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>7 */8 9#include <linux/export.h>10#include <linux/kernel.h>11#include <linux/errno.h>12#include <linux/jiffies.h>13#include <linux/nospec.h>14#include <linux/skbuff.h>15#include <linux/string.h>16#include <linux/types.h>17#include <net/netlink.h>18 19/* For these data types, attribute length should be exactly the given20 * size. However, to maintain compatibility with broken commands, if the21 * attribute length does not match the expected size a warning is emitted22 * to the user that the command is sending invalid data and needs to be fixed.23 */24static const u8 nla_attr_len[NLA_TYPE_MAX+1] = {25	[NLA_U8]	= sizeof(u8),26	[NLA_U16]	= sizeof(u16),27	[NLA_U32]	= sizeof(u32),28	[NLA_U64]	= sizeof(u64),29	[NLA_S8]	= sizeof(s8),30	[NLA_S16]	= sizeof(s16),31	[NLA_S32]	= sizeof(s32),32	[NLA_S64]	= sizeof(s64),33	[NLA_BE16]	= sizeof(__be16),34	[NLA_BE32]	= sizeof(__be32),35};36 37static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = {38	[NLA_U8]	= sizeof(u8),39	[NLA_U16]	= sizeof(u16),40	[NLA_U32]	= sizeof(u32),41	[NLA_U64]	= sizeof(u64),42	[NLA_MSECS]	= sizeof(u64),43	[NLA_NESTED]	= NLA_HDRLEN,44	[NLA_S8]	= sizeof(s8),45	[NLA_S16]	= sizeof(s16),46	[NLA_S32]	= sizeof(s32),47	[NLA_S64]	= sizeof(s64),48	[NLA_BE16]	= sizeof(__be16),49	[NLA_BE32]	= sizeof(__be32),50};51 52/*53 * Nested policies might refer back to the original54 * policy in some cases, and userspace could try to55 * abuse that and recurse by nesting in the right56 * ways. Limit recursion to avoid this problem.57 */58#define MAX_POLICY_RECURSION_DEPTH	1059 60static int __nla_validate_parse(const struct nlattr *head, int len, int maxtype,61				const struct nla_policy *policy,62				unsigned int validate,63				struct netlink_ext_ack *extack,64				struct nlattr **tb, unsigned int depth);65 66static int validate_nla_bitfield32(const struct nlattr *nla,67				   const u32 valid_flags_mask)68{69	const struct nla_bitfield32 *bf = nla_data(nla);70 71	if (!valid_flags_mask)72		return -EINVAL;73 74	/*disallow invalid bit selector */75	if (bf->selector & ~valid_flags_mask)76		return -EINVAL;77 78	/*disallow invalid bit values */79	if (bf->value & ~valid_flags_mask)80		return -EINVAL;81 82	/*disallow valid bit values that are not selected*/83	if (bf->value & ~bf->selector)84		return -EINVAL;85 86	return 0;87}88 89static int nla_validate_array(const struct nlattr *head, int len, int maxtype,90			      const struct nla_policy *policy,91			      struct netlink_ext_ack *extack,92			      unsigned int validate, unsigned int depth)93{94	const struct nlattr *entry;95	int rem;96 97	nla_for_each_attr(entry, head, len, rem) {98		int ret;99 100		if (nla_len(entry) == 0)101			continue;102 103		if (nla_len(entry) < NLA_HDRLEN) {104			NL_SET_ERR_MSG_ATTR_POL(extack, entry, policy,105						"Array element too short");106			return -ERANGE;107		}108 109		ret = __nla_validate_parse(nla_data(entry), nla_len(entry),110					   maxtype, policy, validate, extack,111					   NULL, depth + 1);112		if (ret < 0)113			return ret;114	}115 116	return 0;117}118 119void nla_get_range_unsigned(const struct nla_policy *pt,120			    struct netlink_range_validation *range)121{122	WARN_ON_ONCE(pt->validation_type != NLA_VALIDATE_RANGE_PTR &&123		     (pt->min < 0 || pt->max < 0));124 125	range->min = 0;126 127	switch (pt->type) {128	case NLA_U8:129		range->max = U8_MAX;130		break;131	case NLA_U16:132	case NLA_BE16:133	case NLA_BINARY:134		range->max = U16_MAX;135		break;136	case NLA_U32:137	case NLA_BE32:138		range->max = U32_MAX;139		break;140	case NLA_U64:141	case NLA_UINT:142	case NLA_MSECS:143		range->max = U64_MAX;144		break;145	default:146		WARN_ON_ONCE(1);147		return;148	}149 150	switch (pt->validation_type) {151	case NLA_VALIDATE_RANGE:152	case NLA_VALIDATE_RANGE_WARN_TOO_LONG:153		range->min = pt->min;154		range->max = pt->max;155		break;156	case NLA_VALIDATE_RANGE_PTR:157		*range = *pt->range;158		break;159	case NLA_VALIDATE_MIN:160		range->min = pt->min;161		break;162	case NLA_VALIDATE_MAX:163		range->max = pt->max;164		break;165	default:166		break;167	}168}169 170static int nla_validate_range_unsigned(const struct nla_policy *pt,171				       const struct nlattr *nla,172				       struct netlink_ext_ack *extack,173				       unsigned int validate)174{175	struct netlink_range_validation range;176	u64 value;177 178	switch (pt->type) {179	case NLA_U8:180		value = nla_get_u8(nla);181		break;182	case NLA_U16:183		value = nla_get_u16(nla);184		break;185	case NLA_U32:186		value = nla_get_u32(nla);187		break;188	case NLA_U64:189		value = nla_get_u64(nla);190		break;191	case NLA_UINT:192		value = nla_get_uint(nla);193		break;194	case NLA_MSECS:195		value = nla_get_u64(nla);196		break;197	case NLA_BINARY:198		value = nla_len(nla);199		break;200	case NLA_BE16:201		value = ntohs(nla_get_be16(nla));202		break;203	case NLA_BE32:204		value = ntohl(nla_get_be32(nla));205		break;206	default:207		return -EINVAL;208	}209 210	nla_get_range_unsigned(pt, &range);211 212	if (pt->validation_type == NLA_VALIDATE_RANGE_WARN_TOO_LONG &&213	    pt->type == NLA_BINARY && value > range.max) {214		pr_warn_ratelimited("netlink: '%s': attribute type %d has an invalid length.\n",215				    current->comm, pt->type);216		if (validate & NL_VALIDATE_STRICT_ATTRS) {217			NL_SET_ERR_MSG_ATTR_POL(extack, nla, pt,218						"invalid attribute length");219			return -EINVAL;220		}221 222		/* this assumes min <= max (don't validate against min) */223		return 0;224	}225 226	if (value < range.min || value > range.max) {227		bool binary = pt->type == NLA_BINARY;228 229		if (binary)230			NL_SET_ERR_MSG_ATTR_POL(extack, nla, pt,231						"binary attribute size out of range");232		else233			NL_SET_ERR_MSG_ATTR_POL(extack, nla, pt,234						"integer out of range");235 236		return -ERANGE;237	}238 239	return 0;240}241 242void nla_get_range_signed(const struct nla_policy *pt,243			  struct netlink_range_validation_signed *range)244{245	switch (pt->type) {246	case NLA_S8:247		range->min = S8_MIN;248		range->max = S8_MAX;249		break;250	case NLA_S16:251		range->min = S16_MIN;252		range->max = S16_MAX;253		break;254	case NLA_S32:255		range->min = S32_MIN;256		range->max = S32_MAX;257		break;258	case NLA_S64:259	case NLA_SINT:260		range->min = S64_MIN;261		range->max = S64_MAX;262		break;263	default:264		WARN_ON_ONCE(1);265		return;266	}267 268	switch (pt->validation_type) {269	case NLA_VALIDATE_RANGE:270		range->min = pt->min;271		range->max = pt->max;272		break;273	case NLA_VALIDATE_RANGE_PTR:274		*range = *pt->range_signed;275		break;276	case NLA_VALIDATE_MIN:277		range->min = pt->min;278		break;279	case NLA_VALIDATE_MAX:280		range->max = pt->max;281		break;282	default:283		break;284	}285}286 287static int nla_validate_int_range_signed(const struct nla_policy *pt,288					 const struct nlattr *nla,289					 struct netlink_ext_ack *extack)290{291	struct netlink_range_validation_signed range;292	s64 value;293 294	switch (pt->type) {295	case NLA_S8:296		value = nla_get_s8(nla);297		break;298	case NLA_S16:299		value = nla_get_s16(nla);300		break;301	case NLA_S32:302		value = nla_get_s32(nla);303		break;304	case NLA_S64:305		value = nla_get_s64(nla);306		break;307	case NLA_SINT:308		value = nla_get_sint(nla);309		break;310	default:311		return -EINVAL;312	}313 314	nla_get_range_signed(pt, &range);315 316	if (value < range.min || value > range.max) {317		NL_SET_ERR_MSG_ATTR_POL(extack, nla, pt,318					"integer out of range");319		return -ERANGE;320	}321 322	return 0;323}324 325static int nla_validate_int_range(const struct nla_policy *pt,326				  const struct nlattr *nla,327				  struct netlink_ext_ack *extack,328				  unsigned int validate)329{330	switch (pt->type) {331	case NLA_U8:332	case NLA_U16:333	case NLA_U32:334	case NLA_U64:335	case NLA_UINT:336	case NLA_MSECS:337	case NLA_BINARY:338	case NLA_BE16:339	case NLA_BE32:340		return nla_validate_range_unsigned(pt, nla, extack, validate);341	case NLA_S8:342	case NLA_S16:343	case NLA_S32:344	case NLA_S64:345	case NLA_SINT:346		return nla_validate_int_range_signed(pt, nla, extack);347	default:348		WARN_ON(1);349		return -EINVAL;350	}351}352 353static int nla_validate_mask(const struct nla_policy *pt,354			     const struct nlattr *nla,355			     struct netlink_ext_ack *extack)356{357	u64 value;358 359	switch (pt->type) {360	case NLA_U8:361		value = nla_get_u8(nla);362		break;363	case NLA_U16:364		value = nla_get_u16(nla);365		break;366	case NLA_U32:367		value = nla_get_u32(nla);368		break;369	case NLA_U64:370		value = nla_get_u64(nla);371		break;372	case NLA_UINT:373		value = nla_get_uint(nla);374		break;375	case NLA_BE16:376		value = ntohs(nla_get_be16(nla));377		break;378	case NLA_BE32:379		value = ntohl(nla_get_be32(nla));380		break;381	default:382		return -EINVAL;383	}384 385	if (value & ~(u64)pt->mask) {386		NL_SET_ERR_MSG_ATTR(extack, nla, "reserved bit set");387		return -EINVAL;388	}389 390	return 0;391}392 393static int validate_nla(const struct nlattr *nla, int maxtype,394			const struct nla_policy *policy, unsigned int validate,395			struct netlink_ext_ack *extack, unsigned int depth)396{397	u16 strict_start_type = policy[0].strict_start_type;398	const struct nla_policy *pt;399	int minlen = 0, attrlen = nla_len(nla), type = nla_type(nla);400	int err = -ERANGE;401 402	if (strict_start_type && type >= strict_start_type)403		validate |= NL_VALIDATE_STRICT;404 405	if (type <= 0 || type > maxtype)406		return 0;407 408	type = array_index_nospec(type, maxtype + 1);409	pt = &policy[type];410 411	BUG_ON(pt->type > NLA_TYPE_MAX);412 413	if (nla_attr_len[pt->type] && attrlen != nla_attr_len[pt->type]) {414		pr_warn_ratelimited("netlink: '%s': attribute type %d has an invalid length.\n",415				    current->comm, type);416		if (validate & NL_VALIDATE_STRICT_ATTRS) {417			NL_SET_ERR_MSG_ATTR_POL(extack, nla, pt,418						"invalid attribute length");419			return -EINVAL;420		}421	}422 423	if (validate & NL_VALIDATE_NESTED) {424		if ((pt->type == NLA_NESTED || pt->type == NLA_NESTED_ARRAY) &&425		    !(nla->nla_type & NLA_F_NESTED)) {426			NL_SET_ERR_MSG_ATTR_POL(extack, nla, pt,427						"NLA_F_NESTED is missing");428			return -EINVAL;429		}430		if (pt->type != NLA_NESTED && pt->type != NLA_NESTED_ARRAY &&431		    pt->type != NLA_UNSPEC && (nla->nla_type & NLA_F_NESTED)) {432			NL_SET_ERR_MSG_ATTR_POL(extack, nla, pt,433						"NLA_F_NESTED not expected");434			return -EINVAL;435		}436	}437 438	switch (pt->type) {439	case NLA_REJECT:440		if (extack && pt->reject_message) {441			NL_SET_BAD_ATTR(extack, nla);442			extack->_msg = pt->reject_message;443			return -EINVAL;444		}445		err = -EINVAL;446		goto out_err;447 448	case NLA_FLAG:449		if (attrlen > 0)450			goto out_err;451		break;452 453	case NLA_SINT:454	case NLA_UINT:455		if (attrlen != sizeof(u32) && attrlen != sizeof(u64)) {456			NL_SET_ERR_MSG_ATTR_POL(extack, nla, pt,457						"invalid attribute length");458			return -EINVAL;459		}460		break;461 462	case NLA_BITFIELD32:463		if (attrlen != sizeof(struct nla_bitfield32))464			goto out_err;465 466		err = validate_nla_bitfield32(nla, pt->bitfield32_valid);467		if (err)468			goto out_err;469		break;470 471	case NLA_NUL_STRING:472		if (pt->len)473			minlen = min_t(int, attrlen, pt->len + 1);474		else475			minlen = attrlen;476 477		if (!minlen || memchr(nla_data(nla), '\0', minlen) == NULL) {478			err = -EINVAL;479			goto out_err;480		}481		fallthrough;482 483	case NLA_STRING:484		if (attrlen < 1)485			goto out_err;486 487		if (pt->len) {488			char *buf = nla_data(nla);489 490			if (buf[attrlen - 1] == '\0')491				attrlen--;492 493			if (attrlen > pt->len)494				goto out_err;495		}496		break;497 498	case NLA_BINARY:499		if (pt->len && attrlen > pt->len)500			goto out_err;501		break;502 503	case NLA_NESTED:504		/* a nested attributes is allowed to be empty; if its not,505		 * it must have a size of at least NLA_HDRLEN.506		 */507		if (attrlen == 0)508			break;509		if (attrlen < NLA_HDRLEN)510			goto out_err;511		if (pt->nested_policy) {512			err = __nla_validate_parse(nla_data(nla), nla_len(nla),513						   pt->len, pt->nested_policy,514						   validate, extack, NULL,515						   depth + 1);516			if (err < 0) {517				/*518				 * return directly to preserve the inner519				 * error message/attribute pointer520				 */521				return err;522			}523		}524		break;525	case NLA_NESTED_ARRAY:526		/* a nested array attribute is allowed to be empty; if its not,527		 * it must have a size of at least NLA_HDRLEN.528		 */529		if (attrlen == 0)530			break;531		if (attrlen < NLA_HDRLEN)532			goto out_err;533		if (pt->nested_policy) {534			int err;535 536			err = nla_validate_array(nla_data(nla), nla_len(nla),537						 pt->len, pt->nested_policy,538						 extack, validate, depth);539			if (err < 0) {540				/*541				 * return directly to preserve the inner542				 * error message/attribute pointer543				 */544				return err;545			}546		}547		break;548 549	case NLA_UNSPEC:550		if (validate & NL_VALIDATE_UNSPEC) {551			NL_SET_ERR_MSG_ATTR(extack, nla,552					    "Unsupported attribute");553			return -EINVAL;554		}555		if (attrlen < pt->len)556			goto out_err;557		break;558 559	default:560		if (pt->len)561			minlen = pt->len;562		else563			minlen = nla_attr_minlen[pt->type];564 565		if (attrlen < minlen)566			goto out_err;567	}568 569	/* further validation */570	switch (pt->validation_type) {571	case NLA_VALIDATE_NONE:572		/* nothing to do */573		break;574	case NLA_VALIDATE_RANGE_PTR:575	case NLA_VALIDATE_RANGE:576	case NLA_VALIDATE_RANGE_WARN_TOO_LONG:577	case NLA_VALIDATE_MIN:578	case NLA_VALIDATE_MAX:579		err = nla_validate_int_range(pt, nla, extack, validate);580		if (err)581			return err;582		break;583	case NLA_VALIDATE_MASK:584		err = nla_validate_mask(pt, nla, extack);585		if (err)586			return err;587		break;588	case NLA_VALIDATE_FUNCTION:589		if (pt->validate) {590			err = pt->validate(nla, extack);591			if (err)592				return err;593		}594		break;595	}596 597	return 0;598out_err:599	NL_SET_ERR_MSG_ATTR_POL(extack, nla, pt,600				"Attribute failed policy validation");601	return err;602}603 604static int __nla_validate_parse(const struct nlattr *head, int len, int maxtype,605				const struct nla_policy *policy,606				unsigned int validate,607				struct netlink_ext_ack *extack,608				struct nlattr **tb, unsigned int depth)609{610	const struct nlattr *nla;611	int rem;612 613	if (depth >= MAX_POLICY_RECURSION_DEPTH) {614		NL_SET_ERR_MSG(extack,615			       "allowed policy recursion depth exceeded");616		return -EINVAL;617	}618 619	if (tb)620		memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));621 622	nla_for_each_attr(nla, head, len, rem) {623		u16 type = nla_type(nla);624 625		if (type == 0 || type > maxtype) {626			if (validate & NL_VALIDATE_MAXTYPE) {627				NL_SET_ERR_MSG_ATTR(extack, nla,628						    "Unknown attribute type");629				return -EINVAL;630			}631			continue;632		}633		type = array_index_nospec(type, maxtype + 1);634		if (policy) {635			int err = validate_nla(nla, maxtype, policy,636					       validate, extack, depth);637 638			if (err < 0)639				return err;640		}641 642		if (tb)643			tb[type] = (struct nlattr *)nla;644	}645 646	if (unlikely(rem > 0)) {647		pr_warn_ratelimited("netlink: %d bytes leftover after parsing attributes in process `%s'.\n",648				    rem, current->comm);649		NL_SET_ERR_MSG(extack, "bytes leftover after parsing attributes");650		if (validate & NL_VALIDATE_TRAILING)651			return -EINVAL;652	}653 654	return 0;655}656 657/**658 * __nla_validate - Validate a stream of attributes659 * @head: head of attribute stream660 * @len: length of attribute stream661 * @maxtype: maximum attribute type to be expected662 * @policy: validation policy663 * @validate: validation strictness664 * @extack: extended ACK report struct665 *666 * Validates all attributes in the specified attribute stream against the667 * specified policy. Validation depends on the validate flags passed, see668 * &enum netlink_validation for more details on that.669 * See documentation of struct nla_policy for more details.670 *671 * Returns 0 on success or a negative error code.672 */673int __nla_validate(const struct nlattr *head, int len, int maxtype,674		   const struct nla_policy *policy, unsigned int validate,675		   struct netlink_ext_ack *extack)676{677	return __nla_validate_parse(head, len, maxtype, policy, validate,678				    extack, NULL, 0);679}680EXPORT_SYMBOL(__nla_validate);681 682/**683 * nla_policy_len - Determine the max. length of a policy684 * @p: policy to use685 * @n: number of policies686 *687 * Determines the max. length of the policy.  It is currently used688 * to allocated Netlink buffers roughly the size of the actual689 * message.690 *691 * Returns 0 on success or a negative error code.692 */693int694nla_policy_len(const struct nla_policy *p, int n)695{696	int i, len = 0;697 698	for (i = 0; i < n; i++, p++) {699		if (p->len)700			len += nla_total_size(p->len);701		else if (nla_attr_len[p->type])702			len += nla_total_size(nla_attr_len[p->type]);703		else if (nla_attr_minlen[p->type])704			len += nla_total_size(nla_attr_minlen[p->type]);705	}706 707	return len;708}709EXPORT_SYMBOL(nla_policy_len);710 711/**712 * __nla_parse - Parse a stream of attributes into a tb buffer713 * @tb: destination array with maxtype+1 elements714 * @maxtype: maximum attribute type to be expected715 * @head: head of attribute stream716 * @len: length of attribute stream717 * @policy: validation policy718 * @validate: validation strictness719 * @extack: extended ACK pointer720 *721 * Parses a stream of attributes and stores a pointer to each attribute in722 * the tb array accessible via the attribute type.723 * Validation is controlled by the @validate parameter.724 *725 * Returns 0 on success or a negative error code.726 */727int __nla_parse(struct nlattr **tb, int maxtype,728		const struct nlattr *head, int len,729		const struct nla_policy *policy, unsigned int validate,730		struct netlink_ext_ack *extack)731{732	return __nla_validate_parse(head, len, maxtype, policy, validate,733				    extack, tb, 0);734}735EXPORT_SYMBOL(__nla_parse);736 737/**738 * nla_find - Find a specific attribute in a stream of attributes739 * @head: head of attribute stream740 * @len: length of attribute stream741 * @attrtype: type of attribute to look for742 *743 * Returns the first attribute in the stream matching the specified type.744 */745struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype)746{747	const struct nlattr *nla;748	int rem;749 750	nla_for_each_attr(nla, head, len, rem)751		if (nla_type(nla) == attrtype)752			return (struct nlattr *)nla;753 754	return NULL;755}756EXPORT_SYMBOL(nla_find);757 758/**759 * nla_strscpy - Copy string attribute payload into a sized buffer760 * @dst: Where to copy the string to.761 * @nla: Attribute to copy the string from.762 * @dstsize: Size of destination buffer.763 *764 * Copies at most dstsize - 1 bytes into the destination buffer.765 * Unlike strscpy() the destination buffer is always padded out.766 *767 * Return:768 * * srclen - Returns @nla length (not including the trailing %NUL).769 * * -E2BIG - If @dstsize is 0 or greater than U16_MAX or @nla length greater770 *            than @dstsize.771 */772ssize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t dstsize)773{774	size_t srclen = nla_len(nla);775	char *src = nla_data(nla);776	ssize_t ret;777	size_t len;778 779	if (dstsize == 0 || WARN_ON_ONCE(dstsize > U16_MAX))780		return -E2BIG;781 782	if (srclen > 0 && src[srclen - 1] == '\0')783		srclen--;784 785	if (srclen >= dstsize) {786		len = dstsize - 1;787		ret = -E2BIG;788	} else {789		len = srclen;790		ret = len;791	}792 793	memcpy(dst, src, len);794	/* Zero pad end of dst. */795	memset(dst + len, 0, dstsize - len);796 797	return ret;798}799EXPORT_SYMBOL(nla_strscpy);800 801/**802 * nla_strdup - Copy string attribute payload into a newly allocated buffer803 * @nla: attribute to copy the string from804 * @flags: the type of memory to allocate (see kmalloc).805 *806 * Returns a pointer to the allocated buffer or NULL on error.807 */808char *nla_strdup(const struct nlattr *nla, gfp_t flags)809{810	size_t srclen = nla_len(nla);811	char *src = nla_data(nla), *dst;812 813	if (srclen > 0 && src[srclen - 1] == '\0')814		srclen--;815 816	dst = kmalloc(srclen + 1, flags);817	if (dst != NULL) {818		memcpy(dst, src, srclen);819		dst[srclen] = '\0';820	}821	return dst;822}823EXPORT_SYMBOL(nla_strdup);824 825/**826 * nla_memcpy - Copy a netlink attribute into another memory area827 * @dest: where to copy to memcpy828 * @src: netlink attribute to copy from829 * @count: size of the destination area830 *831 * Note: The number of bytes copied is limited by the length of832 *       attribute's payload. memcpy833 *834 * Returns the number of bytes copied.835 */836int nla_memcpy(void *dest, const struct nlattr *src, int count)837{838	int minlen = min_t(int, count, nla_len(src));839 840	memcpy(dest, nla_data(src), minlen);841	if (count > minlen)842		memset(dest + minlen, 0, count - minlen);843 844	return minlen;845}846EXPORT_SYMBOL(nla_memcpy);847 848/**849 * nla_memcmp - Compare an attribute with sized memory area850 * @nla: netlink attribute851 * @data: memory area852 * @size: size of memory area853 */854int nla_memcmp(const struct nlattr *nla, const void *data,855			     size_t size)856{857	int d = nla_len(nla) - size;858 859	if (d == 0)860		d = memcmp(nla_data(nla), data, size);861 862	return d;863}864EXPORT_SYMBOL(nla_memcmp);865 866/**867 * nla_strcmp - Compare a string attribute against a string868 * @nla: netlink string attribute869 * @str: another string870 */871int nla_strcmp(const struct nlattr *nla, const char *str)872{873	int len = strlen(str);874	char *buf = nla_data(nla);875	int attrlen = nla_len(nla);876	int d;877 878	while (attrlen > 0 && buf[attrlen - 1] == '\0')879		attrlen--;880 881	d = attrlen - len;882	if (d == 0)883		d = memcmp(nla_data(nla), str, len);884 885	return d;886}887EXPORT_SYMBOL(nla_strcmp);888 889#ifdef CONFIG_NET890/**891 * __nla_reserve - reserve room for attribute on the skb892 * @skb: socket buffer to reserve room on893 * @attrtype: attribute type894 * @attrlen: length of attribute payload895 *896 * Adds a netlink attribute header to a socket buffer and reserves897 * room for the payload but does not copy it.898 *899 * The caller is responsible to ensure that the skb provides enough900 * tailroom for the attribute header and payload.901 */902struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)903{904	struct nlattr *nla;905 906	nla = skb_put(skb, nla_total_size(attrlen));907	nla->nla_type = attrtype;908	nla->nla_len = nla_attr_size(attrlen);909 910	memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));911 912	return nla;913}914EXPORT_SYMBOL(__nla_reserve);915 916/**917 * __nla_reserve_64bit - reserve room for attribute on the skb and align it918 * @skb: socket buffer to reserve room on919 * @attrtype: attribute type920 * @attrlen: length of attribute payload921 * @padattr: attribute type for the padding922 *923 * Adds a netlink attribute header to a socket buffer and reserves924 * room for the payload but does not copy it. It also ensure that this925 * attribute will have a 64-bit aligned nla_data() area.926 *927 * The caller is responsible to ensure that the skb provides enough928 * tailroom for the attribute header and payload.929 */930struct nlattr *__nla_reserve_64bit(struct sk_buff *skb, int attrtype,931				   int attrlen, int padattr)932{933	nla_align_64bit(skb, padattr);934 935	return __nla_reserve(skb, attrtype, attrlen);936}937EXPORT_SYMBOL(__nla_reserve_64bit);938 939/**940 * __nla_reserve_nohdr - reserve room for attribute without header941 * @skb: socket buffer to reserve room on942 * @attrlen: length of attribute payload943 *944 * Reserves room for attribute payload without a header.945 *946 * The caller is responsible to ensure that the skb provides enough947 * tailroom for the payload.948 */949void *__nla_reserve_nohdr(struct sk_buff *skb, int attrlen)950{951	return skb_put_zero(skb, NLA_ALIGN(attrlen));952}953EXPORT_SYMBOL(__nla_reserve_nohdr);954 955/**956 * nla_reserve - reserve room for attribute on the skb957 * @skb: socket buffer to reserve room on958 * @attrtype: attribute type959 * @attrlen: length of attribute payload960 *961 * Adds a netlink attribute header to a socket buffer and reserves962 * room for the payload but does not copy it.963 *964 * Returns NULL if the tailroom of the skb is insufficient to store965 * the attribute header and payload.966 */967struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)968{969	if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))970		return NULL;971 972	return __nla_reserve(skb, attrtype, attrlen);973}974EXPORT_SYMBOL(nla_reserve);975 976/**977 * nla_reserve_64bit - reserve room for attribute on the skb and align it978 * @skb: socket buffer to reserve room on979 * @attrtype: attribute type980 * @attrlen: length of attribute payload981 * @padattr: attribute type for the padding982 *983 * Adds a netlink attribute header to a socket buffer and reserves984 * room for the payload but does not copy it. It also ensure that this985 * attribute will have a 64-bit aligned nla_data() area.986 *987 * Returns NULL if the tailroom of the skb is insufficient to store988 * the attribute header and payload.989 */990struct nlattr *nla_reserve_64bit(struct sk_buff *skb, int attrtype, int attrlen,991				 int padattr)992{993	size_t len;994 995	if (nla_need_padding_for_64bit(skb))996		len = nla_total_size_64bit(attrlen);997	else998		len = nla_total_size(attrlen);999	if (unlikely(skb_tailroom(skb) < len))1000		return NULL;1001 1002	return __nla_reserve_64bit(skb, attrtype, attrlen, padattr);1003}1004EXPORT_SYMBOL(nla_reserve_64bit);1005 1006/**1007 * nla_reserve_nohdr - reserve room for attribute without header1008 * @skb: socket buffer to reserve room on1009 * @attrlen: length of attribute payload1010 *1011 * Reserves room for attribute payload without a header.1012 *1013 * Returns NULL if the tailroom of the skb is insufficient to store1014 * the attribute payload.1015 */1016void *nla_reserve_nohdr(struct sk_buff *skb, int attrlen)1017{1018	if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))1019		return NULL;1020 1021	return __nla_reserve_nohdr(skb, attrlen);1022}1023EXPORT_SYMBOL(nla_reserve_nohdr);1024 1025/**1026 * __nla_put - Add a netlink attribute to a socket buffer1027 * @skb: socket buffer to add attribute to1028 * @attrtype: attribute type1029 * @attrlen: length of attribute payload1030 * @data: head of attribute payload1031 *1032 * The caller is responsible to ensure that the skb provides enough1033 * tailroom for the attribute header and payload.1034 */1035void __nla_put(struct sk_buff *skb, int attrtype, int attrlen,1036			     const void *data)1037{1038	struct nlattr *nla;1039 1040	nla = __nla_reserve(skb, attrtype, attrlen);1041	memcpy(nla_data(nla), data, attrlen);1042}1043EXPORT_SYMBOL(__nla_put);1044 1045/**1046 * __nla_put_64bit - Add a netlink attribute to a socket buffer and align it1047 * @skb: socket buffer to add attribute to1048 * @attrtype: attribute type1049 * @attrlen: length of attribute payload1050 * @data: head of attribute payload1051 * @padattr: attribute type for the padding1052 *1053 * The caller is responsible to ensure that the skb provides enough1054 * tailroom for the attribute header and payload.1055 */1056void __nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,1057		     const void *data, int padattr)1058{1059	struct nlattr *nla;1060 1061	nla = __nla_reserve_64bit(skb, attrtype, attrlen, padattr);1062	memcpy(nla_data(nla), data, attrlen);1063}1064EXPORT_SYMBOL(__nla_put_64bit);1065 1066/**1067 * __nla_put_nohdr - Add a netlink attribute without header1068 * @skb: socket buffer to add attribute to1069 * @attrlen: length of attribute payload1070 * @data: head of attribute payload1071 *1072 * The caller is responsible to ensure that the skb provides enough1073 * tailroom for the attribute payload.1074 */1075void __nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data)1076{1077	void *start;1078 1079	start = __nla_reserve_nohdr(skb, attrlen);1080	memcpy(start, data, attrlen);1081}1082EXPORT_SYMBOL(__nla_put_nohdr);1083 1084/**1085 * nla_put - Add a netlink attribute to a socket buffer1086 * @skb: socket buffer to add attribute to1087 * @attrtype: attribute type1088 * @attrlen: length of attribute payload1089 * @data: head of attribute payload1090 *1091 * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store1092 * the attribute header and payload.1093 */1094int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data)1095{1096	if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))1097		return -EMSGSIZE;1098 1099	__nla_put(skb, attrtype, attrlen, data);1100	return 0;1101}1102EXPORT_SYMBOL(nla_put);1103 1104/**1105 * nla_put_64bit - Add a netlink attribute to a socket buffer and align it1106 * @skb: socket buffer to add attribute to1107 * @attrtype: attribute type1108 * @attrlen: length of attribute payload1109 * @data: head of attribute payload1110 * @padattr: attribute type for the padding1111 *1112 * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store1113 * the attribute header and payload.1114 */1115int nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,1116		  const void *data, int padattr)1117{1118	size_t len;1119 1120	if (nla_need_padding_for_64bit(skb))1121		len = nla_total_size_64bit(attrlen);1122	else1123		len = nla_total_size(attrlen);1124	if (unlikely(skb_tailroom(skb) < len))1125		return -EMSGSIZE;1126 1127	__nla_put_64bit(skb, attrtype, attrlen, data, padattr);1128	return 0;1129}1130EXPORT_SYMBOL(nla_put_64bit);1131 1132/**1133 * nla_put_nohdr - Add a netlink attribute without header1134 * @skb: socket buffer to add attribute to1135 * @attrlen: length of attribute payload1136 * @data: head of attribute payload1137 *1138 * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store1139 * the attribute payload.1140 */1141int nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data)1142{1143	if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))1144		return -EMSGSIZE;1145 1146	__nla_put_nohdr(skb, attrlen, data);1147	return 0;1148}1149EXPORT_SYMBOL(nla_put_nohdr);1150 1151/**1152 * nla_append - Add a netlink attribute without header or padding1153 * @skb: socket buffer to add attribute to1154 * @attrlen: length of attribute payload1155 * @data: head of attribute payload1156 *1157 * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store1158 * the attribute payload.1159 */1160int nla_append(struct sk_buff *skb, int attrlen, const void *data)1161{1162	if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))1163		return -EMSGSIZE;1164 1165	skb_put_data(skb, data, attrlen);1166	return 0;1167}1168EXPORT_SYMBOL(nla_append);1169#endif1170