slackhq/go-audit

Failed with panic: runtime error: invalid memory address or nil pointer dereference

joelchen opened this issue · 6 comments

  • I've read and understood the Contributing guidelines and have done my best effort to follow them.
  • I've read and agree to the Code of Conduct.
  • I've searched for any related issues and avoided creating a duplicate issue.

Description

e.g. Description of the bug or feature

Reproducible in:

go-audit version: Latest master branch
OS version(s): Ubuntu 16.04.3 LTS (4.4.0-1028-aws)
rsyslog (preinstalled in Ubuntu): 8.16.0

Steps to reproduce:

  1. Install go-audit with go get github.com/slackhq/go-audit, or make in $GOPATH/src/github.com/slackhq/go-audit after go get github.com/slackhq/go-audit.
  2. Copy go-audit from $GOPATH/bin of former in step 1 or $GOPATH/src/github.com/slackhq/go-audit of latter in step 1, into /usr/local/bin.
  3. Configure /etc/go-audit.yml with syslog output following https://github.com/slackhq/go-audit/blob/master/go-audit.yaml.example and run go-audit with systemd.
  4. Configure /etc/go-audit.yml with file output and sudo mkdir /var/log/go-audit, and restart go-audit yields the same failure.
  5. Configure /etc/rsyslog.conf with module(load="imtcp") and input(type="imtcp" port="514"), /etc/go-audit.yml configured with network: tcp and address: localhost:514, and restart go-audit yields the same failure.

Expected result:

Normal run of go-audit.

Actual result:

Output of /var/log/syslog:

Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: Flushed existing audit rules
Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: Added audit rule #1
Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: Added audit rule #2
Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: Added audit rule #3
Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: Socket receive buffer size: 32768
Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: panic: runtime error: invalid memory address or nil pointer dereference
Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x75ef0f]
Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: goroutine 1 [running]:
Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: main.createFilters(0xc42007c1e0, 0x838967, 0x21, 0x1f4)
Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: #011/home/ubuntu/go/src/github.com/slackhq/go-audit/audit.go:299 +0x55f
Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: main.main()
Aug  6 02:28:05 ip-10-255-0-48 go-audit[1138]: #011/home/ubuntu/go/src/github.com/slackhq/go-audit/audit.go:339 +0x374
Aug  6 02:28:05 ip-10-255-0-48 systemd[1]: go-audit.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Aug  6 02:28:05 ip-10-255-0-48 kernel: [   15.659200] audit_printk_skb: 15 callbacks suppressed
Aug  6 02:28:05 ip-10-255-0-48 kernel: [   15.659203] audit: type=1131 audit(1501957685.404:17): pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=go-audit comm="systemd" exe="/lib/systemd/systemd" hostname=? addr=? terminal=? res=failed'
Aug  6 02:28:05 ip-10-255-0-48 systemd[1]: go-audit.service: Unit entered failed state.
Aug  6 02:28:05 ip-10-255-0-48 systemd[1]: go-audit.service: Failed with result 'exit-code'.
Aug  6 02:28:05 ip-10-255-0-48 kernel: [   15.668861] audit: type=1300 audit(1501957685.416:18): arch=c000003e syscall=59 success=yes exit=0 a0=134e8e8 a1=134d6c8 a2=1343008 a3=598 items=2 ppid=1359 pid=1361 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="sed" exe="/bin/sed" key=(null)
Aug  6 02:28:05 ip-10-255-0-48 kernel: [   15.668867] audit: type=1309 audit(1501957685.416:18): argc=2 a0="sed" a1="s/\([^.]*\)[^@]*\(.*\)/\1\2/"
Aug  6 02:28:05 ip-10-255-0-48 kernel: [   15.668869] audit: type=1307 audit(1501957685.416:18):  cwd="/"
Aug  6 02:28:05 ip-10-255-0-48 kernel: [   15.668873] audit: type=1302 audit(1501957685.416:18): item=0 name="/bin/sed" inode=15 dev=ca:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
Aug  6 02:28:05 ip-10-255-0-48 kernel: [   15.668876] audit: type=1302 audit(1501957685.416:18): item=1 name="/lib64/ld-linux-x86-64.so.2" inode=2041 dev=ca:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
Aug  6 02:28:05 ip-10-255-0-48 kernel: [   15.668880] audit: type=1327 audit(1501957685.416:18): proctitle=73656400732F5C285B5E2E5D2A5C295B5E405D2A5C282E2A5C292F5C315C322F
Aug  6 02:28:05 ip-10-255-0-48 kernel: [   15.696417] audit: type=1300 audit(1501957685.416:19): arch=c000003e syscall=59 success=yes exit=0 a0=134d9c8 a1=1344308 a2=1343008 a3=598 items=2 ppid=1339 pid=1362 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="localedef" exe="/usr/bin/localedef" key=(null)
Aug  6 02:28:05 ip-10-255-0-48 kernel: [   15.696424] audit: type=1309 audit(1501957685.416:19): argc=9 a0="localedef" a1="-i" a2="en_US" a3="-c" a4="-f" a5="UTF-8" a6="-A" a7="/usr/share/locale/locale.alias" a8="en_US.UTF-8"
Aug  6 02:28:05 ip-10-255-0-48 kernel: [   15.696427] audit: type=1307 audit(1501957685.416:19):  cwd="/"

