From nobody@FreeBSD.org  Mon Apr 29 01:11:23 2002
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21])
	by hub.freebsd.org (Postfix) with ESMTP id 84CB637B404
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 29 Apr 2002 01:11:23 -0700 (PDT)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.11.6/8.11.6) id g3T8BNi94570;
	Mon, 29 Apr 2002 01:11:23 -0700 (PDT)
	(envelope-from nobody)
Message-Id: <200204290811.g3T8BNi94570@freefall.freebsd.org>
Date: Mon, 29 Apr 2002 01:11:23 -0700 (PDT)
From: Peter Edwards <pmedwards@eircom.net>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [PATCH] Make ELF shared libraries immutable once loaded (like executables)
X-Send-Pr-Version: www-1.0

>Number:         37554
>Category:       kern
>Synopsis:       [vm] [patch] make ELF shared libraries immutable once loaded (like executables)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 29 01:20:01 PDT 2002
>Closed-Date:    
>Last-Modified:  Sun Nov 04 04:53:18 UTC 2012
>Originator:     Peter Edwards
>Release:        4-STABLE
>Organization:
>Environment:
FreeBSD rocklobster 4.5-STABLE FreeBSD 4.5-STABLE #30: Mon Apr 29 08:00:03 IST 2002     petere@rocklobster:/pub/FreeBSD/work/src/sys/compile/ROCKLOBSTER  i386

>Description:
Before executing a program, the kernel marks the executable file as
immutable by setting the VTEXT flag in its vnode. This makes write
operations return with ETXTBSY when attempted.

However, no such flag is set for shared libraries mapped by rtld.

This patch adds a new fcntl command, F_TXTBSY, which sets the VTEXT flag
in the vnode associated with the file, and gets rtld-elf to make use
of it.

There may be security issues here, allowing user code to set this flag
in contexts it wasn't designed for, but I don't think it allows you do
anything that you couldn't already. You can't stop someone creating a
custom executable in order to get VTEXT set on it anyway, and root can
always kill any processes holding the object in memory to clear the
flag if neccessary.

>How-To-Repeat:
Write a program that depends on a shared library, and overwrite that
library while the program is running. Bad Things happen.

Trying the same on an executable results in the write operation
returning ETXTBSY
>Fix:
Apply the following patch.

