C-Mlock

 view release on metacpan or  search on metacpan

Mlock.c  view on Meta::CPAN

			"pAddressRegion", "C::Mlock")
;

	RETVAL = unlockall(pAddressRegion);
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_C__Mlock_is_locked); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_C__Mlock_is_locked)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "pAddressRegion");
    {
	C__Mlock	pAddressRegion;
	int	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "C::Mlock")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    pAddressRegion = INT2PTR(C__Mlock,tmp);
	}
	else
	    Perl_croak(aTHX_ "%s: %s is not of type %s",
			"C::Mlock::is_locked",
			"pAddressRegion", "C::Mlock")
;

	RETVAL = is_locked(pAddressRegion);
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_C__Mlock_process_locked); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_C__Mlock_process_locked)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "pAddressRegion");
    {
	C__Mlock	pAddressRegion;
	int	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "C::Mlock")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    pAddressRegion = INT2PTR(C__Mlock,tmp);
	}
	else
	    Perl_croak(aTHX_ "%s: %s is not of type %s",
			"C::Mlock::process_locked",
			"pAddressRegion", "C::Mlock")
;

	RETVAL = process_locked(pAddressRegion);
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_C__Mlock_initialize); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_C__Mlock_initialize)
{
    dVAR; dXSARGS;

Mlock.c  view on Meta::CPAN

#  endif
#endif

        (void)newXSproto_portable("C::Mlock::new", XS_C__Mlock_new, file, "$;$");
        (void)newXSproto_portable("C::Mlock::DESTROY", XS_C__Mlock_DESTROY, file, "$");
        (void)newXSproto_portable("C::Mlock::dump", XS_C__Mlock_dump, file, "$");
        (void)newXSproto_portable("C::Mlock::get", XS_C__Mlock_get, file, "$");
        (void)newXSproto_portable("C::Mlock::store", XS_C__Mlock_store, file, "$$$");
        (void)newXSproto_portable("C::Mlock::lockall", XS_C__Mlock_lockall, file, "$");
        (void)newXSproto_portable("C::Mlock::unlockall", XS_C__Mlock_unlockall, file, "$");
        (void)newXSproto_portable("C::Mlock::is_locked", XS_C__Mlock_is_locked, file, "$");
        (void)newXSproto_portable("C::Mlock::process_locked", XS_C__Mlock_process_locked, file, "$");
        (void)newXSproto_portable("C::Mlock::initialize", XS_C__Mlock_initialize, file, "$");
        (void)newXSproto_portable("C::Mlock::set_pages", XS_C__Mlock_set_pages, file, "$$");
        (void)newXSproto_portable("C::Mlock::set_size", XS_C__Mlock_set_size, file, "$$");
        (void)newXSproto_portable("C::Mlock::pagesize", XS_C__Mlock_pagesize, file, "$");
#if PERL_VERSION_LE(5, 21, 5)
#  if PERL_VERSION_GE(5, 9, 0)
    if (PL_unitcheckav)
        call_list(PL_scopestack_ix, PL_unitcheckav);
#  endif
    XSRETURN_YES;

Mlock.pm  view on Meta::CPAN


bootstrap C::Mlock $VERSION;


1

__END__

=head1 NAME

C::Mlock - A locked in RAM memory region

=head1 SYNOPSIS

    use C::Mlock;

    $a = new C::Mlock [$nPages];

    print $a->pagesize;

    $bytesAllocated = $a->initialize();

    $bytesAllocated = $a->set_pages($nPages);
    $bytesAllocated = $a->set_size($nBytes);

    print "memory region locked" if $a->is_locked();
    print "process locked in memory" if $a->process_locked();

    $a->store($data, $length);
    print $a->get();

    $a->lockall();
    $a->unlockall();

    $a->dump();

=head1 DESCRIPTION

Mlock.pm  view on Meta::CPAN

immediately relock the memory reserved in the constructor.

=head1 METHODS

=over 4

=item I<$a> = I<new> I<C::Mlock> I<[$nPages]>

Creates and returns a new C<C::Mlock> object.
The optional $nPages specifies the number of pages to be
allocated and locked on return.

=item I<$a>->I<initialize>()

Will allocate the storage and lock it in memory if I<$nPages>
was not specified as part of the contructor.  Returns the
number of bytes available.

=item I<$a>->I<process_locked>()

Will return 1 if the process has been locked in RAM by a
successful mlockall() call.

=item I<$a>->I<is_locked>()

Will return 1 if the allocated memory cannot be paged to swap
(ie is locked in RAM)

=item I<$a>->I<pagesize>()

Will return the page size on this system.

=item I<$a>->I<set_size>(I<$bytes>)

Will set thelocked storage region to be of size I<$bytes>.

If this is called after bytes are written, it will reallocate
the storage to the new size and copy over all the data from
the old memory region before clearing and releasing it.

If the new size is smaller than the data stored, the data 
will be truncated to the new length.

=item I<$a>->I<set_pages>(I<$pages>)

Mlock.pm  view on Meta::CPAN

=item I<$a>->I<get>()

Returns the data as a scalar string.

=item I<$a>->I<lockall>()

Will lock the entire process in RAM, on error will croak.

=item I<$a>->I<unlockall>()

Will unlock the process from RAM (if locked) and immediately
relock the preallocted memory.

=item I<$a>->I<dump>()

Will return a hexdump of the memory allocated.

=back

=head1 WARNINGS

Users on systems may have restrictions on the amount of memory
that may be locked.  This may cause lockall() to fail with 
C<ENOMEM> which is not caught and will cause a fatal error.
Similarly if you attempt to C<set_size> or C<set_pages> and the
combined total of the original and new regions exceed the limit
on the user a fatal error will occur.

unlockall() knows nothing of other mlock() calls except those in
its own constructor, so if you have multiple instances and you
call unlockall() it will unlock the regions in those instances
and they will not be relocked.  It is recommended that you either
rely on lockall()/unlockall() or the internal locked storage but
not both.

When using this module for cryptography you should undef everything
in the same function if possible and overwrite each scalar
immediately to prevent the memory being put back into the pool
unwiped and therefore defeating the whole purpose of locking
the sensitive data in memory.

=head1 BUGS

Various failures in the C libraries are not checked.  Particularly
C<ENOMEM> where there isn't enough system memory to allow the
process or pages to be locked to RAM.  This is particularly noted
on systems such as linux and freebsd which restrict users (non root)
to disallowing the calls either totally or based on the memory
required to complete the lock (Thanks to Slaven Rezic for noting
that a user can only lock 64kB by defaul on debian/jessie machines
by default.)

=head1 AUTHOR

Michelle Sullivan, cpan@sorbs.net

Mlock.xs  view on Meta::CPAN


int
lockall(pAddressRegion)
	C::Mlock pAddressRegion

int
unlockall(pAddressRegion)
	C::Mlock pAddressRegion

int
is_locked(pAddressRegion)
	C::Mlock pAddressRegion

int
process_locked(pAddressRegion)
	C::Mlock pAddressRegion

int
initialize(pAddressRegion)
	C::Mlock pAddressRegion

int
set_pages(pAddressRegion, pages)
	C::Mlock pAddressRegion
	int	 pages

store.c  view on Meta::CPAN

    if (!pAddressRegion->pBytes)
    {
        pAddressRegion->pBytes = (char *) malloc(pAddressRegion->nBytes); /* Allocate it */
        r = (!mlock(pAddressRegion->pBytes, pAddressRegion->nBytes)); /* lock it to memory */
        memset(pAddressRegion->pBytes, 0, pAddressRegion->nBytes); /* clear it, this will stop copy on write as well */
        pAddressRegion->memLocked = r;
    }
    return pAddressRegion->nBytes;
}

