diff options
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r-- | security/smack/smackfs.c | 369 |
1 files changed, 243 insertions, 126 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 247dc9ebbc71..bf107a389ac1 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/vmalloc.h> | 20 | #include <linux/vmalloc.h> |
21 | #include <linux/security.h> | 21 | #include <linux/security.h> |
22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
23 | #include <net/net_namespace.h> | ||
23 | #include <net/netlabel.h> | 24 | #include <net/netlabel.h> |
24 | #include <net/cipso_ipv4.h> | 25 | #include <net/cipso_ipv4.h> |
25 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
@@ -38,7 +39,7 @@ enum smk_inos { | |||
38 | SMK_DOI = 5, /* CIPSO DOI */ | 39 | SMK_DOI = 5, /* CIPSO DOI */ |
39 | SMK_DIRECT = 6, /* CIPSO level indicating direct label */ | 40 | SMK_DIRECT = 6, /* CIPSO level indicating direct label */ |
40 | SMK_AMBIENT = 7, /* internet ambient label */ | 41 | SMK_AMBIENT = 7, /* internet ambient label */ |
41 | SMK_NLTYPE = 8, /* label scheme to use by default */ | 42 | SMK_NETLBLADDR = 8, /* single label hosts */ |
42 | SMK_ONLYCAP = 9, /* the only "capable" label */ | 43 | SMK_ONLYCAP = 9, /* the only "capable" label */ |
43 | }; | 44 | }; |
44 | 45 | ||
@@ -48,6 +49,7 @@ enum smk_inos { | |||
48 | static DEFINE_MUTEX(smack_list_lock); | 49 | static DEFINE_MUTEX(smack_list_lock); |
49 | static DEFINE_MUTEX(smack_cipso_lock); | 50 | static DEFINE_MUTEX(smack_cipso_lock); |
50 | static DEFINE_MUTEX(smack_ambient_lock); | 51 | static DEFINE_MUTEX(smack_ambient_lock); |
52 | static DEFINE_MUTEX(smk_netlbladdr_lock); | ||
51 | 53 | ||
52 | /* | 54 | /* |
53 | * This is the "ambient" label for network traffic. | 55 | * This is the "ambient" label for network traffic. |
@@ -57,12 +59,6 @@ static DEFINE_MUTEX(smack_ambient_lock); | |||
57 | char *smack_net_ambient = smack_known_floor.smk_known; | 59 | char *smack_net_ambient = smack_known_floor.smk_known; |
58 | 60 | ||
59 | /* | 61 | /* |
60 | * This is the default packet marking scheme for network traffic. | ||
61 | * It can be reset via smackfs/nltype | ||
62 | */ | ||
63 | int smack_net_nltype = NETLBL_NLTYPE_CIPSOV4; | ||
64 | |||
65 | /* | ||
66 | * This is the level in a CIPSO header that indicates a | 62 | * This is the level in a CIPSO header that indicates a |
67 | * smack label is contained directly in the category set. | 63 | * smack label is contained directly in the category set. |
68 | * It can be reset via smackfs/direct | 64 | * It can be reset via smackfs/direct |
@@ -79,6 +75,13 @@ int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT; | |||
79 | */ | 75 | */ |
80 | char *smack_onlycap; | 76 | char *smack_onlycap; |
81 | 77 | ||
78 | /* | ||
79 | * Certain IP addresses may be designated as single label hosts. | ||
80 | * Packets are sent there unlabeled, but only from tasks that | ||
81 | * can write to the specified label. | ||
82 | */ | ||
83 | struct smk_netlbladdr *smack_netlbladdrs; | ||
84 | |||
82 | static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; | 85 | static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; |
83 | struct smk_list_entry *smack_list; | 86 | struct smk_list_entry *smack_list; |
84 | 87 | ||
@@ -104,6 +107,24 @@ struct smk_list_entry *smack_list; | |||
104 | #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) | 107 | #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) |
105 | #define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) | 108 | #define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) |
106 | 109 | ||
110 | /** | ||
111 | * smk_netlabel_audit_set - fill a netlbl_audit struct | ||
112 | * @nap: structure to fill | ||
113 | */ | ||
114 | static void smk_netlabel_audit_set(struct netlbl_audit *nap) | ||
115 | { | ||
116 | nap->loginuid = audit_get_loginuid(current); | ||
117 | nap->sessionid = audit_get_sessionid(current); | ||
118 | nap->secid = smack_to_secid(current_security()); | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * Values for parsing single label host rules | ||
123 | * "1.2.3.4 X" | ||
124 | * "192.168.138.129/32 abcdefghijklmnopqrstuvw" | ||
125 | */ | ||
126 | #define SMK_NETLBLADDRMIN 9 | ||
127 | #define SMK_NETLBLADDRMAX 42 | ||
107 | 128 | ||
108 | /* | 129 | /* |
109 | * Seq_file read operations for /smack/load | 130 | * Seq_file read operations for /smack/load |
@@ -344,13 +365,11 @@ static void smk_cipso_doi(void) | |||
344 | { | 365 | { |
345 | int rc; | 366 | int rc; |
346 | struct cipso_v4_doi *doip; | 367 | struct cipso_v4_doi *doip; |
347 | struct netlbl_audit audit_info; | 368 | struct netlbl_audit nai; |
348 | 369 | ||
349 | audit_info.loginuid = audit_get_loginuid(current); | 370 | smk_netlabel_audit_set(&nai); |
350 | audit_info.sessionid = audit_get_sessionid(current); | ||
351 | audit_info.secid = smack_to_secid(current_security()); | ||
352 | 371 | ||
353 | rc = netlbl_cfg_map_del(NULL, &audit_info); | 372 | rc = netlbl_cfg_map_del(NULL, PF_INET, NULL, NULL, &nai); |
354 | if (rc != 0) | 373 | if (rc != 0) |
355 | printk(KERN_WARNING "%s:%d remove rc = %d\n", | 374 | printk(KERN_WARNING "%s:%d remove rc = %d\n", |
356 | __func__, __LINE__, rc); | 375 | __func__, __LINE__, rc); |
@@ -365,11 +384,19 @@ static void smk_cipso_doi(void) | |||
365 | for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++) | 384 | for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++) |
366 | doip->tags[rc] = CIPSO_V4_TAG_INVALID; | 385 | doip->tags[rc] = CIPSO_V4_TAG_INVALID; |
367 | 386 | ||
368 | rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info); | 387 | rc = netlbl_cfg_cipsov4_add(doip, &nai); |
369 | if (rc != 0) { | 388 | if (rc != 0) { |
370 | printk(KERN_WARNING "%s:%d add rc = %d\n", | 389 | printk(KERN_WARNING "%s:%d cipso add rc = %d\n", |
371 | __func__, __LINE__, rc); | 390 | __func__, __LINE__, rc); |
372 | kfree(doip); | 391 | kfree(doip); |
392 | return; | ||
393 | } | ||
394 | rc = netlbl_cfg_cipsov4_map_add(doip->doi, NULL, NULL, NULL, &nai); | ||
395 | if (rc != 0) { | ||
396 | printk(KERN_WARNING "%s:%d map add rc = %d\n", | ||
397 | __func__, __LINE__, rc); | ||
398 | kfree(doip); | ||
399 | return; | ||
373 | } | 400 | } |
374 | } | 401 | } |
375 | 402 | ||
@@ -379,20 +406,19 @@ static void smk_cipso_doi(void) | |||
379 | static void smk_unlbl_ambient(char *oldambient) | 406 | static void smk_unlbl_ambient(char *oldambient) |
380 | { | 407 | { |
381 | int rc; | 408 | int rc; |
382 | struct netlbl_audit audit_info; | 409 | struct netlbl_audit nai; |
383 | 410 | ||
384 | audit_info.loginuid = audit_get_loginuid(current); | 411 | smk_netlabel_audit_set(&nai); |
385 | audit_info.sessionid = audit_get_sessionid(current); | ||
386 | audit_info.secid = smack_to_secid(current_security()); | ||
387 | 412 | ||
388 | if (oldambient != NULL) { | 413 | if (oldambient != NULL) { |
389 | rc = netlbl_cfg_map_del(oldambient, &audit_info); | 414 | rc = netlbl_cfg_map_del(oldambient, PF_INET, NULL, NULL, &nai); |
390 | if (rc != 0) | 415 | if (rc != 0) |
391 | printk(KERN_WARNING "%s:%d remove rc = %d\n", | 416 | printk(KERN_WARNING "%s:%d remove rc = %d\n", |
392 | __func__, __LINE__, rc); | 417 | __func__, __LINE__, rc); |
393 | } | 418 | } |
394 | 419 | ||
395 | rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info); | 420 | rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, |
421 | NULL, NULL, &nai); | ||
396 | if (rc != 0) | 422 | if (rc != 0) |
397 | printk(KERN_WARNING "%s:%d add rc = %d\n", | 423 | printk(KERN_WARNING "%s:%d add rc = %d\n", |
398 | __func__, __LINE__, rc); | 424 | __func__, __LINE__, rc); |
@@ -603,6 +629,201 @@ static const struct file_operations smk_cipso_ops = { | |||
603 | .release = seq_release, | 629 | .release = seq_release, |
604 | }; | 630 | }; |
605 | 631 | ||
632 | /* | ||
633 | * Seq_file read operations for /smack/netlabel | ||
634 | */ | ||
635 | |||
636 | static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos) | ||
637 | { | ||
638 | if (*pos == SEQ_READ_FINISHED) | ||
639 | return NULL; | ||
640 | |||
641 | return smack_netlbladdrs; | ||
642 | } | ||
643 | |||
644 | static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
645 | { | ||
646 | struct smk_netlbladdr *skp = ((struct smk_netlbladdr *) v)->smk_next; | ||
647 | |||
648 | if (skp == NULL) | ||
649 | *pos = SEQ_READ_FINISHED; | ||
650 | |||
651 | return skp; | ||
652 | } | ||
653 | /* | ||
654 | #define BEMASK 0x80000000 | ||
655 | */ | ||
656 | #define BEMASK 0x00000001 | ||
657 | #define BEBITS (sizeof(__be32) * 8) | ||
658 | |||
659 | /* | ||
660 | * Print host/label pairs | ||
661 | */ | ||
662 | static int netlbladdr_seq_show(struct seq_file *s, void *v) | ||
663 | { | ||
664 | struct smk_netlbladdr *skp = (struct smk_netlbladdr *) v; | ||
665 | unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr; | ||
666 | __be32 bebits; | ||
667 | int maskn = 0; | ||
668 | |||
669 | for (bebits = BEMASK; bebits != 0; maskn++, bebits <<= 1) | ||
670 | if ((skp->smk_mask.s_addr & bebits) == 0) | ||
671 | break; | ||
672 | |||
673 | seq_printf(s, "%u.%u.%u.%u/%d %s\n", | ||
674 | hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label); | ||
675 | |||
676 | return 0; | ||
677 | } | ||
678 | |||
679 | static void netlbladdr_seq_stop(struct seq_file *s, void *v) | ||
680 | { | ||
681 | /* No-op */ | ||
682 | } | ||
683 | |||
684 | static struct seq_operations netlbladdr_seq_ops = { | ||
685 | .start = netlbladdr_seq_start, | ||
686 | .stop = netlbladdr_seq_stop, | ||
687 | .next = netlbladdr_seq_next, | ||
688 | .show = netlbladdr_seq_show, | ||
689 | }; | ||
690 | |||
691 | /** | ||
692 | * smk_open_netlbladdr - open() for /smack/netlabel | ||
693 | * @inode: inode structure representing file | ||
694 | * @file: "netlabel" file pointer | ||
695 | * | ||
696 | * Connect our netlbladdr_seq_* operations with /smack/netlabel | ||
697 | * file_operations | ||
698 | */ | ||
699 | static int smk_open_netlbladdr(struct inode *inode, struct file *file) | ||
700 | { | ||
701 | return seq_open(file, &netlbladdr_seq_ops); | ||
702 | } | ||
703 | |||
704 | /** | ||
705 | * smk_write_netlbladdr - write() for /smack/netlabel | ||
706 | * @filp: file pointer, not actually used | ||
707 | * @buf: where to get the data from | ||
708 | * @count: bytes sent | ||
709 | * @ppos: where to start | ||
710 | * | ||
711 | * Accepts only one netlbladdr per write call. | ||
712 | * Returns number of bytes written or error code, as appropriate | ||
713 | */ | ||
714 | static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | ||
715 | size_t count, loff_t *ppos) | ||
716 | { | ||
717 | struct smk_netlbladdr *skp; | ||
718 | struct sockaddr_in newname; | ||
719 | char smack[SMK_LABELLEN]; | ||
720 | char *sp; | ||
721 | char data[SMK_NETLBLADDRMAX]; | ||
722 | char *host = (char *)&newname.sin_addr.s_addr; | ||
723 | int rc; | ||
724 | struct netlbl_audit audit_info; | ||
725 | struct in_addr mask; | ||
726 | unsigned int m; | ||
727 | __be32 bebits = BEMASK; | ||
728 | __be32 nsa; | ||
729 | |||
730 | /* | ||
731 | * Must have privilege. | ||
732 | * No partial writes. | ||
733 | * Enough data must be present. | ||
734 | * "<addr/mask, as a.b.c.d/e><space><label>" | ||
735 | * "<addr, as a.b.c.d><space><label>" | ||
736 | */ | ||
737 | if (!capable(CAP_MAC_ADMIN)) | ||
738 | return -EPERM; | ||
739 | if (*ppos != 0) | ||
740 | return -EINVAL; | ||
741 | if (count < SMK_NETLBLADDRMIN || count > SMK_NETLBLADDRMAX) | ||
742 | return -EINVAL; | ||
743 | if (copy_from_user(data, buf, count) != 0) | ||
744 | return -EFAULT; | ||
745 | |||
746 | data[count] = '\0'; | ||
747 | |||
748 | rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%d %s", | ||
749 | &host[0], &host[1], &host[2], &host[3], &m, smack); | ||
750 | if (rc != 6) { | ||
751 | rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", | ||
752 | &host[0], &host[1], &host[2], &host[3], smack); | ||
753 | if (rc != 5) | ||
754 | return -EINVAL; | ||
755 | m = BEBITS; | ||
756 | } | ||
757 | if (m > BEBITS) | ||
758 | return -EINVAL; | ||
759 | |||
760 | sp = smk_import(smack, 0); | ||
761 | if (sp == NULL) | ||
762 | return -EINVAL; | ||
763 | |||
764 | for (mask.s_addr = 0; m > 0; m--) { | ||
765 | mask.s_addr |= bebits; | ||
766 | bebits <<= 1; | ||
767 | } | ||
768 | /* | ||
769 | * Only allow one writer at a time. Writes should be | ||
770 | * quite rare and small in any case. | ||
771 | */ | ||
772 | mutex_lock(&smk_netlbladdr_lock); | ||
773 | |||
774 | nsa = newname.sin_addr.s_addr; | ||
775 | for (skp = smack_netlbladdrs; skp != NULL; skp = skp->smk_next) | ||
776 | if (skp->smk_host.sin_addr.s_addr == nsa && | ||
777 | skp->smk_mask.s_addr == mask.s_addr) | ||
778 | break; | ||
779 | |||
780 | smk_netlabel_audit_set(&audit_info); | ||
781 | |||
782 | if (skp == NULL) { | ||
783 | skp = kzalloc(sizeof(*skp), GFP_KERNEL); | ||
784 | if (skp == NULL) | ||
785 | rc = -ENOMEM; | ||
786 | else { | ||
787 | rc = 0; | ||
788 | skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr; | ||
789 | skp->smk_mask.s_addr = mask.s_addr; | ||
790 | skp->smk_next = smack_netlbladdrs; | ||
791 | skp->smk_label = sp; | ||
792 | smack_netlbladdrs = skp; | ||
793 | } | ||
794 | } else { | ||
795 | rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, | ||
796 | &skp->smk_host.sin_addr, &skp->smk_mask, | ||
797 | PF_INET, &audit_info); | ||
798 | skp->smk_label = sp; | ||
799 | } | ||
800 | |||
801 | /* | ||
802 | * Now tell netlabel about the single label nature of | ||
803 | * this host so that incoming packets get labeled. | ||
804 | */ | ||
805 | |||
806 | if (rc == 0) | ||
807 | rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, | ||
808 | &skp->smk_host.sin_addr, &skp->smk_mask, PF_INET, | ||
809 | smack_to_secid(skp->smk_label), &audit_info); | ||
810 | |||
811 | if (rc == 0) | ||
812 | rc = count; | ||
813 | |||
814 | mutex_unlock(&smk_netlbladdr_lock); | ||
815 | |||
816 | return rc; | ||
817 | } | ||
818 | |||
819 | static const struct file_operations smk_netlbladdr_ops = { | ||
820 | .open = smk_open_netlbladdr, | ||
821 | .read = seq_read, | ||
822 | .llseek = seq_lseek, | ||
823 | .write = smk_write_netlbladdr, | ||
824 | .release = seq_release, | ||
825 | }; | ||
826 | |||
606 | /** | 827 | /** |
607 | * smk_read_doi - read() for /smack/doi | 828 | * smk_read_doi - read() for /smack/doi |
608 | * @filp: file pointer, not actually used | 829 | * @filp: file pointer, not actually used |
@@ -891,110 +1112,6 @@ static const struct file_operations smk_onlycap_ops = { | |||
891 | .write = smk_write_onlycap, | 1112 | .write = smk_write_onlycap, |
892 | }; | 1113 | }; |
893 | 1114 | ||
894 | struct option_names { | ||
895 | int o_number; | ||
896 | char *o_name; | ||
897 | char *o_alias; | ||
898 | }; | ||
899 | |||
900 | static struct option_names netlbl_choices[] = { | ||
901 | { NETLBL_NLTYPE_RIPSO, | ||
902 | NETLBL_NLTYPE_RIPSO_NAME, "ripso" }, | ||
903 | { NETLBL_NLTYPE_CIPSOV4, | ||
904 | NETLBL_NLTYPE_CIPSOV4_NAME, "cipsov4" }, | ||
905 | { NETLBL_NLTYPE_CIPSOV4, | ||
906 | NETLBL_NLTYPE_CIPSOV4_NAME, "cipso" }, | ||
907 | { NETLBL_NLTYPE_CIPSOV6, | ||
908 | NETLBL_NLTYPE_CIPSOV6_NAME, "cipsov6" }, | ||
909 | { NETLBL_NLTYPE_UNLABELED, | ||
910 | NETLBL_NLTYPE_UNLABELED_NAME, "unlabeled" }, | ||
911 | }; | ||
912 | |||
913 | /** | ||
914 | * smk_read_nltype - read() for /smack/nltype | ||
915 | * @filp: file pointer, not actually used | ||
916 | * @buf: where to put the result | ||
917 | * @count: maximum to send along | ||
918 | * @ppos: where to start | ||
919 | * | ||
920 | * Returns number of bytes read or error code, as appropriate | ||
921 | */ | ||
922 | static ssize_t smk_read_nltype(struct file *filp, char __user *buf, | ||
923 | size_t count, loff_t *ppos) | ||
924 | { | ||
925 | char bound[40]; | ||
926 | ssize_t rc; | ||
927 | int i; | ||
928 | |||
929 | if (count < SMK_LABELLEN) | ||
930 | return -EINVAL; | ||
931 | |||
932 | if (*ppos != 0) | ||
933 | return 0; | ||
934 | |||
935 | sprintf(bound, "unknown"); | ||
936 | |||
937 | for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++) | ||
938 | if (smack_net_nltype == netlbl_choices[i].o_number) { | ||
939 | sprintf(bound, "%s", netlbl_choices[i].o_name); | ||
940 | break; | ||
941 | } | ||
942 | |||
943 | rc = simple_read_from_buffer(buf, count, ppos, bound, strlen(bound)); | ||
944 | |||
945 | return rc; | ||
946 | } | ||
947 | |||
948 | /** | ||
949 | * smk_write_nltype - write() for /smack/nltype | ||
950 | * @filp: file pointer, not actually used | ||
951 | * @buf: where to get the data from | ||
952 | * @count: bytes sent | ||
953 | * @ppos: where to start | ||
954 | * | ||
955 | * Returns number of bytes written or error code, as appropriate | ||
956 | */ | ||
957 | static ssize_t smk_write_nltype(struct file *file, const char __user *buf, | ||
958 | size_t count, loff_t *ppos) | ||
959 | { | ||
960 | char bound[40]; | ||
961 | char *cp; | ||
962 | int i; | ||
963 | |||
964 | if (!capable(CAP_MAC_ADMIN)) | ||
965 | return -EPERM; | ||
966 | |||
967 | if (count >= 40) | ||
968 | return -EINVAL; | ||
969 | |||
970 | if (copy_from_user(bound, buf, count) != 0) | ||
971 | return -EFAULT; | ||
972 | |||
973 | bound[count] = '\0'; | ||
974 | cp = strchr(bound, ' '); | ||
975 | if (cp != NULL) | ||
976 | *cp = '\0'; | ||
977 | cp = strchr(bound, '\n'); | ||
978 | if (cp != NULL) | ||
979 | *cp = '\0'; | ||
980 | |||
981 | for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++) | ||
982 | if (strcmp(bound, netlbl_choices[i].o_name) == 0 || | ||
983 | strcmp(bound, netlbl_choices[i].o_alias) == 0) { | ||
984 | smack_net_nltype = netlbl_choices[i].o_number; | ||
985 | return count; | ||
986 | } | ||
987 | /* | ||
988 | * Not a valid choice. | ||
989 | */ | ||
990 | return -EINVAL; | ||
991 | } | ||
992 | |||
993 | static const struct file_operations smk_nltype_ops = { | ||
994 | .read = smk_read_nltype, | ||
995 | .write = smk_write_nltype, | ||
996 | }; | ||
997 | |||
998 | /** | 1115 | /** |
999 | * smk_fill_super - fill the /smackfs superblock | 1116 | * smk_fill_super - fill the /smackfs superblock |
1000 | * @sb: the empty superblock | 1117 | * @sb: the empty superblock |
@@ -1021,8 +1138,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) | |||
1021 | {"direct", &smk_direct_ops, S_IRUGO|S_IWUSR}, | 1138 | {"direct", &smk_direct_ops, S_IRUGO|S_IWUSR}, |
1022 | [SMK_AMBIENT] = | 1139 | [SMK_AMBIENT] = |
1023 | {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR}, | 1140 | {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR}, |
1024 | [SMK_NLTYPE] = | 1141 | [SMK_NETLBLADDR] = |
1025 | {"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR}, | 1142 | {"netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR}, |
1026 | [SMK_ONLYCAP] = | 1143 | [SMK_ONLYCAP] = |
1027 | {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR}, | 1144 | {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR}, |
1028 | /* last one */ {""} | 1145 | /* last one */ {""} |