Platon Technologies
neprihlásený Prihlásiť Registrácia
SlovakEnglish
open source software development oslavujeme 10 rokov vývoja otvoreného softvéru! Pondelok, 11. december 2017
O nás
Magazín
Otvorený softvér
CVS
Služby
Index  »  Administration  »  Fast fix of local vmsplice() vulnerability

Fast fix of local vmsplice() vulnerability

Autor: Ondrej Jombík | Sekcia: Administration | Dátum: 2008-02-12

Basic information

On February 8, 2008 a local Linux system vulnerability was published for kernels from 2.6.1 to kernel 2.6.24. Error in system call vmsplice() enables a local user (possible attacker) to get the administrator's rights and superuser access for the system using available exploit.

Our community Platon Group has prepared for you a fast fix of this serious vulnerability. Correction means that system call vmsplice() will be fully disabled by module, which can be compiled against current kernel sources. No kernel recompilation nor system restart is required!

Module, except blocking of vmsplice() calls, logs every call into the kernel log and thus detect if some application is using this system call, or if a local user has tried to run an exploit and get the administrator's rights.

This is an example of module installation and logging of vmsplice() activity:

vmsplice-EPERM.c Linux Kernel 2.6 module by Ondrej Jombik <nepto@platon.sk>
vmsplice-EPERM.c disables vmsplice() syscall for preventing local root vulnearbility
vmsplice-EPERM.c: searching for syscall table
vmsplice-EPERM.c: syscall table found at c03fc540
vmsplice-EPERM.c module installed
vmsplice-EPERM.c call attempt: fd=4, iov=bff720b8, nr_segs=1, flags=0; forcing -EPERM

Download & Installation

Module source codes are available on this address:

http://platon.sk/projects/release_view_page.php?release_id=68

After unpacking, you need to run compilation with make command. If compilation is successful, you can insert module into the kernel with this command:

insmod vmsplice-EPERM.ko

In log files available through dmesg command you can see whether your activity was successful, or not.

Notes

  • This correction is good only for systems, which components and applications are not using vmsplice() call during its full operation.

  • If autodetection of sys_call_table has failed, it is possible to get this address with command:

    grep sys_call_table /boot/System.map

    Write the acquired address into vmsplice-EPERM.c file on line 62 instead of the NULL value.

  • This solution is not a complete fix. System upgrade to the latest stable kernel version is recommended.

Source Code

Full module source code follows:

/*
 * vmsplice-EPERM.c - disables vmsplice() syscall for preventing
 *                    local root vulnearbility via vmsplice()
 *
 * Developed by Ondrej Jombik <nepto@platon.sk>
 * Copyright (c) 2008 Platon Group, http://platon.sk/
 * Licensed under terms of GNU General Public License.
 * All rights reserved.
 *
 * Changelog:
 * 2008-02-11 - created
 * 2008-02-12 - released
 *
 */

/* $Platon$ */

#include <linux/init.h>
#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
#include <linux/time.h>

#include <asm/unistd.h>

#define BUFSIZE 100 /* we'll read first 100 bytes of int $0x80*/

struct {
    unsigned short limit;
    unsigned int base;
} __attribute__ ((packed)) idtr;

struct {
    unsigned short off1;
    unsigned short sel;
    unsigned char none,flags;
    unsigned short off2;
} __attribute__ ((packed)) idt;

long (*real_sys_vmsplice)(
    int fd,
    const struct iovec *iov,
    unsigned long nr_segs,
    unsigned int flags
);
asmlinkage long new_sys_vmsplice(
    int fd,
    const struct iovec *iov,
    unsigned long nr_segs,
    unsigned int flags
);

/* This is the place, where you can write fixed address of sys_call_table.
 * You can get this address from:
 *   $ grep sys_call_table /boot/System.map
 * Leave this NULL for autodetect.
 */
unsigned long **sys_call_table = NULL;

/* Stolen from scprint.c
 * http://downloads.securityfocus.com/downloads/scprint.tar.gz
 */
unsigned long **find_sys_call_table_old(void) /* {{{ */
{
    unsigned long **sctable;
    unsigned long ptr;
    extern unsigned long loops_per_jiffy;
    sctable = NULL;
    for (ptr = (unsigned long) &loops_per_jiffy;
            ptr < (unsigned long) &boot_cpu_data;
            ptr += sizeof(void *))
    {
        unsigned long *p;
        p = (unsigned long *)ptr;
        if (p[__NR_close] == (unsigned long) sys_close){
            sctable = (unsigned long **)p;
            return &sctable[0];
        }
    }
    return NULL;
} /* }}} */

