@@ -3675,34 +3675,21 @@ __bpf_kfunc int bpf_strcspn(const char *s__ign, const char *reject__ign)
36753675 return - EFAULT ;
36763676}
36773677
3678- /**
3679- * bpf_strnstr - Find the first substring in a length-limited string
3680- * @s1__ign: The string to be searched
3681- * @s2__ign: The string to search for
3682- * @len: the maximum number of characters to search
3683- *
3684- * Return:
3685- * * >=0 - Index of the first character of the first occurrence of @s2__ign
3686- * within the first @len characters of @s1__ign
3687- * * %-ENOENT - @s2__ign not found in the first @len characters of @s1__ign
3688- * * %-EFAULT - Cannot read one of the strings
3689- * * %-E2BIG - One of the strings is too large
3690- * * %-ERANGE - One of the strings is outside of kernel address space
3691- */
3692- __bpf_kfunc int bpf_strnstr (const char * s1__ign , const char * s2__ign , size_t len )
3678+ static int __bpf_strnstr (const char * s1 , const char * s2 , size_t len ,
3679+ bool ignore_case )
36933680{
36943681 char c1 , c2 ;
36953682 int i , j ;
36963683
3697- if (!copy_from_kernel_nofault_allowed (s1__ign , 1 ) ||
3698- !copy_from_kernel_nofault_allowed (s2__ign , 1 )) {
3684+ if (!copy_from_kernel_nofault_allowed (s1 , 1 ) ||
3685+ !copy_from_kernel_nofault_allowed (s2 , 1 )) {
36993686 return - ERANGE ;
37003687 }
37013688
37023689 guard (pagefault )();
37033690 for (i = 0 ; i < XATTR_SIZE_MAX ; i ++ ) {
37043691 for (j = 0 ; i + j <= len && j < XATTR_SIZE_MAX ; j ++ ) {
3705- __get_kernel_nofault (& c2 , s2__ign + j , char , err_out );
3692+ __get_kernel_nofault (& c2 , s2 + j , char , err_out );
37063693 if (c2 == '\0' )
37073694 return i ;
37083695 /*
@@ -3712,7 +3699,13 @@ __bpf_kfunc int bpf_strnstr(const char *s1__ign, const char *s2__ign, size_t len
37123699 */
37133700 if (i + j == len )
37143701 break ;
3715- __get_kernel_nofault (& c1 , s1__ign + j , char , err_out );
3702+ __get_kernel_nofault (& c1 , s1 + j , char , err_out );
3703+
3704+ if (ignore_case ) {
3705+ c1 = tolower (c1 );
3706+ c2 = tolower (c2 );
3707+ }
3708+
37163709 if (c1 == '\0' )
37173710 return - ENOENT ;
37183711 if (c1 != c2 )
@@ -3722,7 +3715,7 @@ __bpf_kfunc int bpf_strnstr(const char *s1__ign, const char *s2__ign, size_t len
37223715 return - E2BIG ;
37233716 if (i + j == len )
37243717 return - ENOENT ;
3725- s1__ign ++ ;
3718+ s1 ++ ;
37263719 }
37273720 return - E2BIG ;
37283721err_out :
@@ -3744,8 +3737,69 @@ __bpf_kfunc int bpf_strnstr(const char *s1__ign, const char *s2__ign, size_t len
37443737 */
37453738__bpf_kfunc int bpf_strstr (const char * s1__ign , const char * s2__ign )
37463739{
3747- return bpf_strnstr (s1__ign , s2__ign , XATTR_SIZE_MAX );
3740+ return __bpf_strnstr (s1__ign , s2__ign , XATTR_SIZE_MAX , false);
3741+ }
3742+
3743+ /**
3744+ * bpf_strcasestr - Find the first substring in a string, ignoring the case of
3745+ * the characters
3746+ * @s1__ign: The string to be searched
3747+ * @s2__ign: The string to search for
3748+ *
3749+ * Return:
3750+ * * >=0 - Index of the first character of the first occurrence of @s2__ign
3751+ * within @s1__ign
3752+ * * %-ENOENT - @s2__ign is not a substring of @s1__ign
3753+ * * %-EFAULT - Cannot read one of the strings
3754+ * * %-E2BIG - One of the strings is too large
3755+ * * %-ERANGE - One of the strings is outside of kernel address space
3756+ */
3757+ __bpf_kfunc int bpf_strcasestr (const char * s1__ign , const char * s2__ign )
3758+ {
3759+ return __bpf_strnstr (s1__ign , s2__ign , XATTR_SIZE_MAX , true);
37483760}
3761+
3762+ /**
3763+ * bpf_strnstr - Find the first substring in a length-limited string
3764+ * @s1__ign: The string to be searched
3765+ * @s2__ign: The string to search for
3766+ * @len: the maximum number of characters to search
3767+ *
3768+ * Return:
3769+ * * >=0 - Index of the first character of the first occurrence of @s2__ign
3770+ * within the first @len characters of @s1__ign
3771+ * * %-ENOENT - @s2__ign not found in the first @len characters of @s1__ign
3772+ * * %-EFAULT - Cannot read one of the strings
3773+ * * %-E2BIG - One of the strings is too large
3774+ * * %-ERANGE - One of the strings is outside of kernel address space
3775+ */
3776+ __bpf_kfunc int bpf_strnstr (const char * s1__ign , const char * s2__ign ,
3777+ size_t len )
3778+ {
3779+ return __bpf_strnstr (s1__ign , s2__ign , len , false);
3780+ }
3781+
3782+ /**
3783+ * bpf_strncasestr - Find the first substring in a length-limited string,
3784+ * ignoring the case of the characters
3785+ * @s1__ign: The string to be searched
3786+ * @s2__ign: The string to search for
3787+ * @len: the maximum number of characters to search
3788+ *
3789+ * Return:
3790+ * * >=0 - Index of the first character of the first occurrence of @s2__ign
3791+ * within the first @len characters of @s1__ign
3792+ * * %-ENOENT - @s2__ign not found in the first @len characters of @s1__ign
3793+ * * %-EFAULT - Cannot read one of the strings
3794+ * * %-E2BIG - One of the strings is too large
3795+ * * %-ERANGE - One of the strings is outside of kernel address space
3796+ */
3797+ __bpf_kfunc int bpf_strncasestr (const char * s1__ign , const char * s2__ign ,
3798+ size_t len )
3799+ {
3800+ return __bpf_strnstr (s1__ign , s2__ign , len , true);
3801+ }
3802+
37493803#ifdef CONFIG_KEYS
37503804/**
37513805 * bpf_lookup_user_key - lookup a key by its serial
@@ -4367,7 +4421,9 @@ BTF_ID_FLAGS(func, bpf_strnlen);
43674421BTF_ID_FLAGS (func , bpf_strspn );
43684422BTF_ID_FLAGS (func , bpf_strcspn );
43694423BTF_ID_FLAGS (func , bpf_strstr );
4424+ BTF_ID_FLAGS (func , bpf_strcasestr );
43704425BTF_ID_FLAGS (func , bpf_strnstr );
4426+ BTF_ID_FLAGS (func , bpf_strncasestr );
43714427#if defined(CONFIG_BPF_LSM ) && defined(CONFIG_CGROUPS )
43724428BTF_ID_FLAGS (func , bpf_cgroup_read_xattr , KF_RCU )
43734429#endif
0 commit comments