!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/arch/arm/mm/   drwxr-xr-x
Free 318.29 GB of 458.09 GB (69.48%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     small_page.c (5.03 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 *  linux/arch/arm/mm/small_page.c
 *
 *  Copyright (C) 1996  Russell King
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 *  Changelog:
 *   26/01/1996    RMK    Cleaned up various areas to make little more generic
 *   07/02/1999    RMK    Support added for 16K and 32K page sizes
 *            containing 8K blocks
 */
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/smp.h>

#include <asm/bitops.h>
#include <asm/pgtable.h>

#define PEDANTIC

/*
 * Requirement:
 *  We need to be able to allocate naturally aligned memory of finer
 *  granularity than the page size.  This is typically used for the
 *  second level page tables on 32-bit ARMs.
 *
 * Theory:
 *  We "misuse" the Linux memory management system.  We use alloc_page
 *  to allocate a page and then mark it as reserved.  The Linux memory
 *  management system will then ignore the "offset", "next_hash" and
 *  "pprev_hash" entries in the mem_map for this page.
 *
 *  We then use a bitstring in the "offset" field to mark which segments
 *  of the page are in use, and manipulate this as required during the
 *  allocation and freeing of these small pages.
 *
 *  We also maintain a queue of pages being used for this purpose using
 *  the "next_hash" and "pprev_hash" entries of mem_map;
 */

struct order {
    struct page *queue;
    unsigned int mask;        /* (1 << shift) - 1        */
    unsigned int shift;        /* (1 << shift) size of page    */
    unsigned int block_mask;    /* nr_blocks - 1        */
    unsigned int all_used;        /* (1 << nr_blocks) - 1        */
};


static struct order orders[] = {
#if PAGE_SIZE == 4096
    { NULL, 2047, 11,  1, 0x00000003 }
#elif PAGE_SIZE == 32768
    { NULL, 2047, 11, 15, 0x0000ffff },
    { NULL, 8191, 13,  3, 0x0000000f }
#else
#error unsupported page size
#endif
};

#define USED_MAP(pg)            ((pg)->index)
#define TEST_AND_CLEAR_USED(pg,off)    (test_and_clear_bit(off, &USED_MAP(pg)))
#define SET_USED(pg,off)        (set_bit(off, &USED_MAP(pg)))

static spinlock_t small_page_lock = SPIN_LOCK_UNLOCKED;

static void add_page_to_queue(struct page *page, struct page **p)
{
#ifdef PEDANTIC
    if (page->pprev_hash)
        PAGE_BUG(page);
#endif
    page->next_hash = *p;
    if (*p)
        (*p)->pprev_hash = &page->next_hash;
    *p = page;
    page->pprev_hash = p;
}

static void remove_page_from_queue(struct page *page)
{
    if (page->pprev_hash) {
        if (page->next_hash)
            page->next_hash->pprev_hash = page->pprev_hash;
        *page->pprev_hash = page->next_hash;
        page->pprev_hash = NULL;
    }
}

static unsigned long __get_small_page(int priority, struct order *order)
{
    unsigned long flags;
    struct page *page;
    int offset;

    if (!order->queue)
        goto need_new_page;

    spin_lock_irqsave(&small_page_lock, flags);
    page = order->queue;
again:
#ifdef PEDANTIC
    if (USED_MAP(page) & ~order->all_used)
        PAGE_BUG(page);
#endif
    offset = ffz(USED_MAP(page));
    SET_USED(page, offset);
    if (USED_MAP(page) == order->all_used)
        remove_page_from_queue(page);
    spin_unlock_irqrestore(&small_page_lock, flags);

    return (unsigned long) page_address(page) + (offset << order->shift);

need_new_page:
    page = alloc_page(priority);

    spin_lock_irqsave(&small_page_lock, flags);
    if (!order->queue) {
        if (!page)
            goto no_page;
        SetPageReserved(page);
        USED_MAP(page) = 0;
        cli();
        add_page_to_queue(page, &order->queue);
    } else {
        __free_page(page);
        cli();
        page = order->queue;
    }
    goto again;

no_page:
    spin_unlock_irqrestore(&small_page_lock, flags);
    return 0;
}

static void __free_small_page(unsigned long spage, struct order *order)
{
    unsigned long flags;
    struct page *page;

    page = virt_to_page(spage);
    if (VALID_PAGE(page)) {

        /*
         * The container-page must be marked Reserved
         */
        if (!PageReserved(page) || spage & order->mask)
            goto non_small;

#ifdef PEDANTIC
        if (USED_MAP(page) & ~order->all_used)
            PAGE_BUG(page);
#endif

        spage = spage >> order->shift;
        spage &= order->block_mask;

        /*
         * the following must be atomic wrt get_page
         */
        spin_lock_irqsave(&small_page_lock, flags);

        if (USED_MAP(page) == order->all_used)
            add_page_to_queue(page, &order->queue);

        if (!TEST_AND_CLEAR_USED(page, spage))
            goto already_free;

        if (USED_MAP(page) == 0)
            goto free_page;

        spin_unlock_irqrestore(&small_page_lock, flags);
    }
    return;

free_page:
    /*
     * unlink the page from the small page queue and free it
     */
    remove_page_from_queue(page);
    spin_unlock_irqrestore(&small_page_lock, flags);
    ClearPageReserved(page);
    __free_page(page);
    return;

non_small:
    printk("Trying to free non-small page from %p\n", __builtin_return_address(0));
    return;
already_free:
    printk("Trying to free free small page from %p\n", __builtin_return_address(0));
}

unsigned long get_page_8k(int priority)
{
    return __get_small_page(priority, orders+1);
}

void free_page_8k(unsigned long spage)
{
    __free_small_page(spage, orders+1);
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0048 ]--