Source code for the MCU firmware?

Where can I find the source code to the MCU’s firmware? hifive-premier-p550-tools/mcu-firmware at master · sifive/hifive-premier-p550-tools · GitHub just contains an ELF…

I want to check if it’s really as stupid as it looks in the user manual, that only a Web interface is accessible over ethernet, and not the CLI. :smile:

It’s closed sourced AFAIK. You can sort of create a CLI yourself. The Web interface will use REST/json API to communicate with the MCU. E.g., to get power status, you can use curl -v http://<ip>/power_status (Other APIs can be easily discovered by using developer tools in the browser to capture network requests)

{
  "status": 0,
  "message": "success",
  "data": {
    "power_status": "0"
  }
}

The code quality is pretty bad, though. I can sort of “crash” it (unresponsive to further requests) by doing a port scan through nmap. Luckily the MCU is a STM32F4 (STM32F407VET6) that has the tooling readily available. So I hope I can do a full open-source re-write some time later.

1 Like

Currently MCU repo is private and we will provide fixes for firmware in form of binary.

I must say that the choice of web UI for the ethernet management seems to have been a very poor one. It just doesn’t work. Whenever I try to login, it just says “request failt[sic], try again”. If I check the communication with wireshark, it goes like this:

Browser:
—8<—
POST /login HTTP/1.1
Host: 192.168.44.159
Connection: keep-alive
Content-Length: 29
Accept: /
DNT: 1
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Origin: http://192.168.44.159
Referer: http://192.168.44.159/login.html
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

username=admin&password=admin
—8<—

MCU:
—8<—
HTTP/1.1 413
Connection: close
Content-Length: 48

Request header Too Large header:662,TCP_MSS:640
—8<—

So it can’t even handle the login request because it’s supposedly “too large”. And without the source code we can’t even do anything to fix it…

This is yet another bug in the MCU code. I sort of reproduced it by crafting a HTTP request with larger headers than usual. Also it looks like once the code went to the “header too large” state, it can victimize new connections with legitimate headers! However, it also seems it can be recovered by retrying login through the new HTTP connection, given the 2nd attempt is reusing the same TCP stream… (such as re-login through Chrome) Very confusing. @ESWIN_Support Please fix that, thanks.

I made a small shell script to control the basic functions using curl. It seems that the password isn’t even needed?! Even with this script I still get the “Request header Too Large” from time to time though.

#!/bin/sh

: ${IP:=192.168.44.159}

usage() {
  echo "$0" '{power_status|power_on|power_off|somconsole|telnet_console|uart_console|telnet}'
}

rest_get() {
  curl http://${IP}/${1}'?byhand=0'
}

rest_set() {
  curl --data-urlencode "${2}" http://${IP}/${1}
}

case "$1" in
 power_status) rest_get power_status;;
 power_on) rest_set power_status power_status=1;;
 power_off) rest_set power_status power_status=0;;
 somconsole) rest_get somconsole;;
 telnet_console) rest_set somconsole method=1;;
 uart_console) rest_set somconsole method=0;;
 telnet) exec telnet ${IP};;
 *) usage; exit 1;;
esac

@marcus Could you please share the MCU version and the host software you are using to access the web UI?

% curl http://192.168.44.159/bmc_version
{"status":0,"message":"success","data":{"version":"BMC Version:2.6"}}

The host software I’m using is the shell script I posted above, since using a web browser (I tried both Chromium and Firefox) did not work.

The root cause of the problem is that the MCU’s web server is based on lwIP, which is a lightweight socket framework that has many limitations. One of these limitations is that when the length of the request message exceeds TCP_MSS, the portion of the data that exceeds TCP_MSS becomes garbage data. This garbage data can cause the entire server to enter an unpredictable state.

To avoid this issue, a check was added for HTTP requests. When the length of the request message exceeds TCP_MSS, an error message is returned directly.

How can users work around this issue?

They can switch to a different browser, such as Firefox, or use an older version of Chrome, and ensure that the headers are kept below 600 characters.

Alternatively, they can use curl to initiate HTTP requests. For query-type interfaces, login state validation will not be performed. The URL needed for curl can be found in the jQuery section of the webpage source code (right-click in the browser to view the page source).

You may need to reset the MCU. Looks like the “header too large” state will affect future connections. Reset it and start clean then see if the problem goes away. (Assuming you’ll not trigger it again) if this behavior can be confirmed, then it’s a bug, period (DoS)

I’ll not be able to do further tests with the MCU until after the holidays. Now I finally have the SOM online and remote accessible, so I’d like to keep it that way while I’m out of town for the next two weeks. :slight_smile: