commit - f3870eac196bf7bdcedf3aceeba7501d5211b9ae
commit + 2fd3ff87b97ca6e71113c93bb8a9cfbfcae60b2e
blob - 51256227dc2db4529554e695b72bb80083571457
blob + e0db612ff2630fcce59769e289058b77a42e793e
--- FICS/playerdb.c
+++ FICS/playerdb.c
#include "ficsmain.h"
#include "gamedb.h"
#include "lists.h"
+#include "maxxes-utils.h"
#include "network.h"
#include "playerdb.h"
#include "ratings.h"
player_read(int p, char *name)
{
FILE *fp = NULL;
- char *attr, *value;
char fname[MAX_FILENAME_SIZE] = { '\0' };
char line[MAX_LINE_SIZE] = { '\0' };
+ char *attr, *value;
+ char *resolvedPath;
int len = 0;
int version = 0;
- parray[p].login = stolower(xstrdup(name));
+ parray[p].login = stolower(xstrdup(name)); // free on error?
+ if (!is_valid_login_name(parray[p].login)) {
+ warnx("%s: invalid login name: %s", __func__, parray[p].login);
+ return -1;
+ }
+
snprintf(fname, sizeof fname, "%s/%c/%s", player_dir,
parray[p].login[0], parray[p].login);
+ if ((resolvedPath = realpath(fname, NULL)) == NULL) {
+ warn("%s: realpath", __func__);
+ return -1;
+ }
+ if (strncmp(resolvedPath, player_dir, strlen(player_dir)) != 0) {
+ warnx("%s: path traversal detected", __func__);
+ free(resolvedPath);
+ return -1;
+ }
+
+ mstrlcpy(fname, resolvedPath, sizeof fname);
+ free(resolvedPath);
+ resolvedPath = NULL;
+
if ((fp = fopen(fname, "r")) == NULL) { // Unregistered player
parray[p].name = xstrdup(name);
parray[p].registered = 0;