wiki:NightlyBuildBot
Last modified 10 years ago Last modified on 11/29/09 19:19:26

Setting up a buildhost for Redhat-based distros

General directions

The idea behind the buildhost is pretty simple. All you need is a clone of our git repository and a helper script that you might cron for execution at a certain time. The script would periodically fetch the changes from the repo to keep the local copy of the sources up to date, run mock to build the RPMs in a chroot'ed environment, corresponding to the target operating systems and finally automatically sync the folder with your public webhost. For this you need

  • git, of course
  • recent mock (we're running current git snapshot)
  • recent autoconf (> 2.60)
  • createrepo to make nice repos for yum
  • weex or lftp to sync your package tree

If you consider to run this on a RHEL5 host, you would also need

  • up-to-date RPM with SHA1 and XZ patches
  • patched nss & co for EL5 i386 targets
  • bleeding edge mock

Most of this stuff is readily available for you at the Fedora Infrastructure repos, because they still use a certain number of EL5 builders. Be warned, however, that you need a certain amount of knowledge to go this route, so if you don't mind accidentally blowing up your machine, just go ahead.

The script we use is given below for your convenience (public domain). Feel free to adjust it to suit your system. If you find a potential flaw or want to contribute an enhancement feel free to get in touch with the buildhost maintainer.

mc-build.sh

#!/bin/bash

PATH_BASE=/home/buildbot
PATH_UPLOAD=$PATH_BASE/mc-upload
PATH_SOURCE=$PATH_BASE/mc-git
PATH_TEMP=$PATH_BASE/mc-temp
PATH_RPM=/home/src/rpm
PATH_MOCK=/var/lib/mock

BUILD_ARCH="epel-4-i386 epel-4-x86_64 epel-5-i386 epel-5-x86_64 fedora-10-i386 fedora-10-x86_64 fedora-11-i386 fedora-11-x86_64"

echo Suck git updates...
cd $PATH_SOURCE
git fetch
git reset --hard origin/master
echo Done!

rm -rf $PATH_UPLOAD
mkdir $PATH_UPLOAD

echo Clone source tree...
rm -rf $PATH_TEMP
cp -r $PATH_SOURCE $PATH_TEMP
echo Done!

echo Make dist
cd $PATH_TEMP
./autogen.sh
./configure
make -j 2 dist
echo Done!

for i in $BUILD_ARCH;
do
    
    echo Removing old stuff
    rm -f $PATH_RPM/SPECS/mc.spec
    rm -f $PATH_RPM/SOURCES/mc-*.tar.gz
    rm -f $PATH_RPM/SRPMS/mc-*.src.rpm
    echo Done!

    echo Building SRPM...
    cp mc-*.tar.gz $PATH_RPM/SOURCES
    cp ./contrib/dist/redhat/mc.spec $PATH_RPM/SPECS    

    if [[ "$i" =~ "epel-4" ]]; then
        rpmbuild -bs $PATH_RPM/SPECS/mc.spec --define="dist .el4" --define="el4 1"
    else
        rpmbuild -bs $PATH_RPM/SPECS/mc.spec    
    fi

    echo Done!

    MC_RPM="`ls $PATH_RPM/SRPMS/mc-*.src.rpm`"

    echo Building $i...
    mkdir $PATH_UPLOAD/$i
    mock $MC_RPM --define="packager John Doe <john@doe.com>" -r $i
    cp $PATH_MOCK/$i/result/*.rpm $PATH_UPLOAD/$i
    cp $PATH_MOCK/$i/result/build.log $PATH_UPLOAD/$i
    createrepo $PATH_UPLOAD/$i
    echo Done!

done

for i in `find $PATH_UPLOAD -type f`;
do
    sha1sum $i >>$PATH_UPLOAD/sha1sums
done

HOME=$PATH_BASE weex mc

glib2-CVE-2008-4316.patch

diff -up glib-2.12.3/glib/gbase64.c.CVE-2008-4316 glib-2.12.3/glib/gbase64.c
--- glib-2.12.3/glib/gbase64.c.CVE-2008-4316        2006-07-05 12:42:18.000000000 -0400
+++ glib-2.12.3/glib/gbase64.c        2009-03-09 11:48:11.161822330 -0400
@@ -54,8 +54,9 @@ static const char base64_alphabet[] =
  *
  * The output buffer must be large enough to fit all the data that will
  * be written to it. Due to the way base64 encodes you will need
- * at least: @len * 4 / 3 + 6 bytes. If you enable line-breaking you will
- * need at least: @len * 4 / 3 + @len * 4 / (3 * 72) + 7 bytes.
+ * at least: (@len / 3 + 1) * 4 + 4 bytes (+ 4 may be needed in case of
+ * non-zero state). If you enable line-breaking you will need at least:
+ * ((@len / 3 + 1) * 4 + 4) / 72 + 1 bytes of extra space.
  *
  * @break_lines is typically used when putting base64-encoded data in emails.
  * It breaks the lines at 72 columns instead of putting all of the text on 
@@ -220,8 +221,13 @@ g_base64_encode (const guchar *data, 
   gint state = 0, outlen;
   gint save = 0;
 
-  /* We can use a smaller limit here, since we know the saved state is 0 */
-  out = g_malloc (len * 4 / 3 + 4);
+  /* We can use a smaller limit here, since we know the saved state is 0,
+     +1 is needed for trailing \0, also check for unlikely integer overflow */
+  if (len >= ((G_MAXSIZE - 1) / 4 - 1) * 3)
+    g_error ("%s: input too large for Base64 encoding (%"G_GSIZE_FORMAT" chars)",
+             G_STRLOC, len);
+
+  out = g_malloc ((len / 3 + 1) * 4 + 1);
   outlen = g_base64_encode_step (data, len, FALSE, out, &state, &save);
   outlen += g_base64_encode_close (FALSE,
                                    out + outlen, 
@@ -264,7 +270,8 @@ static const unsigned char mime_base64_r
  *
  * The output buffer must be large enough to fit all the data that will
  * be written to it. Since base64 encodes 3 bytes in 4 chars you need
- * at least: @len * 3 / 4 bytes.
+ * at least: (@len / 4) * 3 + 3 bytes (+ 3 may be needed in case of non-zero
+ * state).
  * 
  * Return value: The number of bytes of output that was written
  *
@@ -338,12 +345,15 @@ g_base64_decode (const gchar *text,
                  gsize       *out_len)
 {
   guchar *ret;
-  gint inlen, state = 0;
+  gsize inlen;
+  gint state = 0;
   guint save = 0;
   
   inlen = strlen (text);
-  ret = g_malloc0 (inlen * 3 / 4);
-  
+  /* We can use a smaller limit here, since we know the saved state is 0,
+     +1 used to avoid calling g_malloc0(0), and hence retruning NULL */
+  ret = g_malloc0 ((inlen / 4) * 3 + 1);
+
   *out_len = g_base64_decode_step (text, inlen, ret, &state, &save);
   
   return ret;