Saturday, January 3, 2015

Dual Booting with GRUB2 (CentOS 7) and Windows 7

TL;DR:You need to install the ntfs-3g package, in order for os-prober to detect Windows installations. This allows grub2-mkconfig to automatically generate an entry for dual-booting into Windows.


Doing a lot more hardware hacking these days, I've felt constrained running Linux in a VM all the time. I was especially disappointed that VirtualBox doesn't expose nested Intel VT-x features to its guests. So I've decided to try dual-booting again, going with the very stable CentOS 7.

Not willing to sacrifice any space on my Windows SSD, I put another Crucial SSD in my machine - this time the 256 GB version of their newer MX100 series. Downloading the NetInstall ISO and pointing at a relatively close mirror gave a very satisfying install experience. Having the whole drive made things quite easy as well - except for the actual Dual-Booting part.

I wasn't terribly surprised that the setup process didn't automatically add a GRUB 2 entry for booting to my Windows 7 drive. Everything I read indicated that simply running grub2-mkconfig should set up the GRUB config script to include Windows. Yet, it wasn't working for me. Supposedly GRUB 2 uses os-prober to automatically detect other OSes and generate boot entries for them. However, running os-prober showed no Windows install, even though my drive was clearly visible.

After stumbling across this post on LinuxQustions.org, it turns out that the NTFS-3g package (for mounting NTFS volumes) isn't installed by default, and os-prober needs this the mount the drive and detect the installed OS. After installing ntfs-3g (from the EPEL repository), I was able to run grub2-mkconfig -o /boot/grub2/grub.cfg and successfully add an entry for Windows 7.

Tuesday, December 30, 2014

Installing Nemiver on Centos 7

I recently heard about Nemiver, a standalone C/C++ debugger for GNOME, and wanted to give it a try.

My current Linux development box is running CentOS 7. While Nemiver packages exist for CentOS 6, the same cannot be said for CentOS 7. So I proceeded to build it from source.

First, I went ahead and cloned the Git repository: git clone git://git.gnome.org/nemiver

After running the ./autogen.sh script, it was clear that I was in for several iterations of dependency installation. I'll save you the trouble:

sudo yum install gnome-common intltool yelp-devel yelp-tools boost-devel sqlite-devel GConf2-devel libgtop2-devel glibmm24-devel gtkmm30-devel gtk3-devel gtksourceview3-devel vte3 vte3-devel

Note that I do have the EPEL repository enabled, so I'm not sure if some of those packages came from EPEL or not.

Unfortunately, there seems to be no gtksourceviewmm-3.0 package for CentOS 7 either! Sure, why not install that one from source, too?

First, download gtksourceviewmm-3.2.0.tar.xz (or later). By default, configure defaults to PREFIX=/usr/local. If you don't change this, pkg-config won't know where do find it. So ./configure --prefix=/usr --libdir=/usr/lib64 seems to be what we want. Then make, sudo make install as usual.

Now, you should be able to finish configuring and making Nemiver!

Note that there also seemed to be a build issue in src/confmgr/nmv-gconf-mgr.cc. The following patch took care of it for me - not sure how this went unnoticed.

--- a/src/confmgr/nmv-gconf-mgr.cc
+++ b/src/confmgr/nmv-gconf-mgr.cc
@@ -32,6 +32,7 @@
 NEMIVER_BEGIN_NAMESPACE (nemiver)
 
 using nemiver::common::GCharSafePtr;