Note:

The auditd is loaded but not active:

$ systemctl status auditd
● auditd.service - Security Auditing Service
   Loaded: loaded (/lib/systemd/system/auditd.service; enabled; vendor preset: enabled)
   Active: inactive (dead)

Looks like there may be a problem with your config teasing out a bug in the filter parsing. Can you add your config here for me to look over?

Another thing, likely unrelated, govendor is used for dependencies in go-audit instead of go get.

The go get will automatically get govendor for dependencies and build the binary for go-audit is not it? Also, I used make which forced me to install govendor beforehand in the second attempt.

As I said in the steps, I followed https://github.com/slackhq/go-audit/blob/master/go-audit.yaml.example for config. Here is config for go-audit.yml for stdout output (stdout is also failing with same error above as with syslog or file output):

# Configure socket buffers, leave unset to use the system defaults
# Values will be doubled by the kernel
# It is recommended you do not set any of these values unless you really need to
socket_buffer:
  # Default is net.core.rmem_default (/proc/sys/net/core/rmem_default)
  # Maximum max is net.core.rmem_max (/proc/sys/net/core/rmem_max)
  receive: 16384

events:
  # Minimum event type to capture, default 1300
  min: 1300
  # Maximum event type to capture, default 1399
  max: 1399

# Configure message sequence tracking
message_tracking:
  # Track messages and identify if we missed any, default true
  enabled: true

  # Log out of orderness, these messages typically signify an overloading system, default false
  log_out_of_order: false

  # Maximum out of orderness before a missed sequence is presumed dropped, default 500
  max_out_of_order: 500

# Configure where to output audit events
# Only 1 output can be active at a given time
output:
  # Writes to stdout
  # All program status logging will be moved to stderr
  stdout:
    enabled: true

    # Total number of attempts to write a line before considering giving up
    # If a write fails go-audit will sleep for 1 second before retrying
    # Default is 3
    attempts: 2

  # Writes logs to syslog
  syslog:
    enabled: false
    attempts: 5

    # Configure the type of socket this should be, default is unixgram
    # This maps to `network` in golangs net.Dial: https://golang.org/pkg/net/#Dial
    network: unixgram

    # Set the remote address to connect to, this can be a path or an ip address
    # This maps to `address` in golangs net.Dial: https://golang.org/pkg/net/#Dial
    address: /dev/log

    # Sets the facility and severity for all events. See the table below for help
    # The default is 132 which maps to local0 | warn
    priority: 129 # local0 | emerg

    # Typically the name of the program generating the message. The PID is of the process is appended for you: [1233]
    # Default value is "go-audit"
    tag: "go-audit"

  # Appends logs to a file
  file:
    enabled: false
    attempts: 2

    # Path of the file to write lines to
    # The actual file will be created if it is missing but make sure the parent directory exists
    path: /var/log/go-audit/go-audit.log

    # Octal file mode for the log file, make sure to always have a leading 0
    mode: 0600

    # User and group that should own the log file
    user: root
    group: root

# Configure logging, only stdout and stderr are used.
log:
  # Gives you a bit of control over log line prefixes. Default is 0 - nothing.
  # To get the `filename:lineno` you would set this to 16
  #
  # Ldate         = 1  // the date in the local time zone: 2009/01/23
  # Ltime         = 2  // the time in the local time zone: 01:23:23
  # Lmicroseconds = 4  // microsecond resolution: 01:23:23.123123.  assumes Ltime.
  # Llongfile     = 8  // full file name and line number: /a/b/c/d.go:23
  # Lshortfile    = 16 // final file name element and line number: d.go:23. overrides Llongfile
  # LUTC          = 32 // if Ldate or Ltime is set, use UTC rather than the local time zone
  #
  # See also: https://golang.org/pkg/log/#pkg-constants
  flags: 0

rules:
  # Watch all 64 bit program executions
  - -a exit,always -F arch=b64 -S execve
  # Watch all 32 bit program executions
  - -a exit,always -F arch=b32 -S execve
  # Enable kernel auditing (required if not done via the "audit" kernel boot parameter)
  # You can also use this to lock the rules. Locking requires a reboot to modify the ruleset.
  # This should be the last rule in the chain.
  - -e 1

# If kaudit filtering isn't powerful enough you can use the following filter mechanism
filters:
  # Each filter consists of exactly 3 parts
  - syscall: 49 # The syscall id of the message group (a single log line from go-audit), to test against the regex
    message_type: 1306 # The message type identifier containing the data to test against the regex
regex: saddr=(10..|0A..) # The regex to test against the message specific message types data

Looks like the problem is the very last line, it should be indented 4 spaces. As for the panic, I will fix that next week.

Thanks @nbrownus. Can it be fix earlier? I would like to use it soon.

You should be able to use it now if you indent the regex line at the very end of your config. The bug I will fix this week will just remove the panic and provide an actionable error message for an incomplete filter rule.

With that merge you should get a much more helpful error message.