Add more php sources as possible php versions

Jul 3, 2015
7
0
1
Bulgari
cPanel Access Level
Root Administrator
I have written a patch for php5.4.0 which changes ext/standard/file.c to deny certain types of fopens.
I have root access to a VPS server running WHM/Cpanel.
I need to create a custom build for apache/php with the patched php sources.

I have searched the threads but nothing exactly like this was offered ( or rather I didn't find it). Can anyone offer me assistance on how to create this custom profile?
 
Jul 3, 2015
7
0
1
Bulgari
cPanel Access Level
Root Administrator
I had one idea which was to create a new perl package which could be used to apply the patch.
I'm basing it on
/var/cpanel/perl/easy/Cpanel/Easy/PHP5/4_42/SilenceDeprecatedPatch.pm
My question, in this case is this:
since this module, for example, uses the patch file:
/home/cpeasyapache/src/cppatch/php5-silence-deprecated.patch

applying the patch like this:
my $path = File::Spec->catdir( $self->{'opt_mod_src_dir'}, $pp_ec->{'src_cd2'} );
return $self->apply_patch( '../cppatch/php5-silence-deprecated.patch', $path );

The header of the diff portion of the patch looking like this:
diff --git a/targz/Cpanel/Easy/PHP5/4_24.pm.tar.gz.d/php-5.4.24/Zend/zend_errors.h b/targz/Cpanel/Easy/PHP5/4_24.pm.tar.gz.d/php-5.4.24/Zend/zend_errors.h

Does the patch necessarily have to be in git diff format?

(I'll keep updating this thread as I make progress)
 
Jul 3, 2015
7
0
1
Bulgari
cPanel Access Level
Root Administrator
OK - I discovered, that If I simply replace the file which is patched with the new version in:
/home/cpeasyapache/src/php-*.*.*/*/*.c
where the stars represent the correct values for the path to the patched file, AND
then I build the module using easyapache, the final result is that the source files are replaced ( ignoring the patched file) and the compile goes through as before.

This, for me, means that I have to add a custom patch for each and every php version.

Alternativelly, an easier approach would simply be to add more php versions ( the new ones already being patched).

Any idea on how to do that ?
 
Jul 3, 2015
7
0
1
Bulgari
cPanel Access Level
Root Administrator
*bump* is there anyone out there....?

Here's another update on what I've done so far ( its not working but its progress):
I created two perl modules:
Code:
Cpanel::Easy::pHP5::FopenPatch
Cpanel::Easy::pHP5::4_42::FopenPatch
inside
/var/cpanel/perl/easy/Cpanel/Easy/PHP5/4_42/ and
/var/cpanel/perl/easy/Cpanel/Easy/PHP5/
respectively.

Code:
package Cpanel::Easy::PHP5::FopenPatch;

# cpanel - Cpanel/Easy/PHP5/4_42/FopenPatch.pm
use strict;

our $easyconfig = {
    'name' => 'fopen Writes Deny from Paths Other than wp-admin Patch',
    'note' => 'This patch will deny fopens that are not strict reads from locations not under wp-admin directories',
    'skip' => 0,
    'step' => {
        '0' => {
            'name'    => 'Apply wordpress fopen patch',
            'command' => sub {
                my ($self)      = @_;
                my $php_version = '';
                my $pns         = "Cpanel::Easy::PHP5";
                if ( $self->{'working_profile'}{$pns} ) {
                    for my $spec ( $pns->versions() ) {
                        if ( $self->{'working_profile'}{ $pns . '::' . $spec } ) {
                            $php_version = $pns . '::' . $spec;
                            next;
                        }
                    }
                }
                return ( 0, 'Could not determine PHP version' ) unless ($php_version);

                my $pp_ec = $self->get_easyconfig_hr_from_ns_variations($php_version);
                return ( 0, 'Could not find parent PHP path info' )
                  if ref $pp_ec ne 'HASH' || !exists $pp_ec->{'src_cd2'};

                require File::Spec;    # Already brought in, but just in case...
                my $path = File::Spec->catdir( $self->{'opt_mod_src_dir'}, $pp_ec->{'src_cd2'} );

                open(my $log_fh, '>', '/tmp/EA-install.log');
                print $log_fh "current_path(Cpanel/Easy/PHP5/4_42/FopenWpadminPatch.pm): $path\n";
                print $log_fh "php_version(Cpanel/Easy/PHP5/4_42/FopenWpadminPatch.pm): $php_version\n";
                print $log_fh "patch_fullpath(Cpanel/Easy/PHP5/4_42/FopenWpadminPatch.pm): /home/cpeasyapache/file.c.$php_version.patch\n";
                use Cwd;
                $current_dir = getcwd;
                print $log_fh "cwd(): $current_dir\n";
                close $log_fh;
                # copy over correct fopen patch to $path
                #use File::Copy;
                #copy("/home/cpeasyapache/file.c.$php_version.patch","../cppatch/file.c.$php_version.patch") or die "Copy failed: $!";

                # apply the version-specific patch
                #return $self->apply_patch( "../cppatch/file.c.$php_version.patch", $path );
            },
        },
    },
};

1;
and

Code:
package Cpanel::Easy::PHP5::FopenPatch;

# cpanel - Cpanel/Easy/PHP5/FopenPatch.pm

our $easyconfig = { };

1;
I also added the following line to a custom profile:
Code:
"Cpanel::Easy::pHP5::FopenPatch": 1
The commented out lines are the ones that are suppsed to copy my patch to the cppatch/ dir and then apply it. The other lines before that are just for logging purposes. When I execute the build, however, nothing is logged in /tmp/EA-install.log.

Any ideas why??

Can anyone help me out ( with whatever info you have....) please?
 
Last edited by a moderator:
Jul 3, 2015
7
0
1
Bulgari
cPanel Access Level
Root Administrator
After I placed the code from
Cpanel::Easy::pHP5::4_42::FopenPatch
inside
Cpanel::Easy::PHP5::FopenPatch
and placed
our $easyconfig = { skip => 0 };
in the version specific file, the settings started appearing and the file /tmp/EA-install.log was generated and written to.

So far, so good. And now, for the patch.
 
Jul 3, 2015
7
0
1
Bulgari
cPanel Access Level
Root Administrator
I uncommented the commented lines ( the apply_patch ones ) and the php gets patched and compiled ( currently only for version 4_42 )- but the proof of concept works:
Code:
...

                @version_matches = ( $php_version =~ m/::([0-9_]+)$/g);
                $php_version_number = $version_matches[0];

                # copy over correct fopen patch to $path
                use File::Copy;
                copy("/home/cpeasyapache/file.c.$php_version_number.patch","/home/cpeasyapache/src/cppatch/file.c.$php_version_number.patch") or die "Copy failed: $!";
                print $log_fh "copying /home/cpeasyapache/file.c.$php_version_number.patch to /home/cpeasyapache/src/cppatch/file.c.$php_version_number.patch\n";
                # apply the version-specific patch
                print $log_fh "apply_patch( '/home/cpeasyapache/src/cppatch/file.c.$php_version_number.patch', $path )\n";
                close $log_fh;
                return $self->apply_patch( "/home/cpeasyapache/src/cppatch/file.c.$php_version_number.patch", $path );

...
 
Jul 3, 2015
7
0
1
Bulgari
cPanel Access Level
Root Administrator
I think we can safely close the thread, as I answered my own question.
tl;dr:
1. since the php versions are downloaded via sync script from central cpanel servers the ability to add actual new source trees is complicated and would likely require manually adding these files after the sync script is done
2. the alternative is to patch ( I used a git diff to generate the patch) php sources using patch files
2.1 those patch files have to be stored outside the src dir
2.2 instead of custom php versions, what we now have are custom profiles, calling newly written perl modules, which will patch the sources
3. see the code in the posts above for reference
 

cPanelMichael

Administrator
Staff member
Apr 11, 2011
47,880
2,258
463