int process_locked(AddressRegion *pAddressRegion)
{
    return pAddressRegion->processLocked;
}

int is_locked(AddressRegion *pAddressRegion)
{
    return pAddressRegion->memLocked;
}

int set_pages(AddressRegion *pAddressRegion, int pages)
{
    int ps;
    ps = pagesize(pAddressRegion);
    return set_size(pAddressRegion, (pages * ps * (int)sizeof(char)));
}

store.c  view on Meta::CPAN

    return r;
}

int lockall(AddressRegion *pAddressRegion)
{
    int r = -1;
    if (!pAddressRegion->processLocked)
    {
        r = mlockall(MCL_CURRENT | MCL_FUTURE); /* Lock everything now and future */
        if (!r)
            pAddressRegion->processLocked = 1; /* Record that it's locked if it succeeded */
    }
    return r;
}

store.h  view on Meta::CPAN

extern void           DESTROY        (AddressRegion *pAddressRegion);
extern void           dump           (AddressRegion *pAddressRegion);
extern int            store          (AddressRegion *pAddressRegion, char *data, int len);
extern char          *get            (AddressRegion *pAddressRegion);
extern int            lockall        (AddressRegion *pAddressRegion);
extern int            unlockall      (AddressRegion *pAddressRegion);

extern int            set_pages      (AddressRegion *pAddressRegion, int pages);
extern int            set_size       (AddressRegion *pAddressRegion, int bytes);
extern int            pagesize       (AddressRegion *pAddressRegion);
extern int            is_locked      (AddressRegion *pAddressRegion);
extern int            process_locked (AddressRegion *pAddressRegion);



( run in 0.576 second using v1.01-cache-2.11-cpan-49f99fa48dc )