+using nemiver::common::GErrorSafePtr;
 
 class GConfMgr : public IConfMgr {
     GConfMgr (const GConfMgr &);

Until this is fixed, you can use my fork at git@github.com:JonathonReinhart/nemiver.git

Thursday, October 23, 2014

GitLab time zone issues

GitLab is a great open source GitHub clone, which I've started using for tracking my personal Git repos.

One frustrating thing I've found with GitLab however, is its handling of time zones.

Read:

Apparently GitLab doesn't detect the user's timezone (or store it in their profile) and display times accordingly.  Everything outside of the Git timestamps appears to be tracked in UTC.

To fix this for my local server, I edited
    /opt/gitlab/embedded/service/gitlab-rails/config/application.rb
and specified
    config.time_zone = 'Eastern Time (US & Canada)'

Update:

In version 7.5.0, this configuration option was moved to gitlab.yml. Now you don't have to re-set this option after every upgrade. Instructions for how to set it for an Omnibus install (in /etc/gitlab/gitlab.rb) are here.

Wednesday, May 28, 2014

TrueCrypt-end

Today, the TrueCrypt website and SourceForge project page suddenly changed, indicating the end of TrueCrypt development. truecrypt.org now redirects to their SourceForge project page, and the content has been replaced with a surprising message:


Not only has development officially ceased, but TrueCrypt is being declared "not secure", and the official webpage is suggesting that people migrate to BitLocker!  (BitLocker is the drive encryption solution built in to some versions of Windows Vista and later.)  Furthermore, a new version 7.2 had been released, which warns users that TrueCrypt is insecure. The repository had been scrubbed, and all previous binaries had been deleted.

I'm sure you could almost hear the collective WTF?! from everyone in the InfoSec community.

A series of edits indicating that the software had been discontinued were even posted to the TrueCrypt Wikipedia page by a user with the handle Truecrypt-end.

At first, it seemed like some pranksters had managed to take over the TrueCrypt website, and poke fun by suggesting users migrate to their inferior commercial competitor, BitLocker.  Well, the DNS records had not changed, so everything was good there. And SourceForge indicated that there was no suspicious behavior on the account (ya know, aside from closing everything down!)

Of course there are rumors abound at all of the tech watering holes, from Slashdot to the /r/sysadmin subreddit  to the InfoSec Stack Exchange site and of course Twitter.  While many still believe that the project was hacked, others are pondering the possibility that the devs were asked to insert a back-door, and subject to a gag-order preventing them from disclosing the requirement.  The TrueCrypt development team has remained behind the big black curtain for most of its development which makes the situation even more curious. Perhaps a vulnerability had been discovered and the developers simply didn't want to be involved with the product any more. There is certainly no shortage of opinions on the matter. The most interesting theory I've heard is that this is a sort of warrant canary.


So what about this new version 7.2?

The binaries were signed with the same GPG key as all previous releases, indicating that this release was "official", or at least produced by someone with access to the private key.

Internally, the TrueCrypt.exe executable and the truecrypt(-x64).sys drivers were signed (a la Microsoft Authenticode) with a different certificate than 7.1.1, but that certificate expired shortly after the last release. This new certificate was issued (to the same named entity) shortly before the previous certificate expired. It's very unlikely that someone was able to spoof a new certificate in this manner, and had planned it two years ago.  [Screenshots tomorrow.]

The changes to the latest version's source code were posted to GitHub.  This paints probably the most confusing picture of all.  

First, the code has been littered with warning messages and error codes indicating that "Using TrueCrypt is not secure".  Next, we see that pretty much all of the code related to creating encrypted volumes has been removed, and replaced with AbortProcess ("INSECURE_APP");. We also notice that all code related to updates, error reporting, user's guide/help, or anything pointing back to the TrueCrypt website has been removed.  Clearly, the developers consciously made the decision to burn all bridges, and carefully executed a plan to do so.

What's very bizarre however, is that while there were 4112 deletions, there were also 1760 additions to the code. Along with other minor bugfixes, it appears that in-place decryption was newly implemented.  It looks as if this was code that was part of an upcoming release that brought some improvements after a two-year break. Unfortunately, it also came with mass deletions that rendered the software useless for anyone seeking to create encrypted content.

What are you thoughts?



Thursday, March 7, 2013

Gotta catch 'em all: Last-chance exception handling in .NET with WinForms

Recently, I went through the exercise of hooking up a crash-reporting component to a large .NET application using Windows Forms.  The goal, of course, is to catch all unhandled exceptions so they can be reported to the developer.

Throughout this post I'll be referring to this Program.cs. The code we incrementally un-commented for each of the examples. I'll also link to compiled example executables. If you don't trust my binaries, you can compile them yourself.



0.  No exception handling

First we see an application that throws exceptions in the UI thread and a background thread, with no handling. Try out 0_Nothing.exe.
With no exception handling, background thread exceptions crash hard. UI thread exceptions are handled by the built-in .NET WinForms handler:


This has a Continue option which allows the user to ignore the exception and go on. This method is absolutely unacceptable. No exceptions should ever be allowed to be ignored, as the program is in an indeterminate state.


1.  try / catch

The naive approach would be to set up a try/catch block in Main() around the Application.Run() call. See 1_TryCatch.exe.
try {
   Application.Run(new Form1());
}
catch (Exception ex) {
   // ...
}
We see here that there is no difference between this and the version with no try/catch. This is because the UI thread exceptions are still being handled inside of Application.Run() by the default handler. The try/catch is never used, and background thread exceptions are unaffected.


2.  Application.ThreadException

Next, we utilize WinForms' Application.ThreadException event to handle UI thread exceptions. See 2_Application_ThreadException.exe.
Application.ThreadException += (sender, args) =>
   HandleException("Application.ThreadException", args.Exception);
Here, we see that instead of the unacceptable WinForms handler, our handler was called (for UI thread exceptions). However, as MSDN points out (emphasis mine):
This event allows your Windows Forms application to handle otherwise unhandled exceptions that occur in Windows Forms threads.
...
To catch exceptions that occur in threads not created and owned by Windows Forms, use the UnhandledException event handler.
So background thread exceptions still crash hard in this example.


3.  AppDomain.UnhandledException

Now we follow the documentation and hook up the AppDomain.UnhandledException handler. See 3_AppDomain_UnhandledException_NoUhandledMode.exe.
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
   HandleException("AppDomain.UnhandledException", (Exception)args.ExceptionObject);
Now finally, we are able to catch exceptions on background threads with this handler. UI thread exceptions, however, are still handled by our Application.ThreadException handler.


4.  Application.SetUnhandledExceptionMode

As mentioned in the MSDN documentation, a call to Application.SetUnhandledExceptionMode and passing UnhandledExceptionMode.ThrowException tells Winforms to not use the Application.ThreadException handler. Instead, it lets exceptions bubble out of Application.Run. See this in 4_Everything.exe.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
The result is that the try/catch around Application.Run actually works now: UI thread exceptions are now caught by that handler.


5.  No more try / catch

Finally, removing the try/catch around Application.Run allows for all unhandled exceptions to be handled via AppDomain.UnhandledException. See 5_Final.exe. This is how we ended up handling everything in our application; we found it ideal to have one route for all[1] unhandled exceptions.



Summary

It is important to note that all exceptions are handled on the thread that they occurred on. If you're in the same boat I was in, you're stuck with a third-party crash handler component that had to be run on the UI thread. Because of this, I marshal the calls to the UI thread with a call to Control.Invoke(), as usual for cross-thread UI stuff.

[1] - In fact it gets even more complicated. There are certain scenarios where exceptions that need to cross Kernel or COM boundaries can be swallowed. For example, the Form.OnLoad method is actually a user-mode kernel callback. These are notorious for swallowing exceptions. In cases where we are sufficiently suspect of exceptions, we set up a try/catch and manually hand off the exception to the common handler.

The full source code for my example binaries can be downloaded here.

Monday, February 25, 2013

goto: The Forbidden Fruit



Nowdays, it's not hard to find tons of arguments against the use of goto in C (and C-like languages).  Post anything to StackOverflow, about/including goto and you're almost guaranteed to get flamed.


Just like many good and useful things in our lives (pocketknives, guns, kegs, etc.) it only takes a few people to abuse something before everyone else categorizes it as "bad".  But the truth is, goto is a simple tool that, when used correctly, can make a program much easier to write (and even understand!)

First, let's take a look at how *not* to use goto (this is just a little example, nothing meaningful):

int foo(int a)
{

   int bar;
   while (bar < spam())
   {
loop:
      bar = a * scale;
      if (bar > 100) goto toobig;
      bla(bar);
   }
   return bar;
toobig:
   if (bar-tar > 0)
      return bar;
   bar -= 5; goto loop;


   return bar * 2;
}


Wow, that was even hard to come up with, and cetrainly isn't the way to do things. Jumping in and out of control structures is bound to confuse the next guy, and possibly the compiler when it is trying to optimize.

But in the right places, goto can be extremely useful. Luckily, my opinion here is not alone. In fact, the Linux Kernel (3.8) uses goto over 100,000 times!
$ find linux-3.8 -iname '*.c' -exec grep 'goto' {} \; | wc -l
104299
Here is a good example of this programming style in use, from the ext4 driver.


First, let's look at some bad code. The author does two things that I really dislike: 1) They return all over the place. This is okay, unless (like in this example) you have to deal with resource de-allocation. Here, this leads to a fragile situation with lots of calls to free. 2) They check first for success, which leads to ridiculous amounts of nesting.
bool baz() {
   bool result = false;
   uint8_t *buf1 = NULL;
   uint8_t *buf2 = NULL;
   uint8_t *buf3 = NULL;

   // Allocate buffers.
   buf1 = malloc(BUF1_SIZE);
   if (buf1) {

      buf2 = malloc(BUF2_SIZE);
      if (buf2) {

         buf3 = malloc(BUF3_SIZE);
         if (buf3) {

            result = use_buffers(buf1, buf2, buf3);
            if (result)
               printf("Success!\n");
            else
               fprintf(stderr, "Operation failed.\n");
            free(buf3);
            free(buf2);
            free(buf1);
            return result;

         }
         else {
            fprintf(stderr, "Error allocating %d bytes.\n", BUF3_SIZE);
            free(buf2);
            free(buf1);
            return false;
         }
      }
      else {
         fprintf(stderr, "Error allocating %d bytes.\n", BUF2_SIZE);
         free(buf1);
         return false;
      }
   }
   else {
      fprintf(stderr, "Error allocating %d bytes.\n", BUF1_SIZE);
      return false;
   }
}


Using goto and a single exit point clean this mess up very nicely:
bool baz() {
   bool result = false;    // Assume failure until proven successful
   uint8_t *buf1 = NULL;
   uint8_t *buf2 = NULL;
   uint8_t *buf3 = NULL;

   // Allocate buffers.
   buf1 = malloc(BUF1_SIZE);
   if (!buf1) {
      fprintf(stderr, "Error allocating %d bytes.\n", BUF1_SIZE);
      goto exit;
   }

   buf2 = malloc(BUF2_SIZE);
   if (!buf2) {
      fprintf(stderr, "Error allocating %d bytes.\n", BUF2_SIZE);
      goto exit;
   }

   buf3 = malloc(BUF3_SIZE);
   if (!buf3) {
      fprintf(stderr, "Error allocating %d bytes.\n", BUF3_SIZE);
      goto exit;
   }

   // Do something useful
   if (!use_buffers(buf1, buf2, buf3)) {
      fprintf(stderr, "Operation failed.\n");
      goto exit;
   }

   result = true;
   printf("Success!\n");

exit:
   if (buf1) free(buf1);
   if (buf2) free(buf2);
   if (buf3) free(buf3);

   return result;
}

This allows for a very straight-forward approach to handling resource allocation/freeing and a clean exit path. It's much easier to maintain as well (imagine having to remove buf2 in the first example!)

An alternative to goto I often see is the dummy do-while loop:
bool baz() {
   bool result = false;
   uint8_t *buf1 = NULL;
   uint8_t *buf2 = NULL;
   uint8_t *buf3 = NULL;

   do {
      // Allocate buffers.
      buf1 = malloc(BUF1_SIZE);
      if (!buf1) {
         fprintf(stderr, "Error allocating %d bytes.\n", BUF1_SIZE);
         break;
      }
   
      buf2 = malloc(BUF2_SIZE);
      if (!buf2) {
         fprintf(stderr, "Error allocating %d bytes.\n", BUF2_SIZE);
         break;
      }
   
      buf3 = malloc(BUF3_SIZE);
      if (!buf3) {
         fprintf(stderr, "Error allocating %d bytes.\n", BUF3_SIZE);
         break;
      }
   
      // Do something useful
      if (!use_buffers(buf1, buf2, buf3)) {
         fprintf(stderr, "Operation failed.\n");
         break;
      }
   
      result = true;
      printf("Success!\n");
   } while(0);

   if (buf1) free(buf1);
   if (buf2) free(buf2);
   if (buf3) free(buf3);

   return result;
}

This isn't terrible, but what about when you want to use an actual loop inside that dummy do-while, and break out of it? PHP includes a nice disgusting feature to break out of multiple levels. In other languages you're screwed, unless you follow the loop with some additional code to check for completion of the loop:

bool baz() {
   bool result = false;
   uint8_t *buf1 = NULL;
   uint8_t *buf2 = NULL;
   int i;

   do {
      // Allocate buffers.
      buf1 = malloc(BUF1_SIZE);
      if (!buf1) {
         fprintf(stderr, "Error allocating %d bytes.\n", BUF1_SIZE);
         break;
      }
   
      buf2 = malloc(BUF2_SIZE);
      if (!buf2) {
         fprintf(stderr, "Error allocating %d bytes.\n", BUF2_SIZE);
         break;
      }
   
      // Do something in a loop
      for (i=0; i<CONSTANT; ++i) {
         if (!use_buffers(buf1, buf2)) {
            fprintf(stderr, "Operation #%d failed.\n", i);
            break;            // Can't get out of the do-while from here!
         }
      }

      // Have to add this ridiculous check, because we could have exited
      // the loop early...
      if (i==CONSTANT) {
         result = true;
         printf("Success!\n");
      }
   } while(0);

   if (buf1) free(buf1);
   if (buf2) free(buf2);

   return result;
}
In this case, a goto exit; would have worked just fine.

Sunday, February 24, 2013

Deftones - You've Seen the Butcher - Timing


Maybe the name of this blog should include something about ADD or OCD. Either way, enough time was spent perfecting this, I figure I might as well share it with the Interwebs.

I'm a big fan of Deftones and their 2010 album Diamond Eyes was unsurprisingly awesome.  You've Seen the Butcher is an awesome track.  The timing is subtly complicated, so I decided to chart it out.  Hope this helps someone.

All time signatures are x/4, and the number of beats in each measure are shown.  For many parts of the song, the final measure's number of beats is the same as the part that follows. These are noted.

Intro
     lead-in                      1

Guitar-only               Alt. 3 and 4
     last measure                 5

Heavy riff (no vox)    Alt. 3 and 5
     last measure                 4


Verse 1
Verse                  Alt. 3 and 4
     last measure                 5

Pre-Chorus             Alt. 3 and 5

Chorus                 4
     last measure                 3


Verse 2
Verse                  Alt. 3 and 4
     last measure                 5

Pre-Chorus             Alt. 3 and 5

Chorus                 4


Bridge  note the two 6/4 measures

Heavy riff (no vox)    3  5  3  6  3  5  3  5
                     
Pre-Chorus             3  5  3  6  3  5  3  5


Outro
Chrous                 4
     last measure                 5

Ending                 3  (free)