@@ -443,34 +443,53 @@ struct smack_known *smk_find_entry(const char *string)
443443}
444444
445445/**
446- * smk_parse_smack - parse smack label from a text string
447- * @string: a text string that might contain a Smack label
448- * @len: the maximum size, or zero if it is NULL terminated.
446+ * smk_parse_label_len - calculate the length of the starting segment
447+ * in the string that constitutes a valid smack label
448+ * @string: a text string that might contain a Smack label at the beginning
449+ * @len: the maximum size to look into, may be zero if string is null-terminated
449450 *
450- * Returns a pointer to the clean label or an error code.
451+ * Returns the length of the segment (0 < L < SMK_LONGLABEL) or an error code.
451452 */
452- char * smk_parse_smack (const char * string , int len )
453+ int smk_parse_label_len (const char * string , int len )
453454{
454- char * smack ;
455455 int i ;
456456
457- if (len <= 0 )
458- len = strlen ( string ) + 1 ;
457+ if (len <= 0 || len > SMK_LONGLABEL )
458+ len = SMK_LONGLABEL ;
459459
460460 /*
461461 * Reserve a leading '-' as an indicator that
462462 * this isn't a label, but an option to interfaces
463463 * including /smack/cipso and /smack/cipso2
464464 */
465465 if (string [0 ] == '-' )
466- return ERR_PTR ( - EINVAL ) ;
466+ return - EINVAL ;
467467
468468 for (i = 0 ; i < len ; i ++ )
469469 if (string [i ] > '~' || string [i ] <= ' ' || string [i ] == '/' ||
470470 string [i ] == '"' || string [i ] == '\\' || string [i ] == '\'' )
471471 break ;
472472
473473 if (i == 0 || i >= SMK_LONGLABEL )
474+ return - EINVAL ;
475+
476+ return i ;
477+ }
478+
479+ /**
480+ * smk_parse_smack - copy the starting segment in the string
481+ * that constitutes a valid smack label
482+ * @string: a text string that might contain a Smack label at the beginning
483+ * @len: the maximum size to look into, may be zero if string is null-terminated
484+ *
485+ * Returns a pointer to the copy of the label or an error code.
486+ */
487+ char * smk_parse_smack (const char * string , int len )
488+ {
489+ char * smack ;
490+ int i = smk_parse_label_len (string , len );
491+
492+ if (i < 0 )
474493 return ERR_PTR (- EINVAL );
475494
476495 smack = kstrndup (string , i , GFP_NOFS );
@@ -554,31 +573,26 @@ int smack_populate_secattr(struct smack_known *skp)
554573}
555574
556575/**
557- * smk_import_entry - import a label, return the list entry
558- * @string: a text string that might be a Smack label
559- * @len: the maximum size, or zero if it is NULL terminated.
576+ * smk_import_valid_allocated_label - import a label, return the list entry
577+ * @smack: a text string that is a valid Smack label and may be kfree()ed.
578+ * It is consumed: either becomes a part of the entry or kfree'ed.
579+ * @gfp: Allocation type
560580 *
561- * Returns a pointer to the entry in the label list that
562- * matches the passed string, adding it if necessary,
563- * or an error code.
581+ * Returns: see description of smk_import_entry()
564582 */
565- struct smack_known * smk_import_entry (const char * string , int len )
583+ static struct smack_known *
584+ smk_import_allocated_label (char * smack , gfp_t gfp )
566585{
567586 struct smack_known * skp ;
568- char * smack ;
569587 int rc ;
570588
571- smack = smk_parse_smack (string , len );
572- if (IS_ERR (smack ))
573- return ERR_CAST (smack );
574-
575589 mutex_lock (& smack_known_lock );
576590
577591 skp = smk_find_entry (smack );
578592 if (skp != NULL )
579593 goto freeout ;
580594
581- skp = kzalloc (sizeof (* skp ), GFP_NOFS );
595+ skp = kzalloc (sizeof (* skp ), gfp );
582596 if (skp == NULL ) {
583597 skp = ERR_PTR (- ENOMEM );
584598 goto freeout ;
@@ -608,6 +622,44 @@ struct smack_known *smk_import_entry(const char *string, int len)
608622 return skp ;
609623}
610624
625+ /**
626+ * smk_import_entry - import a label, return the list entry
627+ * @string: a text string that might contain a Smack label at the beginning
628+ * @len: the maximum size to look into, may be zero if string is null-terminated
629+ *
630+ * Returns a pointer to the entry in the label list that
631+ * matches the passed string, adding it if necessary,
632+ * or an error code.
633+ */
634+ struct smack_known * smk_import_entry (const char * string , int len )
635+ {
636+ char * smack = smk_parse_smack (string , len );
637+
638+ if (IS_ERR (smack ))
639+ return ERR_CAST (smack );
640+
641+ return smk_import_allocated_label (smack , GFP_NOFS );
642+ }
643+
644+ /**
645+ * smk_import_valid_label - import a label, return the list entry
646+ * @label: a text string that is a valid Smack label, not null-terminated
647+ * @label_len: the length of the text string in the @label
648+ * @gfp: the GFP mask used for allocating memory for the @label text string copy
649+ *
650+ * Return: see description of smk_import_entry()
651+ */
652+ struct smack_known *
653+ smk_import_valid_label (const char * label , int label_len , gfp_t gfp )
654+ {
655+ char * smack = kstrndup (label , label_len , gfp );
656+
657+ if (!smack )
658+ return ERR_PTR (- ENOMEM );
659+
660+ return smk_import_allocated_label (smack , gfp );
661+ }
662+
611663/**
612664 * smack_from_secid - find the Smack label associated with a secid
613665 * @secid: an integer that might be associated with a Smack label
0 commit comments