--- freem/src/mumps.c 2025/04/03 20:48:14 1.15
+++ freem/src/mumps.c 2025/04/16 05:37:06 1.24
@@ -1,5 +1,5 @@
/*
- * $Id: mumps.c,v 1.15 2025/04/03 20:48:14 snw Exp $
+ * $Id: mumps.c,v 1.24 2025/04/16 05:37:06 snw Exp $
* main module of freem
*
*
@@ -24,6 +24,33 @@
* along with FreeM. If not, see .
*
* $Log: mumps.c,v $
+ * Revision 1.24 2025/04/16 05:37:06 snw
+ * Refine FreeBSD ASLR fix
+ *
+ * Revision 1.23 2025/04/16 05:33:15 snw
+ * Try to use procctl function to fix ASLR problem on FreeBSD
+ *
+ * Revision 1.22 2025/04/15 16:49:36 snw
+ * Make use of logprintf throughout codebase
+ *
+ * Revision 1.21 2025/04/15 02:24:43 snw
+ * Improve FreeM logging capabilities
+ *
+ * Revision 1.20 2025/04/13 04:22:43 snw
+ * Fix snprintf calls
+ *
+ * Revision 1.19 2025/04/10 01:24:38 snw
+ * Remove C++ style comments
+ *
+ * Revision 1.18 2025/04/09 19:52:02 snw
+ * Eliminate as many warnings as possible while building with -Wall
+ *
+ * Revision 1.17 2025/04/04 21:28:16 snw
+ * Remove custom_user and custom_group vars from freem and shed privileges per environment catalog settings
+ *
+ * Revision 1.16 2025/04/04 19:43:18 snw
+ * Switch to using environment catalog to determine user and group for environment, and remove -u and -g flags from freem
+ *
* Revision 1.15 2025/04/03 20:48:14 snw
* Improve daemon error diagnostics and bump to 0.63.0-rc3
*
@@ -65,6 +92,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
**/
+#define _GNU_SOURCE
#include
#include
#include "mpsdef.h"
@@ -93,8 +121,10 @@
#include
#include
#include
-
-
+#include "log.h"
+#if defined(__FreeBSD__)
+# include
+#endif
#if defined(HAVE_GETOPT_H)
# include
#endif
@@ -108,7 +138,6 @@ extern char *getenv(const char *name);
void freem_usage(void);
void freem_print_version(void);
void init_ztrap(void);
-void m_log (int, const char *);
int main (int argc, char **argv, char **envp)
{
@@ -137,9 +166,6 @@ int main (int argc, char **argv, char **
gid_t d_gid;
uid_t d_uid;
- short custom_user = FALSE;
- short custom_group = FALSE;
-
#if defined(HAVE_GETOPT_LONG)
struct option long_options[] = {
{"help", no_argument, 0, 'h'},
@@ -168,14 +194,13 @@ int main (int argc, char **argv, char **
char *symname = (char *) calloc(STRLEN, sizeof(char));
char *symval = (char *) calloc(STRLEN, sizeof(char));
-
- int namelen;
- int vallen;
-
+
char cli_rtn_path[PATH_MAX] = {0};
char *cli_rtn_file;
char cli_rtn_name[256];
+ char env_ena[25];
+
routine_mode = FALSE;
strcpy (m_dialect, "FREEM");
@@ -193,6 +218,9 @@ int main (int argc, char **argv, char **
strcpy (stack0, argv[0]);
stcnv_c2m (stack0);
+#if defined(__FreeBSD__)
+ int prcdta = PROC_ASLR_FORCE_DISABLE;
+#endif
/* strncpy (config_file, SYSCONFDIR"/freem.conf", 100); */
@@ -205,7 +233,7 @@ int main (int argc, char **argv, char **
while (1) {
- c = getopt_long (argc, argv, "hsfiqRr:n:e:vx:dkpS:u:g:", long_options, &option_index);
+ c = getopt_long (argc, argv, "hsfiqRr:n:e:vx:dkpS", long_options, &option_index);
if (c == -1) break;
if (c == '?') freem_usage ();
@@ -228,7 +256,7 @@ int main (int argc, char **argv, char **
break;
case 'e': /* specify FreeM environment */
- strncpy (shm_env, optarg, 255);
+ strncpy (shm_env, optarg, sizeof (shm_env) - 1);
break;
case 'R':
@@ -318,18 +346,7 @@ int main (int argc, char **argv, char **
case 'S': /* --shmsize */
shm_init_size = atol (optarg);
- break;
-
- case 'u': /* --user */
- strncpy (d_username, optarg, 40);
- custom_user = TRUE;
- break;
-
- case 'g': /* --group */
- strncpy (d_groupname, optarg, 40);
- custom_group = TRUE;
- break;
-
+ break;
}
@@ -341,7 +358,7 @@ int main (int argc, char **argv, char **
extern char *optarg;
extern int optind, optopt;
- while ((c = getopt (argc, argv, "hsfiqRr:n:e:vx:dkS:u:g:")) != -1) {
+ while ((c = getopt (argc, argv, "hsfiqRr:n:e:vx:dkS:")) != -1) {
if (c == '?') freem_usage ();
@@ -364,7 +381,7 @@ int main (int argc, char **argv, char **
break;
case 'e': /* specify FreeM environment */
- strncpy (shm_env, optarg, 255);
+ strncpy (shm_env, optarg, sizeof (shm_env) - 1);
break;
case 'R':
@@ -449,17 +466,6 @@ int main (int argc, char **argv, char **
shm_init_size = atol (optarg);
break;
- case 'u': /* --user */
- strncpy (d_username, optarg, 40);
- custom_user = TRUE;
- break;
-
- case 'g': /* --group */
- strncpy (d_groupname, optarg, 40);
- custom_group = TRUE;
- break;
-
-
}
}
}
@@ -472,35 +478,56 @@ int main (int argc, char **argv, char **
}
#endif
- snprintf (config_file, 4096, "%s/freem/%s/freem.conf", SYSCONFDIR, shm_env);
+ snprintf (config_file, sizeof (config_file) - 1, "%s/freem/%s/freem.conf", SYSCONFDIR, shm_env);
+ snprintf (env_config_file, sizeof (config_file) - 1, "%s/freem/env.conf", SYSCONFDIR);
- if (run_daemon == TRUE && geteuid() == 0) {
+ if (!file_exists (env_config_file)) {
+ logprintf (FM_LOG_FATAL, "freem: environment catalog does not exist; may need to run fmadm configure");
+ }
- if (custom_group) {
- d_grp = getgrnam (d_groupname);
+ if (!file_exists (config_file)) {
+ logprintf (FM_LOG_FATAL, "freem: configuration file for %s does not exist; may need to run fmadm configure", shm_env);
+ }
- if (d_grp == NULL) {
- fprintf (stderr, "freem: invalid group '%s'\n", d_groupname);
- exit (1);
- }
-
- d_gid = d_grp->gr_gid;
- }
+ if (read_profile_string (env_config_file, shm_env, "user", d_username) == FALSE) {
+ logprintf (FM_LOG_FATAL, "freem: could not determine owning user for environment %s", shm_env);
+ }
- if (custom_user) {
- d_user = getpwnam (d_username);
+ if (read_profile_string (env_config_file, shm_env, "group", d_groupname) == FALSE) {
+ logprintf (FM_LOG_FATAL, "freem: could not determine owning group for environment %s", shm_env);
+ }
- if (d_user == NULL) {
- fprintf (stderr, "freem: invalid user '%s'\n", d_username);
- exit (1);
- }
-
- d_uid = d_user->pw_uid;
- }
- else {
- d_uid = 0;
- }
+ if (read_profile_string (env_config_file, shm_env, "enabled", env_ena) == FALSE) {
+ logprintf (FM_LOG_FATAL, "freem: could not discover enabled state for environment %s", shm_env);
+ }
+
+ if (strcmp (env_ena, "true") != 0) {
+ logprintf (FM_LOG_FATAL, "freem: environment %s is administratively disabled", shm_env);
+ }
+
+ d_grp = getgrnam (d_groupname);
+ if (d_grp == NULL) {
+ logprintf (FM_LOG_FATAL, "freem: invalid group '%s'", d_groupname);
+ }
+ d_gid = d_grp->gr_gid;
+ d_user = getpwnam (d_username);
+ if (d_user == NULL) {
+ logprintf (FM_LOG_FATAL, "freem: invalid user '%s'", d_username);
+ }
+ d_uid = d_user->pw_uid;
+
+
+#if defined(__linux__)
+ if (run_daemon == FALSE && group_member (d_gid) == 0) {
+ logprintf (FM_LOG_FATAL, "freem: you must be a member of the %s group to use environment %s", d_groupname, shm_env);
+ }
+#endif
+
+ if (run_daemon == TRUE) {
+ if (geteuid () != 0 && nofork == FALSE) {
+ logprintf (FM_LOG_FATAL, "freem: forking daemon must be run as root");
+ }
}
if ((nofork == TRUE) && (run_daemon == FALSE)) {
@@ -511,15 +538,15 @@ int main (int argc, char **argv, char **
if ((run_daemon == TRUE) && (nofork == FALSE)) {
int fork_fd;
+
+ init_log ();
/* daemonize */
fork_pid = fork ();
if (fork_pid < 0) {
- fprintf (stderr, "freem: failure in fork()\r\n");
- m_log (1, "failure in initial fork()\r\n");
- exit (1);
+ logprintf (FM_LOG_FATAL, "environment error: failure in initial fork()");
}
if (fork_pid > 0) {
@@ -527,9 +554,7 @@ int main (int argc, char **argv, char **
}
if (setsid () < 0) {
- fprintf (stderr, "freem: failure in setsid()\r\n");
- m_log (1, "failure in setsid()\r\n");
- exit (1);
+ logprintf (FM_LOG_FATAL, "environment error: failure in setsid()");
}
signal (SIGCHLD, SIG_IGN);
@@ -537,14 +562,12 @@ int main (int argc, char **argv, char **
fork_pid = fork ();
if (fork_pid < 0) {
- fprintf (stderr, "freem: failure in fork()\r\n");
- m_log (1, "failure in second fork()\r\n");
- exit (1);
+ logprintf (FM_LOG_FATAL, "environment error: failure in second fork()");
}
if (fork_pid > 0) {
+ logprintf (FM_LOG_DEBUG, "environment: exiting from second fork()");
exit (0);
- m_log (1, "exiting from second fork");
}
umask (0);
@@ -556,34 +579,28 @@ int main (int argc, char **argv, char **
}
if (geteuid () == 0) {
- /* shed privileges */
- if (custom_group) {
- fprintf (stderr, "freem: switching to group %s\n", d_groupname);
- m_log (1, "switching groups");
-
- if (setgid (d_gid) == -1) {
- fprintf (stderr, "freem: failure switching GID\n");
- m_log (1, "failure switching GIDs");
- exit (1);
- }
+ /* shed privileges */
+ logprintf (FM_LOG_INFO, "environment: switching to group %s", d_groupname);
+
+ if (setgid (d_gid) == -1) {
+ logprintf (FM_LOG_FATAL, "environment error: failure switching GID");
}
+
+
+ if (d_uid != geteuid ()) {
- if (custom_user) {
- fprintf (stderr, "freem: switching to username %s\n", d_username);
- m_log (1, "switching users");
+ logprintf (FM_LOG_INFO, "environment: switching to username %s", d_username);
if (setuid (d_uid) == -1) {
- fprintf (stderr, "freem: failure switching UID\n");
- m_log (1, "failure switching UIDs");
- exit (1);
+ logprintf (FM_LOG_FATAL, "environment error: failure switching UID");
}
}
}
else {
- fprintf (stderr, "not euid 0");
+ logprintf (FM_LOG_INFO, "environment: not running as superuser; not shedding privileges");
}
freopen ("/dev/null", "r", stdin);
@@ -606,18 +623,12 @@ int main (int argc, char **argv, char **
errsav = errno;
if (pid_fd < 0) {
- fprintf (stderr, "freem: could not open PID file %s [%s]\n", pid_file_path, strerror (errsav));
- m_log (1, "freem: could not open PID file");
- m_log (1, strerror (errsav));
- exit (1);
+ logprintf (FM_LOG_FATAL, "environment error: could not open PID file %s [%s]", pid_file_path, strerror (errsav));
}
if (lockf (pid_fd, F_TLOCK, 0) < 0) {
errsav = errno;
- fprintf (stderr, "freem: could not lock PID file [%s]\n", strerror (errsav));
- m_log (1, "freem: could not lock PID file - perhaps already running?");
- m_log (1, strerror (errsav));
- exit (1);
+ logprintf (FM_LOG_FATAL, "environment error: could not lock PID file [%s]", strerror (errsav));
}
sprintf (pidfile_buf, "%ld\n", (long) getpid ());
@@ -652,7 +663,7 @@ int main (int argc, char **argv, char **
skip_init = 1;
/* initialize FreeM environment */
- strncpy (nsnbuf, nsname, 255);
+ strncpy (nsnbuf, nsname, sizeof (nsnbuf));
if (init (nsnbuf) == FALSE) {
if (fm_initialized) set_io (UNIX);
@@ -707,20 +718,20 @@ int main (int argc, char **argv, char **
}
/* make this the startup routine */
- snprintf (startuprou, 256, "^%s\201", cli_rtn_name);
+ snprintf (startuprou, sizeof (startuprou) - 1, "^%s\201", cli_rtn_name);
/* re-work the namespace config to search for the
routine in the discovered path */
if (cli_rtn_name[0] == '%') {
- snprintf (rou0plib, 256, "%s\201", cli_rtn_path);
- snprintf (rou1plib, 256, "%s\201", cli_rtn_path);
+ snprintf (rou0plib, sizeof (rou0plib) - 1, "%s\201", cli_rtn_path);
+ snprintf (rou1plib, sizeof (rou1plib) - 1, "%s\201", cli_rtn_path);
}
else {
- snprintf (rou0path, 256, "%s\201", cli_rtn_path);
- snprintf (rou1path, 256, "%s\201", cli_rtn_path);
+ snprintf (rou0path, sizeof (rou0path) - 1, "%s\201", cli_rtn_path);
+ snprintf (rou1path, sizeof (rou1path) - 1, "%s\201", cli_rtn_path);
}
@@ -739,7 +750,7 @@ int main (int argc, char **argv, char **
if (!skip_init) {
/* initialize FreeM environment */
- strncpy (nsnbuf, nsname, 255);
+ strncpy (nsnbuf, nsname, sizeof (nsnbuf));
if (init (nsnbuf) == FALSE) {
set_io (UNIX);
fprintf (stderr, "\nError initializing FreeM.\n");
@@ -751,22 +762,27 @@ int main (int argc, char **argv, char **
}
}
+#if defined(__FreeBSD__)
+ if ((first_process == FALSE) && (procctl (P_PID, getpid (), PROC_ASLR_CTL, &prcdta) == -1)) {
+ fprintf (stderr, "freem: could not disable address space layout randomization for pid %ld; program operation may be unreliable [error %s]\n", getpid(), strerror (errno));
+ }
+#endif
+
+
if (first_process == TRUE) {
char verstr[500];
pid_t stop_requester;
if (run_daemon == FALSE) {
- fprintf (stderr, "freem: re-run with --daemon or -d command-line flags\r\n");
- cleanup ();
- exit (1);
+ logprintf (FM_LOG_FATAL, "freem: re-run with --daemon or -d command-line flags");
}
stcpy (verstr, FREEM_VERSION_STR);
stcnv_m2c (verstr);
fprintf (stderr, "Coherent Logic Development FreeM version %s\r\n", verstr);
- fprintf (stderr, "freem: shared memory for environment %s initialized (%ld bytes of shared memory @ '%p')\r\nfreem: system ready\r\n", shm_env, (long) shm_init_size, shm_config->dta);
+ logprintf (FM_LOG_INFO, "freem: shared memory for environment %s initialized (%ld bytes of shared memory @ '%p')", shm_env, (long) shm_init_size, shm_config->dta);
for (;;) {
@@ -777,8 +793,7 @@ int main (int argc, char **argv, char **
job_slot_t *slot;
- fprintf (stderr, "freem: entering maintenance mode\r\n");
- m_log (1, "freem: entering maintenance mode");
+ logprintf (FM_LOG_WARNING, "environment: entering maintenance mode");
for (slot = shm_config->hdr->jobtab_head; slot != NULL; slot = slot->next) {
@@ -797,29 +812,29 @@ int main (int argc, char **argv, char **
connected_jobs = job_count ();
- fprintf (stderr, "freem: STOP requested by pid %d\r\n", stop_requester);
- fprintf (stderr, "freem: there are %d job(s) connected to this environment\r\n", connected_jobs);
+ logprintf (FM_LOG_INFO, "environment: STOP requested by pid %ld", stop_requester);
+ logprintf (FM_LOG_INFO, "environment: there are %d job(s) connected to this environment", connected_jobs);
if (connected_jobs > 1) {
- fprintf (stderr, "freem: asking non-daemon job(s) to disconnect and halt...\r\n");
+ logprintf (FM_LOG_INFO, "environment: asking non-daemon job(s) to disconnect and halt...");
job_request_all_stop ();
- fprintf (stderr, "freem: waiting 5 seconds for job(s) to disconnect...\r\n");
+ logprintf (FM_LOG_INFO, "environment: waiting 5 seconds for job(s) to disconnect...");
sleep (5);
connected_jobs = job_count ();
- if (connected_jobs > 1) {
- fprintf (stderr, "freem: sending SIGTERM to %d job(s)...\r\n", connected_jobs);
+ if (connected_jobs > 1) {
+ logprintf (FM_LOG_INFO, "environment: sending SIGTERM to %d job(s)...", connected_jobs);
job_signal_all (SIGTERM);
- fprintf (stderr, "freem: waiting 5 seconds for job(s) to disconnect...\r\n");
+ logprintf (FM_LOG_INFO, "environment: waiting 5 seconds for job(s) to disconnect...");
sleep (5);
}
connected_jobs = job_count ();
if (connected_jobs > 1) {
- fprintf (stderr, "freem: sending SIGKILL to %d job(s)...\r\n", connected_jobs);
+ logprintf (FM_LOG_INFO, "environment: sending SIGKILL to %d job(s)...", connected_jobs);
job_signal_all (SIGKILL);
}
@@ -828,7 +843,7 @@ int main (int argc, char **argv, char **
}
- fprintf (stderr, "freem: terminating\r\n");
+ logprintf (FM_LOG_INFO, "freem: terminating");
cleanup ();
exit (0);
@@ -848,24 +863,16 @@ int main (int argc, char **argv, char **
#if !defined(_AIX)
- if(import_env == TRUE) {
-
+ if (import_env == TRUE) {
int i_maxlen = 255;
- for(env = envp; *env != 0; env++) {
-
- namelen = 0;
- vallen = 0;
-
- varname = strtok(*env, "=");
- varval = strtok(NULL, "=");
-
- if(varval != NULL) {
- namelen = strlen (varname);
- vallen = strlen (varval);
+ for (env = envp; *env != 0; env++) {
+ varname = strtok (*env, "=");
+ varval = strtok (NULL, "=");
+ if (varval != NULL) {
snprintf (symname, i_maxlen, "ENV.%s\201\201", varname);
- strncpy (symval, varval, i_maxlen);
+ strncpy (symval, varval, i_maxlen - 1);
stcnv_c2m (symval);
@@ -884,10 +891,10 @@ int main (int argc, char **argv, char **
stcpy (verstr, FREEM_VERSION_STR);
stcnv_m2c (verstr);
- snprintf (version, 255, "\r\nCoherent Logic Development FreeM version %s [DIALECT: %s%s]\r\n\201", verstr, m_dialect, (restricted_mode == TRUE ? "/RESTRICTED" : ""));
+ snprintf (version, sizeof (version) - 1, "\r\nCoherent Logic Development FreeM version %s [DIALECT: %s%s]\r\n\201", verstr, m_dialect, (restricted_mode == TRUE ? "/RESTRICTED" : ""));
write_m (version);
- snprintf (version, 255, "Copyright (C) 2014, 2020, 2021, 2023, 2025 Coherent Logic Development LLC\r\n\r\n\201");
+ snprintf (version, sizeof (version) - 1, "Copyright (C) 2014, 2020, 2021, 2023, 2025 Coherent Logic Development LLC\r\n\r\n\201");
write_m (version);
/*
@@ -904,7 +911,7 @@ int main (int argc, char **argv, char **
if (dx_mode) {
char k_buf[512];
- snprintf (k_buf, 512 - 1, "%%TMPINITMCODE\201\201");
+ snprintf (k_buf, sizeof (k_buf) - 1, "%%TMPINITMCODE\201\201");
symtab (set_sym, k_buf, dx_mcode);
const_define (k_buf, dx_mcode);
}
@@ -912,7 +919,7 @@ int main (int argc, char **argv, char **
if (routine_mode) {
char k_buf[512];
- snprintf (k_buf, 512 - 1, "%%TMPINITROUTINE\201\201");
+ snprintf (k_buf, sizeof (k_buf) - 1, "%%TMPINITROUTINE\201\201");
symtab (set_sym, k_buf, startup_routine);
const_define (k_buf, startup_routine);
}