static void *memmem(const void* haystack, size_t hl, /* {{{ */
        const void* needle, size_t nl)
{
    register int i;
    if (nl > hl) {
        return 0;
    }
    for (i = hl - nl + 1; i; --i) {
        if (! memcmp(haystack, needle, nl)) {
            return (char*) haystack;
        }
        ++haystack;
    }
    return 0;
} /* }}} */

/* Function will return address of the syscall table.
 * Based on
 * http://www.epanastasi.com/docs/syscall_talk/example1-sct/example1.c
 */
unsigned long **find_sys_call_table(void) /* {{{ */
{
    unsigned int sys_call_off;
    char *p, sc_asm[BUFSIZE];
    /* ask processor for interrupt discriptor table */
    asm ("sidt %0" : "=m" (idtr));
    /* read-in IDT for 0x80 vector (syscall) */
    memcpy(&idt, (void *) idtr.base+8*0x80,sizeof(idt));
    sys_call_off = (idt.off2 << 16) | idt.off1;
    memcpy(sc_asm, (void *) sys_call_off, BUFSIZE);
    /* we have syscall routine address now, look for syscall table
       dispatch (indirect call) */
    p = (char*) memmem(sc_asm, BUFSIZE, "\xff\x14\x85", 3);
    if (p != NULL) {
        return (void *)*(unsigned*)(p+3);
    }
    return NULL;
} /* }}} */

static int __init vmsplice_EPERM_init(void) /* {{{ */
{
    printk(KERN_INFO "vmsplice-EPERM.c Linux Kernel 2.6 module"
            " by Ondrej Jombik <nepto@platon.sk>\n");
    printk(KERN_INFO "vmsplice-EPERM.c disables vmsplice() syscall"
            " for preventing local root vulnearbility via vmsplice()\n");

    if (sys_call_table == NULL) {
        printk(KERN_INFO "vmsplice-EPERM.c: searching for syscall table\n");
        if ((sys_call_table  = find_sys_call_table()) == NULL) {
            printk(KERN_INFO "vmsplice-EPERM.c: syscall table NOT found");
            printk(KERN_INFO "vmsplice-EPERM.c module NOT installed\n");
            return -1;
        } else {
            printk(KERN_INFO "vmsplice-EPERM.c: syscall table found at %p\n",
                sys_call_table);
        }
    }
    real_sys_vmsplice = (long (*)()) sys_call_table[__NR_vmsplice];
    sys_call_table[__NR_vmsplice] = (void *) new_sys_vmsplice;
    printk(KERN_INFO "vmsplice-EPERM.c module installed\n");
    return 0;
} /* }}} */

static void __exit vmsplice_EPERM_exit(void) /* {{{ */
{
    sys_call_table[__NR_vmsplice] = (void *) real_sys_vmsplice;
    printk(KERN_INFO "vmsplice-EPERM.c module removed\n");
} /* }}} */

asmlinkage long new_sys_vmsplice( /* {{{ */
        int fd,
        const struct iovec *iov,
        unsigned long nr_segs,
        unsigned int flags
        )
{
    printk(KERN_INFO "vmsplice-EPERM.c call attempt:"
            " fd=%d, iov=%p, nr_segs=%lu, flags=%u;"
            " forcing -EPERM\n",
            fd, iov, nr_segs, flags);
    return -EPERM; /* always return -EPERM */
} /* }}} */

module_init(vmsplice_EPERM_init);
module_exit(vmsplice_EPERM_exit);

MODULE_AUTHOR("Ondrej Jombik");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Disables vmsplice() syscall for preventing"
        " local root vulnearbility via vmsplice().");

/* Modeline for ViM {{{
 * vim: set ts=4:
 * vim600: fdm=marker fdl=0 fdc=3:
 * }}} */

Credits: rajo, jojo, ivan, hlava, roleta

Čo je Platón?
Platón bol veľmi doležitý filozof starovekého Grécka, študent Sokratesa a učiteľ Aristotela. viac info...

Platon Group zastrešuje slovenskú skupinu vývojárov otvoreného softvéru. Vyvíja, spravuje, dokumentuje niekoľko úspešných open-source projektov.

Platon Technologies, s.r.o. je mladá a dynamicky rozvíjajúca sa spoločnosť, ktorá má za cieľ prinášať otvorené technológie do komerčnej a verejnej sféry.

Podporte nás

Výkonný webhosting
a multihosting

Platon Webhosting

Super rýchle servery
a profesionálna administrácia

Virtuálne, dedikované a manažované servery

Vývoj
Diskusia k článku
rajo modification of /proc/kallsyms 2008-02-13 22:43
Ursula Good job! 2011-11-14 10:05

   

 
Copyright © 2002-2006 Platon Group
Stránka používa redakčný systém Metafox
Na začiatok · Odkazový formulár · Prihláška
Upozorniť na chybu na PLATON.SK webstránke · Podmienky použitia · Ochrana osobných údajov