Ruben de Vries
Ruben de Vries

Reputation: 535

PHP extension seg fault when modifying a zval by reference

PHP:

$publickey = pack('H*', "03ca473d3c0cccbf600d1c89fa33b7f6b1f2b4c66f1f11986701f4b6cc4f54c360");  
$pubkeylen = strlen($publickey);  
$result = secp256k1_ec_pubkey_decompress($publickey, $pubkeylen);  

C extension:

PHP_FUNCTION(secp256k1_ec_pubkey_decompress) {
    secp256k1_start(SECP256K1_START_SIGN);

    zval *pubkey, *pubkeylen;
    unsigned char* newpubkey;
    int newpubkeylen;
    int result;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &pubkey, &pubkeylen) == FAILURE) {
        return;
    }

    newpubkey = Z_STRVAL_P(pubkey);
    newpubkeylen = Z_LVAL_P(pubkeylen);
    result = secp256k1_ec_pubkey_decompress(newpubkey, &newpubkeylen);

    if (result == 1) {
        newpubkey[newpubkeylen] = 0U;
        ZVAL_STRINGL(pubkey, newpubkey, newpubkeylen, 0);
        ZVAL_LONG(pubkeylen, newpubkeylen);
    }

    RETURN_LONG(result);
}

the $publickey is decompressed from a 32 byte to a 65 byte string, for w/e reason when we're doing this we get a Segmentation Fault.
I asume we're doing something structurally wrong ... considering this is our first PHP extension.

full code; https://github.com/afk11/secp256k1-php

Upvotes: 1

Views: 110

Answers (1)

SuVeRa
SuVeRa

Reputation: 2904

After looking at your extension code, you haven't linked the actual secp256k1 lib (.so) while building your extension ( #include "secp256k1.h" does not include actual bitcoin/secp256k1 code c library ).

You need to change your config.m4 in any of the following ways

1) Add "-l/path/to/bitcoin/secp256k1/lib" to the "gcc" options.

Help: here, I am talking about once you "make install" on bitcoin/secp256k1, some libraries will be installed to /usr/lib or /usr/lib64 or /usr/lib/secp256k1 etc....

-lsecp256k1

// i.e. something like...
PHP_NEW_EXTENSION(secp256k1, secp256k1.c, $ext_shared,, "-lsecp256k1 -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1")

2) Or, include actual *.c files in from actual secp256k1 library

PHP_NEW_EXTENSION(secp256k1, secp256k1.c ../secp256k1/src/secp256k1.c ../secp256k1/src/others.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)

I would recommend option-1

Upvotes: 1

Related Questions