@@ -776,6 +776,55 @@ static int apparmor_sb_pivotroot(const struct path *old_path,
776
776
return error ;
777
777
}
778
778
779
+ static int apparmor_getselfattr (unsigned int attr , struct lsm_ctx __user * lx ,
780
+ size_t * size , u32 flags )
781
+ {
782
+ int error = - ENOENT ;
783
+ struct aa_task_ctx * ctx = task_ctx (current );
784
+ struct aa_label * label = NULL ;
785
+ size_t total_len = 0 ;
786
+ char * value ;
787
+
788
+ switch (attr ) {
789
+ case LSM_ATTR_CURRENT :
790
+ label = aa_get_newest_label (cred_label (current_cred ()));
791
+ break ;
792
+ case LSM_ATTR_PREV :
793
+ if (ctx -> previous )
794
+ label = aa_get_newest_label (ctx -> previous );
795
+ break ;
796
+ case LSM_ATTR_EXEC :
797
+ if (ctx -> onexec )
798
+ label = aa_get_newest_label (ctx -> onexec );
799
+ break ;
800
+ default :
801
+ error = - EOPNOTSUPP ;
802
+ break ;
803
+ }
804
+
805
+ if (label ) {
806
+ error = aa_getprocattr (label , & value , false);
807
+ if (error > 0 ) {
808
+ total_len = ALIGN (struct_size (lx , ctx , error ), 8 );
809
+ if (total_len > * size )
810
+ error = - E2BIG ;
811
+ else if (lx )
812
+ error = lsm_fill_user_ctx (lx , value , error ,
813
+ LSM_ID_APPARMOR , 0 );
814
+ else
815
+ error = 1 ;
816
+ }
817
+ kfree (value );
818
+ }
819
+
820
+ aa_put_label (label );
821
+
822
+ * size = total_len ;
823
+ if (error < 0 )
824
+ return error ;
825
+ return 1 ;
826
+ }
827
+
779
828
static int apparmor_getprocattr (struct task_struct * task , const char * name ,
780
829
char * * value )
781
830
{
@@ -795,16 +844,15 @@ static int apparmor_getprocattr(struct task_struct *task, const char *name,
795
844
error = - EINVAL ;
796
845
797
846
if (label )
798
- error = aa_getprocattr (label , value );
847
+ error = aa_getprocattr (label , value , true );
799
848
800
849
aa_put_label (label );
801
850
put_cred (cred );
802
851
803
852
return error ;
804
853
}
805
854
806
- static int apparmor_setprocattr (const char * name , void * value ,
807
- size_t size )
855
+ static int do_setattr (u64 attr , void * value , size_t size )
808
856
{
809
857
char * command , * largs = NULL , * args = value ;
810
858
size_t arg_size ;
@@ -835,7 +883,7 @@ static int apparmor_setprocattr(const char *name, void *value,
835
883
goto out ;
836
884
837
885
arg_size = size - (args - (largs ? largs : (char * ) value ));
838
- if (strcmp ( name , "current" ) == 0 ) {
886
+ if (attr == LSM_ATTR_CURRENT ) {
839
887
if (strcmp (command , "changehat" ) == 0 ) {
840
888
error = aa_setprocattr_changehat (args , arg_size ,
841
889
AA_CHANGE_NOFLAGS );
@@ -850,7 +898,7 @@ static int apparmor_setprocattr(const char *name, void *value,
850
898
error = aa_change_profile (args , AA_CHANGE_STACK );
851
899
} else
852
900
goto fail ;
853
- } else if (strcmp ( name , "exec" ) == 0 ) {
901
+ } else if (attr == LSM_ATTR_EXEC ) {
854
902
if (strcmp (command , "exec" ) == 0 )
855
903
error = aa_change_profile (args , AA_CHANGE_ONEXEC );
856
904
else if (strcmp (command , "stack" ) == 0 )
@@ -870,13 +918,42 @@ static int apparmor_setprocattr(const char *name, void *value,
870
918
871
919
fail :
872
920
ad .subj_label = begin_current_label_crit_section ();
873
- ad .info = name ;
921
+ if (attr == LSM_ATTR_CURRENT )
922
+ ad .info = "current" ;
923
+ else if (attr == LSM_ATTR_EXEC )
924
+ ad .info = "exec" ;
925
+ else
926
+ ad .info = "invalid" ;
874
927
ad .error = error = - EINVAL ;
875
928
aa_audit_msg (AUDIT_APPARMOR_DENIED , & ad , NULL );
876
929
end_current_label_crit_section (ad .subj_label );
877
930
goto out ;
878
931
}
879
932
933
+ static int apparmor_setselfattr (unsigned int attr , struct lsm_ctx * ctx ,
934
+ size_t size , u32 flags )
935
+ {
936
+ int rc ;
937
+
938
+ if (attr != LSM_ATTR_CURRENT && attr != LSM_ATTR_EXEC )
939
+ return - EOPNOTSUPP ;
940
+
941
+ rc = do_setattr (attr , ctx -> ctx , ctx -> ctx_len );
942
+ if (rc > 0 )
943
+ return 0 ;
944
+ return rc ;
945
+ }
946
+
947
+ static int apparmor_setprocattr (const char * name , void * value ,
948
+ size_t size )
949
+ {
950
+ int attr = lsm_name_to_attr (name );
951
+
952
+ if (attr )
953
+ return do_setattr (attr , value , size );
954
+ return - EINVAL ;
955
+ }
956
+
880
957
/**
881
958
* apparmor_bprm_committing_creds - do task cleanup on committing new creds
882
959
* @bprm: binprm for the exec (NOT NULL)
@@ -1424,6 +1501,8 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {
1424
1501
LSM_HOOK_INIT (file_lock , apparmor_file_lock ),
1425
1502
LSM_HOOK_INIT (file_truncate , apparmor_file_truncate ),
1426
1503
1504
+ LSM_HOOK_INIT (getselfattr , apparmor_getselfattr ),
1505
+ LSM_HOOK_INIT (setselfattr , apparmor_setselfattr ),
1427
1506
LSM_HOOK_INIT (getprocattr , apparmor_getprocattr ),
1428
1507
LSM_HOOK_INIT (setprocattr , apparmor_setprocattr ),
1429
1508
0 commit comments