begin 644 shlib-textbusy.tar.Z
M26YD97@Z(&QI8F5X96,O<G1L9"UE;&8O<G1L9"YC"CT]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T*4D-3(&9I;&4Z("]P=6(O1G)E94)31"]D979E;&]P;65N="]&
M<F5E0E-$+4-64R]S<F,O;&EB97AE8R]R=&QD+65L9B]R=&QD+F,L=@IR971R
M:65V:6YG(')E=FES:6]N(#$N-#,N,BXQ,`ID:69F("UU("UR,2XT,RXR+C$P
M(')T;&0N8PHM+2T@;&EB97AE8R]R=&QD+65L9B]R=&QD+F,),B!!<'(@,C`P
M,B`R,CHU.#HU."`M,#`P,`DQ+C0S+C(N,3`**RLK(&QI8F5X96,O<G1L9"UE
M;&8O<G1L9"YC"3(Y($%P<B`R,#`R(#`W.C4X.C,P("TP,#`P"D!`("TQ,34R
M+#8@*S$Q-3(L,3,@0$`*(`H@("`@(&EF("AO8FH@/3T@3E5,3"D@>PDO*B!&
M:7)S="!U<V4@;V8@=&AI<R!O8FIE8W0L('-O('=E(&UU<W0@;6%P(&ET(&EN
M("HO"B`)9&)G*")L;V%D:6YG(%PB)7-<(B(L('!A=&@I.PHK"2\J"BL)("H@
M5')Y('1O(&5N<W5R92!T:&4@;V)J96-T(&1O97-N)W0@8VAA;F=E(&]N8V4@
M=V4@<W1A<G0@<F5A9&EN9R!I=`HK"2`J(%A86#H@1F%I;'5R92!O9B!T:&4@
M9F-N=&P@9&]E<R!N;W0@8V]N<W1I='5T92!A;B!E<G)O<BP@8G5T(&QE879E
M<PHK"2`J('1H92!P<F]C97-S(&]P96X@=&\@:&%V:6YG(&ET<R!L:6)R87)I
M97,@<W1O;7!E9"!O;BX**PD@*B\**PEI9B`H;V)J*0HK"2`@("!F8VYT;"AF
M9"P@1E]46%1"4UDL(#$I.PH@"6]B:B`](&UA<%]O8FIE8W0H9F0L('!A=&@L
M("9S8BD["B`)8VQO<V4H9F0I.PH@"6EF("AO8FH@/3T@3E5,3"D@>PI);F1E
M>#H@<WES+VME<FXO:V5R;E]D97-C<FEP+F,*/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]/0I20U,@9FEL93H@+W!U8B]&<F5E0E-$+V1E=F5L;W!M96YT+T9R965"
M4T0M0U93+W-R8R]S>7,O:V5R;B]K97)N7V1E<V-R:7`N8RQV"G)E=')I979I
M;F<@<F5V:7-I;VX@,2XX,2XR+C$P"F1I9F8@+74@+7(Q+C@Q+C(N,3`@:V5R
M;E]D97-C<FEP+F,*+2TM('-Y<R]K97)N+VME<FY?9&5S8W)I<"YC"3$V($9E
M8B`R,#`R(#`Y.C(S.C,W("TP,#`P"3$N.#$N,BXQ,`HK*RL@<WES+VME<FXO
M:V5R;E]D97-C<FEP+F,),CD@07!R(#(P,#(@,#<Z,C@Z,C$@+3`P,#`*0$`@
M+3,V,RPV("LS-C,L,38@0$`*(`D)"0D@("`@*&-A9&1R7W0I*&EN='!T<E]T
M*75A<"T^87)G+"!S:7IE;V8H9FPI*3L*(`D)?0H@"0ER971U<FXH97)R;W(I
M.PHK"BL)8V%S92!&7U185$)363H**PD):68@*&9P+3YF7W1Y<&4@(3T@1%19
M4$5?5DY/1$4I"BL)"0ER971U<FX@*$5"041&*3L**PD)=G`@/2`H<W1R=6-T
M('9N;V1E("HI9G`M/F9?9&%T83L**PD)<VEM<&QE7VQO8VLH)G9P+3YV7VEN
M=&5R;&]C:RD["BL)"79P+3YV7V9L86<@?#T@5E1%6%0["BL)"7-I;7!L95]U
M;FQO8VLH)G9P+3YV7VEN=&5R;&]C:RD["BL)"7)E='5R;B`H,"D["BL*(`ED
M969A=6QT.@H@"0ER971U<FX@*$5)3E9!3"D["B`)?0I);F1E>#H@<WES+W-Y
M<R]F8VYT;"YH"CT]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T*4D-3(&9I;&4Z("]P
M=6(O1G)E94)31"]D979E;&]P;65N="]&<F5E0E-$+4-64R]S<F,O<WES+W-Y
M<R]F8VYT;"YH+'8*<F5T<FEE=FEN9R!R979I<VEO;B`Q+CDN,BXR"F1I9F8@
M+74@+7(Q+CDN,BXR(&9C;G1L+F@*+2TM('-Y<R]S>7,O9F-N=&PN:`DS($IU
M;B`R,#`Q(#`U.C`P.C$P("TP,#`P"3$N.2XR+C(**RLK('-Y<R]S>7,O9F-N
M=&PN:`DR.2!!<'(@,C`P,B`P-SHS,3HR-2`M,#`P,`I`0"`M,3<T+#8@*S$W
M-"PQ,R!`0`H@(V5N9&EF"B`*("\J"BL@*B!&<F5E0E-$(&5X=&5N<VEO;G,*
M*R`J+PHK(VEF;F1E9B!?4$]325A?4T]54D-%"BLC9&5F:6YE"49?5%A40E-9
M"3$P,#`Q"0DO*B!D;VXG="!O=F5R=W)I=&4@=VAI;&4@<W1I;&P@;W!E;B`J
M+PHK(V5N9&EF"BL**R\J"B`@*B!!9'9I<V]R>2!F:6QE('-E9VUE;G0@;&]C
M:VEN9R!D871A('1Y<&4@+0H@("H@:6YF;W)M871I;VX@<&%S<V5D('1O('-Y
2<W1E;2!B>2!U<V5R"B`@*B\*
`
end

>Release-Note:
>Audit-Trail:
From: Peter Edwards <peter.edwards@openet-telecom.com>
To: freebsd-gnats-submit@FreeBSD.org, pmedwards@eircom.net
Cc:  
Subject: Re: kern/37554: [PATCH] Make ELF shared libraries immutable once
 loaded (like executables)
Date: Thu, 13 Jun 2002 20:19:11 +0100

 Hm. This is possibly a nicer way to do it, and certainly a smaller, if more 
 intrusive, patch. It changes the semantics of mmap() somewhat, but I think 
 in a reasonable way, and it avoids all that ugliness in the run-time linker.
 
 Basically, a request for PROT_EXEC on a regular file will cause it to become 
 immutable:
 
 
 --- vm_mmap.c   3 Nov 2001 01:41:10 -0000       1.108.2.5
 +++ vm_mmap.c   13 Jun 2002 19:15:28 -0000
 @@ -406,8 +406,17 @@
 
          error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot,
              flags, handle, pos);
 -       if (error == 0)
 +       if (error == 0) {
                  p->p_retval[0] = (register_t) (addr + pageoff);
 +               /*
 +                * A successful map for a regular file, with execute access:
 +                * mark the vnode immutable.
 +                * XXX: GCC warns, but (handle == 0 || handle == vp)
 +                * I'm not sure of the "correct" way to avoid this.
 +                */
 +               if (handle && vp->v_type == VREG && (prot & PROT_EXEC))
 +                       vp->v_flag |= VTEXT;
 +       }
   done:
          if (fp)
                  fdrop(fp, p);
 
 
 
 Of course, the utility of all this is questionable: I just wanted the 
 functionality for something locally.
 Cheers,
 Peter
 
Responsible-Changed-From-To: freebsd-bugs->jmg 
Responsible-Changed-By: jmg 
Responsible-Changed-When: Mon Sep 15 18:05:46 PDT 2003 
Responsible-Changed-Why:  
I'm going to take this, since I'm interested in it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=37554 
Responsible-Changed-From-To: jmg->freebsd-bugs 
Responsible-Changed-By: eadler 
Responsible-Changed-When: Sun Nov 4 04:53:18 UTC 2012 
Responsible-Changed-Why:  
no progress from jmg since 2003 

http://www.freebsd.org/cgi/query-pr.cgi?pr=37554 
>Unformatted:
