summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAndrii Nakryiko <andrii@kernel.org>2023-11-30 10:52:19 -0800
committerAlexei Starovoitov <ast@kernel.org>2023-12-06 10:02:59 -0800
commit4cbb270e115bc197ff2046aeb54cc951666b16ec (patch)
tree649b1a6a47043000dff55125dc5a91ad91fd24b7 /kernel
parente1cef620f598853a90f17701fcb1057a6768f7b8 (diff)
downloadlinux-4cbb270e115bc197ff2046aeb54cc951666b16ec.tar.gz
linux-4cbb270e115bc197ff2046aeb54cc951666b16ec.tar.bz2
linux-4cbb270e115bc197ff2046aeb54cc951666b16ec.zip
bpf: take into account BPF token when fetching helper protos
Instead of performing unconditional system-wide bpf_capable() and perfmon_capable() calls inside bpf_base_func_proto() function (and other similar ones) to determine eligibility of a given BPF helper for a given program, use previously recorded BPF token during BPF_PROG_LOAD command handling to inform the decision. Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/r/20231130185229.2688956-8-andrii@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/bpf/cgroup.c6
-rw-r--r--kernel/bpf/helpers.c6
-rw-r--r--kernel/bpf/syscall.c5
-rw-r--r--kernel/trace/bpf_trace.c2
4 files changed, 10 insertions, 9 deletions
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 491d20038cbe..98e0e3835b28 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -1630,7 +1630,7 @@ cgroup_dev_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
case BPF_FUNC_perf_event_output:
return &bpf_event_output_data_proto;
default:
- return bpf_base_func_proto(func_id);
+ return bpf_base_func_proto(func_id, prog);
}
}
@@ -2191,7 +2191,7 @@ sysctl_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
case BPF_FUNC_perf_event_output:
return &bpf_event_output_data_proto;
default:
- return bpf_base_func_proto(func_id);
+ return bpf_base_func_proto(func_id, prog);
}
}
@@ -2348,7 +2348,7 @@ cg_sockopt_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
case BPF_FUNC_perf_event_output:
return &bpf_event_output_data_proto;
default:
- return bpf_base_func_proto(func_id);
+ return bpf_base_func_proto(func_id, prog);
}
}
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index ee9bdf29246a..b3be5742d6f1 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -1679,7 +1679,7 @@ const struct bpf_func_proto bpf_probe_read_kernel_str_proto __weak;
const struct bpf_func_proto bpf_task_pt_regs_proto __weak;
const struct bpf_func_proto *
-bpf_base_func_proto(enum bpf_func_id func_id)
+bpf_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
switch (func_id) {
case BPF_FUNC_map_lookup_elem:
@@ -1730,7 +1730,7 @@ bpf_base_func_proto(enum bpf_func_id func_id)
break;
}
- if (!bpf_capable())
+ if (!bpf_token_capable(prog->aux->token, CAP_BPF))
return NULL;
switch (func_id) {
@@ -1788,7 +1788,7 @@ bpf_base_func_proto(enum bpf_func_id func_id)
break;
}
- if (!perfmon_capable())
+ if (!bpf_token_capable(prog->aux->token, CAP_PERFMON))
return NULL;
switch (func_id) {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 2c8393c21b8c..1cc03f08c9cd 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -5712,7 +5712,7 @@ static const struct bpf_func_proto bpf_sys_bpf_proto = {
const struct bpf_func_proto * __weak
tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
- return bpf_base_func_proto(func_id);
+ return bpf_base_func_proto(func_id, prog);
}
BPF_CALL_1(bpf_sys_close, u32, fd)
@@ -5762,7 +5762,8 @@ syscall_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
switch (func_id) {
case BPF_FUNC_sys_bpf:
- return !perfmon_capable() ? NULL : &bpf_sys_bpf_proto;
+ return !bpf_token_capable(prog->aux->token, CAP_PERFMON)
+ ? NULL : &bpf_sys_bpf_proto;
case BPF_FUNC_btf_find_by_name_kind:
return &bpf_btf_find_by_name_kind_proto;
case BPF_FUNC_sys_close:
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 1648bde28f01..774cf476a892 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1626,7 +1626,7 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
case BPF_FUNC_trace_vprintk:
return bpf_get_trace_vprintk_proto();
default:
- return bpf_base_func_proto(func_id);
+ return bpf_base_func_proto(func_id, prog);
}
}
'?8B Z w&*𜅌h\~x)fjm?$l01w$ w C\=̡ɡD˽J@<m@~vݨw7K&+|*s7sRa65 #2ًQ!k?NCr(D74=Xmj 4cQMxE t O)i7 `YddP%7,ץ?bVJ?)X9'A wu$maj=:ۭadfq䍗QF{˨ڐ'VYk82b{s͇/Anx_ĔaFZE G35=*\q΀Hٖ_ }+ިP[hLU#mƨ=7yTLA/oȪ=1߿YrHE?7?qKz @Ua C:O=^qnbf$E<6īH²15Ձ6 \13Q|$n:5ȁB߶XU+zQgW[yo~r3}LC"8[gpA q+cT2/tJ%˻Ųt0I?׷xHTvwǥlwP=T!eJwSfkLc $o\s@!~X[mc\D&wo fP)NoN}\p"!U6y1nNWxPz\%BOuH-k+VsVUW=L)]%IFM0S")FSQ_0M(#~O7Z!l.+o=El,q&3'jRyJL@"a lzɤa=mA>EMHIKu?_`BVdۯσ$&! 3sUZ>uY k|"QC}wO|U&Gnwߩ苟X{.7L*AD uk:'vcT$ -Mb)$GDHG#G)x܈z53q^a~jeWj| HD-R6!3euDq6vT$ |4A_u~maɟrkyU܈,e@Weޏet-m~i_r`Re$}2=S, {a:`5Ѵj~G9&_yje}7V|n0n0:'ݷɳ! 6|p|QH {jvc}|j~ﷳEyk.5Tﹷq&24eKsY_\tTHNzOXO^ @ԇ> }7_*)u3`@ɇ/̱]MSW8gD:MGvr(oɯ]6;&9{ۆ_<{ c']wv{>qkiOag?gg%{\G/Ni:+#pg974uB͈l#m ?(NR`SĦB#W-(ʱqtl|jHq-b~>{ '($<1ݔŊ6`A yCDT!Db 0* GqsUl4@lKFjUD_AhG^DU3M jDbUNd7ϕK#ðtv߇R[irEGx+?Qy TQQHxZl%ʈqrnoK}nNP.4Gd},upM7B^MPuiyF=1_o7{}dt(1v^q10 '܉,>?%W[GS9 r~^96Dfΰ"psM笟Gt Kl4PW՞_#mDhc?߿PO)\.3JX5K y _'y/ʫ:1/;?bd鏖ieW^|:9U>q5Ճׇ7@vu.ᚘN>kyןW?d1QֺGa6zYٝy6aJtsU&,5R8NyxÛW^ye]ʽC8w0rmv:;.xX}S m٤0SNRvj'wVf=u}W;lF=,Fx?θa7u7v몯Ku=v ;vs)-*UUٝ8Vm~jÏCu]{lFͫnQZwv3 A+۝/pzFPfgfy]鈺NޅAB9 ?U]:aNz[߉\Swg:Fvk,/$rr S8Eo ovDžx;+SV&I`$__K^#/`iVgaRӬ[:Ǜ%V?A^56/y{nu 7놧qs [\^28+H":Z/A#&z^8a1jK(7CڸT+%0c[k-sx۳>|T~?̿&7?{>AWa,يwCy>\5kʫxX( gۄKz v!Vh6Vv <~hIfAN ƌi@us5>6cj>6/}j  @orGń˭+{q GDC G$;yնX3h,(bH">{ƹ 5gs!')%ԁNi&L ͌÷-+Ӎ{wt}*VY ~ 6ۧV GVÎ( ǯC輹:I[e \5ihf39" 6l1科ק>z'f{N \E؅E,0)gF4%&![@U\Je׺dҰ(ۡ7u•16 EZ CGT>Y u/Ʒ'BJ f7-X|EZ+vZ@_CG6C/sS^K.ϋцjs8CU Hfv`g$nB昫j!̀vr}[9wֻ4k :B\>qǎ naZ0yF* ގ;rOUYK9w>A1Lv1wGBw0_ظr ʮ]뢱a ~l#|7hCS\2?H1rQH|BFvc'?t /pjf8}5Sn\qN.<.k,Wp42@ dr.\Ŷ/ખ ߝG?Q.PT%  ~lqv|`Mb?MC=>1'n —D0"rPM1 amj< E bk?~G}Z.{Nknl(CbP$H"0#MacAob[g} oΠCOՌ|g\!veH0ӿfܫVc*Żڮd߷ӫXԗ уo-_ S !iV*;VW7/j9B@v ~A=}vQevDMR\~Y~Z#T`\ֳay^~aW?ѓ'J0SȱC?kz1c>TL hx0K#@ G.Ɓ/jA#}un¨jcA`;Ɍ& _!b$>Iа&YX<|oLoP _ o} 甴/ VXJ#9UIڮkO/z޼3r5As#B: یLG DOkwLt+'q$-0ċ Kg CzbSʵA\|֫g9DT >=k%y4j.lNxoN.?WI%aӎ _n[*5 z!Q2CYkq{:E">b]L: o0UM$~ ڢ#Q3rA20q㽆D_c ]4?,ÂOl9 L")@no4}[\>=f#Q1LAC|pW藝{rꍐwyڗEZ@ XVQPC盲47a |11lEDd8<7``̂x@nE:5W_#=8iW]>gW-.cM"=ؽ;"OT^0Dfp2.Pps-, RRҺzVv{M'H'?v/m74c'kK('Nk>u1iA;]͵Uşt\z>:bB$lQ)a**[ ^h<7|6_a&@#Q?KNF×<|Qo*o%/pƺgDwtksc(>aU Ptk7]S(z>GsUd*aC҆;g~Hknj6 v3f }|htN ?jS~jvQAO[!/cŬ5_#$O4iΜ6QXR=v f)/,W vXN>xlak@ն0 iQ:RLrB{)Fˀɜbo8yd#L+'3<-LϠEzgC%_7g犺*Xa[G5vJAٔaalJ $ Cݧ腀,#ڠp"uhǺ9̭vj`8v,s1;6pX͆'m~7Z 0c:h'X;;{̠zƫ`.#l3}]'_}ej,9,bPXv9,FpԪIj%~De96.f<t:+!#*' 1 ~KX*"*mc%*ETTWoU-Ge p)\d&1sxUCxmq Y<=GiC䆌9AIycU*);>"cy瓱b:#|dh "h8v#<k. O}Zט[bRL,#Q&w5&~9DˑD(\@Z?'.؋Ϗ`ex4m{U>7bPr{a!a?-d˹Jd 7Çl(kS)@ 2Ў}TYPj[ κ]0P9P!&{;"1r҇5`mYa#nk!^c6vnLdƄtkDD]lr xᢌWw^/|*{134T"Fq\mѩ}mw >]H\)T.blfGݣAr?\A&8$-gy齻pbC)pYVNn5n_.^!|U2Z}zt_E_3,vrW|K՟PEUK2;P"WeGoV_=9k ޚH.y{(D{;j[V6s]T@sw @)0/PR`[>}!3jƒ:rlS^DEE> A6۸s'er3j,; g<6U`+o^2%j2x׮)%czGceUkY.sy5rVW$e),u}GgF{镈KV~E=F`i^LnFd :LU~;h]\GȈtO?g\.[R.FB^3KÌ~}D $PAGntw g e:8{mhrà >:E//%׎ tScC5<܉7i?V j@>@z(#L(@ i^SppKW%=Ӝ"g8Qk7khMu/=:H|ּz8 R0H+cZPDSb#皥}8M-MWÛ[]yav-945UaQ:L_ھ"1NϪӃPuGg~73,85,ʇ҇e`Żrniaփ{9`#˅<-ct<'8Ǜ/ٟc*5 YM-fX*C۳ع A7X"TU  _Z%C_x[x];ރ V@::u5uS'A?!Kw(z_SgTh/>ZsYi;;*\:l>Zl<l"]-VCUY] P> j/vQv?BV0y?d{BeںsޓLP?&a+`Gtz B*n[(QTAGOGX_m_`9TsK 8 ER$7 o 9~Gs0?"j#trC:#PGALmC:h<&$ M`jT6ځ250^_ӮʊfQᡳkjJ> y՞6KIu7LTSصRW/R[*&3ev[ 56"[~Gmp!0(תӟ)δy!M"[=acĪ:懿0,8к$ݝ qM5[OwCKW 21s!:Y8].9l{ֺׅM=Gz,` >.W7h ~K~-V:S5 吓Mes}̡6s[K̈p`{jrAE-E>q1MP BF.?MىIj>t~ lUmm:L{fR1]DcMҖ;` _n޼b8j6oI14TM\S$@I_qE$A׍|͊(7P}PfDl8֩R$D*!7Whw۔^%B>H?TM&YܐN][~p۪h6s^#x `uH@G(L[IjMda7[yL {b4z: \_T_e5q}9U[!V=XlpGX@Anw, w}U܊[¡ͶUUo &)d!P1"#]"A_AFXGM8ң ڢ67eU8p[[hkӬ8(UrNLPL];TT+۲PX~.S@ǣf;Ec"&eD':O0ǑDp^ .1+-/w&eI';7ju:nOlp {ˆGRaًJ|148ʝ=9l~8jt}L.뷍Gt%rsnNE/ eI:gX8s,6g*riy -x^"k HF u6a+,уPK'rM-UR!R (` 풎v Z#zf·ώQIa`9pFq/"*})z%npxdxA+ sxᢋ'׾5S0ι:⩭ tǣJNF^ 7} Oo E܃ΧSz2^*]Ec^]d`V+x};TפNh5\\8pn[%u3 "gaC/&O;8p@k(J x\'&"4 ;/H$LjsO$q|xhsh$@I΄hé-`$;:S񹽀F`s2m Ustg8:[A!6G3o#;|J"B);Y Rrbsz*cMk/F&#gҸ9 2Iڈ:;r%3Q`Pq D$ln&Pr NAjŤ1YBH1cnw@0#37:ֲ8wCqq3.WY9haGbб7/K$o8cCU*Ea[%|~F<̒D\Ax`@;<o"wS{ȂY;B9SZXq vDžN$|+vG&Xۓ ws@m< 룍3ۜLqgٵ.jC%뀛 Ջ`9yD$NDH6D[ΤCϡ0aʃ]aGYp--mv\^Hj3j#Ĺ_T_8XDӠFY:D]_眿{? [W!3ҷZWuaMY'"X `S_,~KDWWig|:;;R:3:{yxu+4/~bu1-;o~ģ@ KaN|s_ߏMҢOi9EpCVpĖl1lّXu\$6mWnՐx2T7`2>3uE"ֶ?da-%w]_kh-Y3h3B6\,YiXZQH|=(}߮>2s<}d/P7'& `h[oR VѾrfu]0|nPYb)SyS9H BlZNsF#G*Z!+{^]ͣx%YWR'su)·А)> *K⣙ ]odm$L ZdY\1 3y_PK] Big]1C󟯛 f^51G cD5Y\??jjkx0ï8Uw]WkFV1FB4&w783 4pĹpWoz'/A @k":ص'k=I@Oul7@o.+gCkyXA@Ou|pu!!$3`T޾PM+~m(t!!x48ݜM^N qWW0~?1/V3oV^-tZBrXFzڨU dju )KMC1E#ٮa<_>OQǯp=~m,7Cq_<׷7u寶ϛJ d۹79]{mW#4?'_ej/ eꦶODUu|p_ȯr%s0'<i+dy $1x_?vʹBUMUTӀ0gٕϼ VU?`(7 bDs%IXUj. Io`vߴV>?%Ukmpg&% xv{o/?b#x Ek=cy5LР2;dbG" #:jGbĤ&'?=\,o&BV 0Bf:u?M2pAu''rEͳ/WmhgT",S]|:W{YEٷ9=ܙ+ ]q BKy<3Q~I3gm=nQ1#[uKEqJuU"ώQg{ٻA笿`I\[1`TFM'qq9w@˼udD;\O/R>*;MT@]?9sqHA"+{յ"64Hs!FK +}_2g\x=:}} =a*#x\J|,J !3EyLV30C~w5}7TX؄ͩzWycY^a"$Ѡ :zQ$%v/U/?C&0 0$tl%HGo..oW W/=rd\!4|Qqa5oSu<~j2H6GZ\Iu:{KhgJ?Lgfar|`Y3baL[[{Y =4ڪG-_'d0݁ \C$_9BRn&TT~۔,*?,=ٹ1\c}[\r/CuC-;ZO2ߐ/@W'r7Y'MZ-ߍNF/u8+"UXRDHkvыBU&gI<dž3&.#!q4;J_~~#s 2V2uSLBo) Z3> AD"aArt>YsNS! Gs{_腬(ʷ2*or| bz5Tny}s'g'Ϥv[%fCeQTQSOS"dLVizR>љ{f&{@HԘ*" J4PԘd&^zVHc1R&MbY}r\/%80^[,KF|yǗ]y>XID^ypuh6F[բ:xk fJr׍{_-^VYvl/p.pGLIq[pnClND%{l:oGC!3eET8u{j8%PP6,.ÄȳpPY$y]Kg9:~qzJ6-U٭weٝ..qQi}"O/TG1A_RG|X_W[1YT1nK?c\掊M+Y_.;U+,X/;w[Krb:jSH99ͅ,'5V فLaRǓ7`B=: rDiAg[ȒڸC˿)?{q7` bZ׿:p. N4P%=׫S;n뽾̼&2߽m$;>l%3fRrη&mDs\Zl0&s4#CXMcX8@DFZC;:2\1M17l(=KADJ] }?h{~GʧɼEߒ|Y<@?ݬ9bLWroɯИ (l: .PDսabz;$RlCaߣ"K{f5qQ Ը{h;pb-a*MRyR tBf&e_$iuLouܖU*QD`yȚ촴ɠIfatBU #vAQD +bӞ#*z 턳i*H~jtIu񹝨igj>ŴK*5-fT4hwd[=?QZ8g,0~|PXHd0;C7h-9<;*~9޹l3-¨U (f fe4W.KDH4d}T7_t;h,RQ<{ sg՜ cr|멱|;e5|_?xBB La[e WG 6 vOT ž%.Mn+389-ڦ_zo5adϤ?!j0(ޟ⦗-²1zp!V F[YDjE\`4R$uFOvv!qj}O! ;ۡH EZC< ~h'>4S/+r܃6/>IDtE{0t)l𨢺j bCm% Uʥo.o_cS&F_Ⱬi272 W"ra)| ZSq(Uyl %UNF>J^NZuvA~gźB~ҨabfSrT>TSr?7C T+{%_ tT= վ'xZ[%K&q1cs:hVtr<ήX}6]}7~=K\ AAE+s:̪oj^kQUKQS@"R\eĝ$xp!Dv;#YcA^LL Vca7_FQ$w0 /jm#鲪nc0w(p kXO0'饭@u2qQsȬ+Vd` k0?~ȭ?ըB>&33N)dBv8' q9ۀHcޤr 6(HO(.T8\pݞ,GϤCK{yIvgcih#JlY%ɔX3KQHaR:]YO[~ ¦6x-_pu/w+_Ga~MP /^\`*P7pQcR[!6>4}I Oqgf]%5wQ=d[:UDBpDoW"0m(- S( c^XY^~5A=4z*S5K$ }N(v3B~x YDZ:׳X1G#!' E =$ 4Qr{q7 ~4z_EW8 ŧƱf̵^9;~W[ 6[1pAΩ=;fRvh2 hozMw-y!&G3Xθ2k|.Dl&cϏ;BcR:݋HA5 LH@TV '89@* Duy3JU&yN%s[ Cq gn*% ~uiDK~[\󸈂/m=GW˵ea8VRUKy+W@ Zp_gP:-܅Hautp7R![ }nF7:H5SQgu,j25<1B+/w˾LD ~ij4 H^]ZpW\H2 u rDcC H]&I =qo(5ѩ+wJm'ڮF2(2L*<3Xw ;V5( AG%Cz܍7ښȱب0xʼRbC-5Ä S'ZKPCʫ~㡞-[ iay*XDc%XdV!UZ+T. Q(e8T2/ 3NM+$/S%rB=yBCAn]~m+Eˆ0M:f!$H 7wӵlbϠ^pPK}-]7yŒ 7SCoxwϪq[6e'4m{n}U:q! *n^ z&W #F{dt,OS[(YZ#TŖWUq{›UȪRu!fI֚zj*9wyɥ{{LqQs:_C@ :JϩO]jJRw+9;l(ebʈ"'/]6 H#aӗJm?D5}eOcتo3@w|g'Cqs<|ΒWCtto˶{Wƅ+u1H'Z34jH`_>|1yU 4 hPxu+yW r)2B rR ]zo#^刍EOvp_Sm (Q$:qnhGnQy|J869oUKz~4G0wrѩ%5Qô9Rq̅H|j-Jέy˙x NsHB-~emVN@_=μR1 `8_󐃰Cagţq3Ǭrt/x1Z:d79`jto3Hrs\gk ^*Z=conmٝgcVPV~x3$9f^bB%Q85cigLG@n=jkCg!8o)Pb"RVΕX2BT8kmyQ?-!8?޲I0KX3/s;\E=$ ڬ^;+&#I"ò@låZ(%&N36ʬr+t>ejSzτ(tq.'uPl1"&vA`a5m2p-#ԃ:j1qV¦u0 ,AEfXJAQ})yAUxv`=j9v1 HI>nj/ǏkrA^ m%͙=u912gYdO"{!a`*mcKMkABBtC s:<8Dg^Wu'(,~!yvǬGI7|Oc8`ɜS6Vtm[H`Ɔ``Fu&|+Kdv!VjQ_21QrC_nn=fhBU^NtTv;U\%ΪAڶHRxyH_ >`Ty3;[IYW q?C"ax~-+77 aK|/oPGI r%(!$D, JOnLm2R~}(*Z]k]eϗJ\g_%])5DImxԄ)b\,Mfx}~ =SvA% nI1pJBNX\Z,I0E(*C y0$j_}8_A8 8!$PU+cvx V-/[~1n][D㤄(1.@TȮ{eo=쌯Joȩ1-(6wFuj61'm]tC⪷.l_o$_)σL~PA,,GIve('r|:$OSUTq"=_|؉W/ c{ }l%m|$'tA rkT X"@M"Hҳ;\Ybj\qEjǎ"ׯ\hu#.0&gޤB}Y^klўCqJ},nԯlձؼYsϙVjVS-elK>;bza'׳K35n+Q"N&=E` B {3;}C4//̉;ajO 9b/G 9X9&%DA~`2aVGw$w TTC[=uAj}u` "^29qxQb uIɊHK+\_VV9Up8ww4WwNWbDX!@#@@=uhQ^4PEA47yz%w՗:,Ym+.zvHlQph7`Fc%b|T/._uso~fZoGZ\9|ȧ/ g,ijt^=ËYB+C(akk zOбosZ;[QJ_8uC7GZigSSِڿ<0u{i2 PHӀG_d~c] K6^rSEcj5\ W` v-ko99Iy1W(;?{eyu8~kˠT)Wv =rz <*JtZxͳ!'aix,jBikG 7:SR}oPT'a Y}n)^YD9ӿ;6bt"!Pbe1oS#Ͽ5}mK[Kn _: 4(d.2qRlG";|;mىAs؉ ʺnwHk\t X{1:t1m|mo~=Oe\ Tg7ɖReK=% N: {W#);tᖚs4J~P%!Y,rI};b7ƶ)u9:!~{7u|\Tb꧍P/!ѹV(y,yB>s .+1`HoS(4~|k.f{ 2(A㈩)@ 0_Ɲ #+$tBڂ^hƮbSL!qs G>Sǎ3;W}xX1sQA}ȗ A$`4sr֠ti̶X{u$,>?$qE;:)S\qWA(b /#rpQkT9+TZD2Q4.Q{ֵ9/4N*듢BSR?(L>l*;؈/Q3$,=19?݇7eMtZ:i4S+ǭcRޟ6S2HP)<&W~ H&!Sp{Ի/M8t) $Z^ M$&N3Xi8Q76x+:ADX"{ǙId~ djUjO_Z7hgh/34K6exy+f܁tIhV,xL2|8ܽ>bQ_bn<1=nNz73tN/T_(EV) $*_֛ߑ7xW!>d BId!wE}<ȍVzC@ 7w4&ާǶC9cKD+ B$ SᏆAe"\ٜ*R &0L4QH};Q9ۧf5)Ω!gsg1/ "0pXCU<԰ʵIwΪ::Nnq"=t-n_ !G) h ouaz +u!a]UuW𧚺2VXl5|Cx5z8ֵNWW<$G7)؄_V֑ʌ&W^j.G5KaI`z;%!TLj?q ʧ:嶓\;/C^>ip k_kv#* ǃ!jY\B!P\z}|zZTG!u,b@ b<9~jU`{6G? ^{;/ I4_D:C2p揕Dz̴%~&c0(mPqf. D^ lQ,ڬ Â1+r< ].GyeyjZ(Ǥ}F|9 B_}K28  }17BMD(:uHc.w8VvusEW|<T`$mp!O΄R0v3W& n䙥rTu4QRiwpqc6Ƕ9Zo[#?OmzvL_T29}"eoUnuOFY#:nR"P%~(~s-rʧ6_G__})PPU2S``u8*x}a4s~t9miQHTU5L0L,ADtEUOUw~;^%Jw@f=ǘ?"4gQxvf@|<,:AE>c/.^Z L!s6/{ڹVBD_zZ;pPf% ̡S`F18 ~NA݄/~aO]P Tv=aڛKvr?Ϸn 0gtQۭݚAnTF 6͝a40(6*Ha,(}xgW(d)1-({zcosrpvl;)DG؁('[4l˒4o" i]+:q28y'J~Ѱf@}mQ q>z7I/MXxf4N8Dq|zw8 :%@29k2<Զ|nlKSuJ<PBCAWbpTUMa 'C2"Ƿ288D|#|I+d/XSÏ;B|f 2cO ?fwwn-u ;ש5Faԍ'p5Y ); ܹdlETʔ j"8VtߴC4.b+ Tl_ /9ӨP Rپ:W10s[89ߖCu1[_1n{s>rp>I+>v3jDBeaGQ_wj ,1WcJ@`xFnS]& 89)2wwNcǷ \$@‹HØW3ܦ$ z:m}w+ ]_pkH?S[Å+p,@'P6n@ !2qI|;&H드%ۈz˪\]nw|}*Kg|~ԘM;Y~'b8ǴIeq="0(\9 ?Qޤ&M2~`" |En>`fs :s[Yc2O$ ~;jXo;}0["us!!fNkZ.9CY LY GdbB.¬oAEytZ.P+AHfBF'TJJU HlU&[Az(BQJŠ(< pA zUIuHknn7bc|r?&O1'sr03?8K9lqL ^^}l+*Ŧo O8f~8%qEe(xv%h35M8O|<$u\{9ߛTw zᯟn{}8r5A"uj8gls3a1E@h* ׶-ήaze B,suY[Mt~kVaޏtzbiGa绋S <s4A l2.)WYN( 0TTJ)[yu}m7u[ޯbQAdv}Hc¶U GɋΣ>X"N);CE]ZŠYpSjlBG}vV]/*K>9plckz E-WcEM򾡟 QXOzvW7#ᚺ3chF43| _e~es+)j(%_i4g1@~^<9*,m&$ֵq(5O)q\gEk8<#$vD{krxKgKlJÑ,QAE&Q*|o%6FAU\AR9:w2%(~L0r$IϴH >Թg-vU}IZ$djmXc u'" tzΛ85-P@LaupY&@6i3ax><@9HӒQݝ EiLTE` DQHxm HwdE4yj)@L7V `MfG?_]'?HuA2Evs([dy hE5!{:gfRs-; 7^['t#EO@.XTgK9x}[csKD}/k~,1dKyW[l!sZj>W63!7XT,.26fL/]`y󇙜:RU0$g+U.CyG2+)J$Lae8zUGb ^μRtC7龢:,K[br0BdWH'A%˥Lj8xx~g~D1~y)GT?gr9͙G<`]%8|o4k!J3*+pHvEhR<7(=fYb&Vֱp#C۴_YSj$ 0_slW>5S-ߚ~U[r*;0"@WqvR{FiEξj,^}\_- #t_*CvR$j" W[!@^o2WX:d~΂zP@y\=XJ?_/ AjrAGDga~y]'Y(wгZ@ˍm/96uKaש^,1| ]~[2T‡FܫK'c{w{P1?$1549EϤ4~G k{Ü>RH{73uWn7$`)3,\[̭6 =&w+$0kXR~f+qgkc^7Ç7kdE! Wᡠʅ]҈ywp( [NuϛV,.JM4LԳLndZ+ޣ9Xx5@/;μUV( `X;FŠ8W{< Sv7aH#ppIHpv\O5+*@w[:cpKz*#5\ˍҴ({?d zYg҄rۨ[J(O?Rj::&yjŕ2ԢDQ {t36Qq kɌ$ґ=ܔ׬3]dmtv7 q+nd1Dǝ\.,oAԎ/㓢&0#aUoc ^+9$=\?$)Ϊuk] _蚨"q>f*dGӇpZ nф{Mv8&O/.`!({Z7 [n1AeJGƐa|#(@^׍.81UHYL0Q}vba%vJp_b^zLXW: V/sXVp5c\ "§t]B/>Q7iXSa>qomVgۣKXA( #j\8}iRkӶ&ć-=E63q 8‚صP8"\|7VbHak5^|/ƹ0HPa$O':i^Ne ^RfsK+g]%7r}%~O=A:g4uV=&We5Nr\qM]j 1?pj=|H~GXa#YT IFߪ7Z'UEJ$$.g3LqyqզQ4. &SaVPXe5*$Iwvџ[JTx汨$DU0@lJ?0j4uxzdc1z 󎟣`ӄ<%23$3P"͛hɲ"HiD,o/↢ֳ~wja1w|m 9Ȁ! Nnk$q9?79âGIh}f7•.My2>]ux $$=c.E#Ruf| qL?tFte/$`”G  CwdK5ɷeH*H$ؠ.\EKpV(.EtAxԐp LM`S:AG'L!|e9|BM";C5XӲN& A˜us'sȠjm[ 1k\=-L [ri0pw9&K2X+pB5r*l_C+1PY%xX $sğ1d(7 Ls82mMB$,/e,!!D!O0´TqX93!88ؖDj,2Q.#rO:moWo}\>9%%EpjT@,rɌﻹB2@H}̙""T < EO9oZ<q'#4M\18ADb QS.Ug- w0N12}۶ w qT1+pI` =lY+W3KA֮;o]XU\bB\䊠w] 7Cyma9(Ra>.y{<1Pk6q5Xf5P P0z KUL,"&Gؘ0=V9D8dV`G$9?/[f spـe܇pbIvaw?^!t#O$(jfT!ȗ_ƯSIH3B< U%>\5~y7\1_O<ק2m1 џeh%vJ[NMr%=}Ԑ|vuESu9[̸ _;]dlT0rFy o.߯[ݤP -HGe x@2PTȡN-8.yq8$N`{>ByMpL ~>c_Ƚk#!D ,Q UF2g"a7QGP8h>cyya1yA 5 Wg ? l/=ko't5j=r ]3`bR+6MoԨ`+dM|{qy~~09"s/ O=*x2C$-Ώ,0oQA0$Ukb[yXQ>#ҽN]nof^}WM{e iLZ* SOfZ9zx{g|}%9#~y;keP tYAmanQ7 U_uyu `:H8&u@֚rd8?k s_?L}8PÎHGgb yq.k=nnU &,>iQ7a.bA|(OzX49 BO/\ sP3 OOAt镭Z>Q a-Kk6y=:bf 37kLx|_Ǹwb6OҶ_Ox\3Kb\}s4DxAo7d '9d=dGg=|-@=yMg7@5rXC"x 8^c^%(N!,`)~H%7v],yȇo m w*z94PEB,D7tC@7X""p0ݭCL~Rp<} ^c#ZǶK X!ztÈKZȏ'0SHY$|BJԵl:ȀHn*\Shy*t) ]9j8‘ѿ=BȭA R\ej4r,Lg[ x<\R@XQnz_gM԰X^Š׊R_ $"<.3na`bxE |KAe^sHiڭȗ>  uH=;~ bK4Z_˱޾@;\+1܄-Y#1]'ҏぐtȧL!8 1:Xƿ"(f+r{]K@"rD=5-_ⵢ7:V$mg[պ)!0F̱,}xÈ;cѩƭb?ai,P9*YSH4FFd-t'-tvJ}4͑+=4 2R/)i "kF DvolS2>ʾ0$N䂟S sêq` "CL7obn/DW<)]ٔ!$Qf/<^IOgn`Go Ф Ry,ޗyrZGs_o _'?B3ipy COk8A+gּ]_2*lȼ@/s)zH:RJF64{We !UE̤{{*,m~Ck9Ylhg3}|.06^OLZNJ2V}XǑ«#x"+(n`dhےb(RA}KtU{b9}>`acW^d]֚᱆Ezɐk Ev'2B3f l'hM uIa7Ӱu; zTz$ܓ73; H#Rs1Ӗ@1\W_^ S 2|B9 _ظ[- =@a1犄@\k+o"N;[ȟ b=QCVFY˜!Nʔg_pL.D0?"ڠtӣN:$G (&mXs4kd,͝ <` ا(#H6YB7[uA~p3O5#q/ Q8n/gSKjN87 ǟ\'KtHMPjGe:I 0r0e!gNjQ늎+䟄(xLɛ.e0n!Q{)(@=֥+ZWjcA*@g)0]z#He䇀ñ36__PS(&wJ.j| <] a*J /l[}q㣅KU᲌]Y^5ʨEDAHYopm,LgH1,9YT/r0@Qs_(N#n~ȟɇܧyW6_|לq5YYƵXr=eBHMx`DKH{B:Yߡ."32yAXXR=0dĸ(3XJ ?l[5kpM#.kޙ0n>(|j_髜] Ik_rnq>L(eMoɻ;խ_Ѿ́ƿpH'z nJG2H .71By-\ Vq'@~3,[-ˣB%R+gStE s#;-[-|a˴UemhArH9.?B5J&?=^<ǕEV+ oR%耴ٵBzȟ+2z1~KAqL8l@X%-5[\2S>oVS/AUD}(N׏S[DbaMz|V/Wzr,':zt+CvIɣ6Nf 2 dPqU݋\ewܢ?n+«y2g 2-2NlBY:0tGjH_mu?YO5{^>QT哹!- Mb[ʇ7p+i6,gެs ]j`t !6qWxsm{d8 89>28P,uL>!G!o߹,k\gZhOv0W8qF#8HL2CJҼcS;4Aod#PPryাx01h86;69^Pwo]ö-H%YT8A/o;g+{(/L:(<>ӎ l}ÊT G#pPD3ҍ;SU #|o4#gonhpHKץ ױl" -F%x8_[;X&WQ;qIƪd5Z7J|>q[g>Da7w!yTT{uȬ;R N (aSE5T;+ )cSM[㑍fi֐F'bjImj̵ 1#fofY. }<.s"y5Fo/$A}VBr35]C"+=;ghب^U - XX=u]sw:q=Ig\s"(`?úd>DvaQB4\χxm)NFxqybtOqypBmܦYuzGuSCa+PG/~.x74'=ոC͈q|oz*~d,I/?h$KZ7zr}/~"N$gE5wqvqc0́0Y8z\\7&,urozXqμ>Hg|;.i@DZp7!,`ZY;x̺>CcL9T kO`ݠ*n9eK⵨|!|؃:xg:O'6QMӖ-sI}X:PotbQ|\! p_;+_C9+| ծ:^X6n()3G~^TFoOt/\D߁ ȠTH-x/ 9'n`ǚ[UrCg(1fluGesKαASgqU^8OX_Z}( Ba>7 \̙~ uYֹ}3Q!,ED#%ZU40YWėٳB (r/=!D/K~lo﫽GFk{v9yW699t5Xr8厴Ʋ5d&SUdcs9)X uykoƙW fY.zqe -};b97X|+@Ļj'sӾX v%/C8 հN0۪q5\ǀ|KsY"l7]pV.#e9mhg}DGˎ=>v"I#9]ހpUĀ06Td񳺿sɽVSs̸`#!zg/{>79@s pc(D=&%e;ÿ\^1y5Zw=x\f[s[9o78)^'9ա;rv3 OCq)h>ޯ1X<)D?2\r=# Ϝa5\s2|7MM+)x!(|`a|' |ЭKK{tw:qp3ƷT]n-z} YiPzrvxkRl4|ƛ)IكAE+vEYc&^o9~aSjqOSo+1;#oSrij~0Y | 1 V`#TGD[>_1\ x^Yya>[qP Ǧyƨ{dwFpa}3Π:!V9 fq۸asGOuqQB^{)~>ɽ@e4aexq繧8߭l5-~]x8zi)O7>_ Gso׊,z C6&Mhxw83vI}^ |ߙwB3i+OsjzF׺b''P)菟/4_0EoI'9qru{"wQ99c*:s!g{y0FVrqp;qMmQ%K qsEѺ7G WO1dCiba? @D}Ӌ- 7A EG^}NᜋwtbIV`Bü~oS*uo^v7~l@dYfjd8p0\)hTXVAál!HhXgi'U鹘 ڬlwtJCjc"p1Y- X6AzL7zKM$8ùNhzSIJODcMVF|za6$piq|VKSbAWӅ";C"8Kd)r,#0JP ]TU܈k"Q#fT{,"T O9r r\s؝KY +Q6CyڈWFĭLsQs^?JMq578q#.XsǴs.ưlu/+0k[3~xD  }rHp\ۘ9 +YBI{Y]0Mp>o:vwqg  i:qFR̰r_94!_1N߫_Htw闑lKwShZH_&12=ZQc+ >-P,Z׊[}"zFl geU¾5I9d˩VhK{DRGO'yGO Bce#IC0%]Čp/.y[}89 LPp?ՅE{@DG6Wd5j\-֪jHvk2 k|:g0(zs'&I`Qy 5>nxS.D`os}N7G~OEIƑeZ/\Hk0CYSQxT+l3wW? Ӝ WN 5em<|/KɽWk." ?<؁X1PKQLp k~qJ `8/Rf,ӼМ/kR CW7 @t. eVSDbә0ňiڻ,D,}$'K奈)O-%!c%KLZ}c,Kc/3LnIQof$^ݕ|Luj5gr]̡gZmIfE롇{w;,@MI~ƷDGJV ` a5/FS$W&pi[JgJfDZ6n:媥L}Z>,üWZMflUR @3r-qKN>7|\ERU _Vbqg87r ?+"KE/H߮~W}+hQ[S59Lݸf gc41mN;vg6 fP!~ .sf G150<8Jj`a5,"N9F3 ۯuӶ?]]ERŀkSR{i^w:\1t߇:H*۹G3/65}JKqұU""'rjLhH=?YN*OOw- UzNⰆoQU$hQ[qsS[XI4\h# K+3`e8q= N0g_GX͙q,m|NJХmJ!+㥟hu55Vm(/9ȩETO,]XiuL8X`Dł&$O6hJG(p6(-h.e`o(YR(oOڡňztO|49z^7Z/ƔH7M)L(Ê nlHXй"a]s:EN T,7_t/鋧 0]2yP&)ZKyڦ`$(}9Fa 0s/p2Ð_#N"|\vɽH[>()šBz{Yd&tL挐B rQkaY%GAMokj̣.LFzTEl.ʹ}x2}}kSUA# OP[n bk}fs]x=GLv( 0I\և]Ll@4:3ȭRO`H{CBh-)AßcU+7Yj ĻHt+[R*CXꪗ)Xpƶ[ِjW&MTAêR6vA< GwA|Dvqf7ҲAH(R+,xf H!V¢=3V@D# F,%=`ըt69>FPxb5/\ ԻI< .]~8,7ȇ= ("]vvGu5u$)Zb܆C;K'6raah1-ɇ?BhR=q|eiUH~4x"i}J~evkHj{|/HDYF|c0s `p 4 f:63Qj:"K9 4~P}p#{)sE>1!e&J~q32+)Y}f=эu,Sۜ]vծ3Dڷ4SqήCDiڡv4 (ծQ>oJZ=ҍP9^`cģGv>vPEY+Xz79+`#3ȟ0/~|EH6~3^+0H## אʱXW[)E|bэwu?54@C"@Rvƃ'/8XH;g y$xkvxL7)eb:>̢ߊW`u<%8Tu@P^I?pg Vg۸SSF,w[vdUAF|ѭs+pP:Ӵ9M?X旘m7#C%s[*#} R-w4!}^5SF]ҋ|so!\|kv EAV{#DM^º,3|dZ ,RG}ܭgxǒ&Pn:t$;/=M lcQ^Hvͽd1>7\C'<,Y .,g",S &-x0[ے3KWWGtPڊPr&VC!B@@J G% ,w ^]|?Hng*wQl3iW{;W[JN_R_P $h$|zkFzz5^00tP!96ܮ` }cӁZ 8͑pM`D}BF%f#ߺpwdJQup/'}ZXԌ _G_7ehF8 ցG,=s G\Ҵ>™O&k??I__>A3:}j_X`) +{{~oo OP6U6 h;< >z|z%V#RκB8BLJ*Ss81I/*F<ύ)oζ5 _{ܱ=k} ] vB# _펯PsVGU]W kHq=Eڧ{o9d5a=y~ز >?/-*CGBrvU}Yko z_Zh,0z~` ͈ Hxg9Kv;~?WP{ÿj3ag=(}AnAٗcKꕋI*kFJ FY2kK25m0q!ȥA#j}Ȍ0n,{ !̀t0fkу d D֤- 0=-900P4tCw[cdȠ)76It`6#dO"8%ӟF Gp;AE"DY7_+Pp=!~;>!N<.!n$L0?i(օYX=cLCG׳_|CAB= ӬIz?#F)_-sp/`"T6)_7Uۗ?$}Ӕ u;n<]*c7D;uR *iPek_͠OǏ;t`k Us gRtj^|&×dÒ_ʩgZPeho5{Lg<ķ~'>}\eZ{\J|{C#RDwӳjO12C+t\F/Xr?fʃdW ^Gu^z÷k(ف <΃j# 3>>OH9 _?\rǪ8L~gv?߇n)y 䩑zI7t^G LɥQ$zڰw.\ȩ>w^햏8Yz}s~gCw gucg %V+?;& }2K.um]SYGW} F!\1x, ^.mkWzS@g٩ ›h 4cy7b˨ykwv4oʶ-"rV{0w~MUQr .}K< RA8:q_ѿzX RˌHq~^^5p}c?fE$2yuڱPǴ5u"sMFf~:x|P;  J~_Bq`8=bk#Jcf`G)HXb$U썞'{kOf.F[O%坵dis̨MUU٤+OFVnuhD=2zU$z]qy~. pq?u+:( LPl-C<8ɣA;QSGye{ѡFQk`er1P FahHJ %E,A㒗 67TK{ |hUӻiK6;9_>_e",xY[64 !XeF־` ρH" Г۷7Fs|KF,2]{ϾUE03>K3p 5ﻇwo 7hbGbL3Gkׯw#;cXsBfpZVNw#ouYYTq=s;m-_hӦtA*ADžy<'/16.Z.H>x̢nauT[㝚%ُ G% 1w/{?Ħѵrp$Tl9>R{1Up6iqb34Qw g2*,qE>㭯5ٯ)4;;Юv>6ٮDS~0Ք }jVߋN7G]K">m:<>kp`ԝWx8QrqPAϏLW[l9:&Jnv.%DjfE\{zC _%aKSS{Qʵ{xAL90{/pc.}֚&ȑrXdxUPtIDA+|$͜î)4/a,FNip6NT{Eɝ|+2}8Ht+GGj[qn3͊$OYNjSj=( :?G'[,"QӑfpA@Z7«J0 0p\q XI,x j%=P[rǹ}ӫ|.4HER$dU5gPheL!/PAK=|Dj7ݩѵ,\h[!~rǷ-,/D (W 5 g5M5`(M3i_{ުOLֺljVup" Q 8#7]a9 -^<`EFBapO3D LdL 9CE)oK-(,|X4YCI#p f 7@K jDz۽g+pO$-QSFؼ[F7f%]s^U_= 3Zᖏ8AoCo#ɕ,þ 0^n~$2^v*>-RzQjm<|RzpUVP9K?& ĽE}C|nAz,qjXaE-e ڙjF0[$P戥N=mXaLdL|:?F#`PF]2R,xO8 NZ'N#8q;gO4lNs$?/uxāCxLL(1Ώms؂2DlcG$;+ojxɇ *-4 LwQ?_sF_dO"}8\]"Q t<]c1ɑJ_c@} ?DX1-t: &!FfO(& 6Ag}6(+p ?d2%N0(vd4Z|#6Tp\e#{g#ovQ)v zw uƸAcA$4r&5z'miKB"s/U%8.ty@==k?>y g})I>t1dQx=g{CbHrOrW̉HțX=}zzw_Z@cͿd`/OLJDW]^M4(ٳ>C- hg{p8|MO\]uMHGŒc*3ayk'?|A+s^NnTX"qlEc PTٰYk~SgʾBm nAghV$) s1j$<.o&5dLh-A%@r|j6HDi:SII!Y6 `×W`67m&]|هҍ*:S,DDjDD-NϜRorԴuq<|s$^e3/_/ 1@^.o,0"Ipέ2w:)p 7ha$h,c*µ"z oּEn Ĩij'$Z-^0ѢڮLu `8!t,@ֈCƱմW3c΃x8'o\@