1313 */
1414
1515#include <linux/audit.h>
16+ #include <linux/security.h>
1617
1718#include "include/audit.h"
1819#include "include/context.h"
@@ -36,6 +37,11 @@ static void audit_cb(struct audit_buffer *ab, void *va)
3637
3738 audit_log_format (ab , " rlimit=%s value=%lu" ,
3839 rlim_names [aad (sa )-> rlim .rlim ], aad (sa )-> rlim .max );
40+ if (aad (sa )-> peer ) {
41+ audit_log_format (ab , " peer=" );
42+ aa_label_xaudit (ab , labels_ns (aad (sa )-> label ), aad (sa )-> peer ,
43+ FLAGS_NONE , GFP_ATOMIC );
44+ }
3945}
4046
4147/**
@@ -48,13 +54,17 @@ static void audit_cb(struct audit_buffer *ab, void *va)
4854 * Returns: 0 or sa->error else other error code on failure
4955 */
5056static int audit_resource (struct aa_profile * profile , unsigned int resource ,
51- unsigned long value , int error )
57+ unsigned long value , struct aa_label * peer ,
58+ const char * info , int error )
5259{
5360 DEFINE_AUDIT_DATA (sa , LSM_AUDIT_DATA_NONE , OP_SETRLIMIT );
5461
5562 aad (& sa )-> rlim .rlim = resource ;
5663 aad (& sa )-> rlim .max = value ;
64+ aad (& sa )-> peer = peer ;
65+ aad (& sa )-> info = info ;
5766 aad (& sa )-> error = error ;
67+
5868 return aa_audit (AUDIT_APPARMOR_AUTO , profile , & sa , audit_cb );
5969}
6070
@@ -72,9 +82,21 @@ int aa_map_resource(int resource)
7282 return rlim_map [resource ];
7383}
7484
85+ static int profile_setrlimit (struct aa_profile * profile , unsigned int resource ,
86+ struct rlimit * new_rlim )
87+ {
88+ int e = 0 ;
89+
90+ if (profile -> rlimits .mask & (1 << resource ) && new_rlim -> rlim_max >
91+ profile -> rlimits .limits [resource ].rlim_max )
92+ e = - EACCES ;
93+ return audit_resource (profile , resource , new_rlim -> rlim_max , NULL , NULL ,
94+ e );
95+ }
96+
7597/**
7698 * aa_task_setrlimit - test permission to set an rlimit
77- * @profile - profile confining the task (NOT NULL)
99+ * @label - label confining the task (NOT NULL)
78100 * @task - task the resource is being set on
79101 * @resource - the resource being set
80102 * @new_rlim - the new resource limit (NOT NULL)
@@ -83,14 +105,15 @@ int aa_map_resource(int resource)
83105 *
84106 * Returns: 0 or error code if setting resource failed
85107 */
86- int aa_task_setrlimit (struct aa_profile * profile , struct task_struct * task ,
108+ int aa_task_setrlimit (struct aa_label * label , struct task_struct * task ,
87109 unsigned int resource , struct rlimit * new_rlim )
88110{
89- struct aa_label * task_label ;
111+ struct aa_profile * profile ;
112+ struct aa_label * peer ;
90113 int error = 0 ;
91114
92115 rcu_read_lock ();
93- task_label = aa_get_newest_cred_label (( __task_cred (task ) ));
116+ peer = aa_get_newest_cred_label (__task_cred (task ));
94117 rcu_read_unlock ();
95118
96119 /* TODO: extend resource control to handle other (non current)
@@ -99,53 +122,70 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
99122 * the same profile or that the task setting the resource of another
100123 * task has CAP_SYS_RESOURCE.
101124 */
102- if ((profile != labels_profile (task_label ) &&
103- aa_capable (& profile -> label , CAP_SYS_RESOURCE , 1 )) ||
104- (profile -> rlimits .mask & (1 << resource ) &&
105- new_rlim -> rlim_max > profile -> rlimits .limits [resource ].rlim_max ))
106- error = - EACCES ;
107125
108- aa_put_label (task_label );
109-
110- return audit_resource (profile , resource , new_rlim -> rlim_max , error );
126+ if (label != peer &&
127+ !aa_capable (label , CAP_SYS_RESOURCE , SECURITY_CAP_NOAUDIT ))
128+ error = fn_for_each (label , profile ,
129+ audit_resource (profile , resource ,
130+ new_rlim -> rlim_max , peer ,
131+ "cap_sys_resoure" , - EACCES ));
132+ else
133+ error = fn_for_each_confined (label , profile ,
134+ profile_setrlimit (profile , resource , new_rlim ));
135+ aa_put_label (peer );
136+
137+ return error ;
111138}
112139
113140/**
114141 * __aa_transition_rlimits - apply new profile rlimits
115- * @old : old profile on task (NOT NULL)
116- * @new : new profile with rlimits to apply (NOT NULL)
142+ * @old_l : old label on task (NOT NULL)
143+ * @new_l : new label with rlimits to apply (NOT NULL)
117144 */
118- void __aa_transition_rlimits (struct aa_profile * old , struct aa_profile * new )
145+ void __aa_transition_rlimits (struct aa_label * old_l , struct aa_label * new_l )
119146{
120147 unsigned int mask = 0 ;
121148 struct rlimit * rlim , * initrlim ;
122- int i ;
149+ struct aa_profile * old , * new ;
150+ struct label_it i ;
151+
152+ old = labels_profile (old_l );
153+ new = labels_profile (new_l );
123154
124- /* for any rlimits the profile controlled reset the soft limit
125- * to the less of the tasks hard limit and the init tasks soft limit
155+ /* for any rlimits the profile controlled, reset the soft limit
156+ * to the lesser of the tasks hard limit and the init tasks soft limit
126157 */
127- if (old -> rlimits .mask ) {
128- for (i = 0 , mask = 1 ; i < RLIM_NLIMITS ; i ++ , mask <<= 1 ) {
129- if (old -> rlimits .mask & mask ) {
130- rlim = current -> signal -> rlim + i ;
131- initrlim = init_task .signal -> rlim + i ;
132- rlim -> rlim_cur = min (rlim -> rlim_max ,
133- initrlim -> rlim_cur );
158+ label_for_each_confined (i , old_l , old ) {
159+ if (old -> rlimits .mask ) {
160+ int j ;
161+
162+ for (j = 0 , mask = 1 ; j < RLIM_NLIMITS ; j ++ ,
163+ mask <<= 1 ) {
164+ if (old -> rlimits .mask & mask ) {
165+ rlim = current -> signal -> rlim + j ;
166+ initrlim = init_task .signal -> rlim + j ;
167+ rlim -> rlim_cur = min (rlim -> rlim_max ,
168+ initrlim -> rlim_cur );
169+ }
134170 }
135171 }
136172 }
137173
138174 /* set any new hard limits as dictated by the new profile */
139- if (!new -> rlimits .mask )
140- return ;
141- for (i = 0 , mask = 1 ; i < RLIM_NLIMITS ; i ++ , mask <<= 1 ) {
142- if (!(new -> rlimits .mask & mask ))
143- continue ;
175+ label_for_each_confined (i , new_l , new ) {
176+ int j ;
144177
145- rlim = current -> signal -> rlim + i ;
146- rlim -> rlim_max = min (rlim -> rlim_max ,
147- new -> rlimits .limits [i ].rlim_max );
148- /* soft limit should not exceed hard limit */
149- rlim -> rlim_cur = min (rlim -> rlim_cur , rlim -> rlim_max );
178+ if (!new -> rlimits .mask )
179+ continue ;
180+ for (j = 0 , mask = 1 ; j < RLIM_NLIMITS ; j ++ , mask <<= 1 ) {
181+ if (!(new -> rlimits .mask & mask ))
182+ continue ;
183+
184+ rlim = current -> signal -> rlim + j ;
185+ rlim -> rlim_max = min (rlim -> rlim_max ,
186+ new -> rlimits .limits [j ].rlim_max );
187+ /* soft limit should not exceed hard limit */
188+ rlim -> rlim_cur = min (rlim -> rlim_cur , rlim -> rlim_max );
189+ }
150190 }
151191}
0 commit comments