The branch, master has been updated
via ceb9109c877 lib:replace: Implement setproctitle() based on
PRCTL_MM_MAP
via 298be05d8fe lib:replace: Remove trailing spaces
via cd3f273309b lib:replace: There is special code already to check for
HAVE_PRCTL
from f25e8ccf0d1 CVE-2025-10230: s4:wins: restrict names fed to shell
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit ceb9109c87765a28eba69b51ec726fbf70b2ba4a
Author: Andreas Schneider <[email protected]>
Date: Fri Oct 17 10:16:30 2025 +0200
lib:replace: Implement setproctitle() based on PRCTL_MM_MAP
This should work on Linux. It requires CAP_SYS_RESOURCE, but our daemons
run as root anyway.
Signed-off-by: Andreas Schneider <[email protected]>
Reviewed-by: Martin Schwenke <[email protected]>
Autobuild-User(master): Andreas Schneider <[email protected]>
Autobuild-Date(master): Wed Oct 22 08:03:35 UTC 2025 on atb-devel-224
commit 298be05d8fe850c6a7521ba53cd876351b5b7425
Author: Andreas Schneider <[email protected]>
Date: Fri Oct 17 10:18:02 2025 +0200
lib:replace: Remove trailing spaces
Signed-off-by: Andreas Schneider <[email protected]>
Reviewed-by: Martin Schwenke <[email protected]>
commit cd3f273309bbeff6c006251cdf4134f258db1119
Author: Andreas Schneider <[email protected]>
Date: Fri Oct 17 10:15:12 2025 +0200
lib:replace: There is special code already to check for HAVE_PRCTL
Signed-off-by: Andreas Schneider <[email protected]>
Reviewed-by: Martin Schwenke <[email protected]>
-----------------------------------------------------------------------
Summary of changes:
lib/replace/replace.c | 235 ++++++++++++++++++++++++++++++++++++++++++++------
lib/replace/wscript | 2 +-
2 files changed, 208 insertions(+), 29 deletions(-)
Changeset truncated at 500 lines:
diff --git a/lib/replace/replace.c b/lib/replace/replace.c
index f7f26712614..e8ff9908322 100644
--- a/lib/replace/replace.c
+++ b/lib/replace/replace.c
@@ -1,4 +1,4 @@
-/*
+/*
Unix SMB/CIFS implementation.
replacement routines for broken systems
Copyright (C) Andrew Tridgell 1992-1998
@@ -8,7 +8,7 @@
** NOTE! The following LGPL license applies to the replace
** library. This does NOT imply that all of Samba is released
** under the LGPL
-
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
@@ -37,6 +37,10 @@
#include <sys/syscall.h>
#endif
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+
#ifdef _WIN32
#define mkdir(d,m) _mkdir(d)
#endif
@@ -91,7 +95,7 @@ size_t rep_strlcpy(char *d, const char *s, size_t bufsize)
#endif
#ifndef HAVE_STRLCAT
-/* like strncat but does not 0 fill the buffer and always null
+/* like strncat but does not 0 fill the buffer and always null
terminates. bufsize is the length of the buffer, which should
be one more than the maximum resulting string length */
size_t rep_strlcat(char *d, const char *s, size_t bufsize)
@@ -116,7 +120,7 @@ size_t rep_strlcat(char *d, const char *s, size_t bufsize)
#ifndef HAVE_MKTIME
/*******************************************************************
-a mktime() replacement for those who don't have it - contributed by
+a mktime() replacement for those who don't have it - contributed by
C.A. Lademann <[email protected]>
Corrections by [email protected]
********************************************************************/
@@ -137,7 +141,7 @@ time_t rep_mktime(struct tm *t)
return((time_t)-1);
n = t->tm_year + 1900 - 1;
- epoch = (t->tm_year - 70) * YEAR +
+ epoch = (t->tm_year - 70) * YEAR +
((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY;
y = t->tm_year + 1900;
@@ -147,7 +151,7 @@ time_t rep_mktime(struct tm *t)
epoch += mon [m] * DAY;
if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
epoch += DAY;
-
+
if(++m > 11) {
m = 0;
y++;
@@ -156,7 +160,7 @@ time_t rep_mktime(struct tm *t)
epoch += (t->tm_mday - 1) * DAY;
epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
-
+
if((u = localtime(&epoch)) != NULL) {
t->tm_sec = u->tm_sec;
t->tm_min = u->tm_min;
@@ -176,7 +180,7 @@ time_t rep_mktime(struct tm *t)
#ifndef HAVE_INITGROUPS
/****************************************************************************
- some systems don't have an initgroups call
+ some systems don't have an initgroups call
****************************************************************************/
int rep_initgroups(char *name, gid_t id)
{
@@ -194,7 +198,7 @@ int rep_initgroups(char *name, gid_t id)
int i,j;
struct group *g;
char *gr;
-
+
if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) {
errno = ENOMEM;
return -1;
@@ -250,9 +254,9 @@ void *rep_memmove(void *dest,const void *src,int size)
if (d < s) {
/* we can forward copy */
- if (s-d >= sizeof(int) &&
- !(s%sizeof(int)) &&
- !(d%sizeof(int)) &&
+ if (s-d >= sizeof(int) &&
+ !(s%sizeof(int)) &&
+ !(d%sizeof(int)) &&
!(size%sizeof(int))) {
/* do it all as words */
int *idest = (int *)dest;
@@ -267,9 +271,9 @@ void *rep_memmove(void *dest,const void *src,int size)
}
} else {
/* must backward copy */
- if (d-s >= sizeof(int) &&
- !(s%sizeof(int)) &&
- !(d%sizeof(int)) &&
+ if (d-s >= sizeof(int) &&
+ !(s%sizeof(int)) &&
+ !(d%sizeof(int)) &&
!(size%sizeof(int))) {
/* do it all as words */
int *idest = (int *)dest;
@@ -281,7 +285,7 @@ void *rep_memmove(void *dest,const void *src,int size)
char *cdest = (char *)dest;
char *csrc = (char *)src;
for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
- }
+ }
}
return(dest);
}
@@ -334,16 +338,16 @@ void rep_vsyslog (int facility_priority, const char
*format, va_list arglist)
size_t rep_strnlen(const char *s, size_t max)
{
size_t len;
-
+
for (len = 0; len < max; len++) {
if (s[len] == '\0') {
break;
}
}
- return len;
+ return len;
}
#endif
-
+
#ifndef HAVE_STRNDUP
/**
Some platforms don't have strndup.
@@ -351,7 +355,7 @@ void rep_vsyslog (int facility_priority, const char
*format, va_list arglist)
char *rep_strndup(const char *s, size_t n)
{
char *ret;
-
+
n = strnlen(s, n);
ret = malloc(n+1);
if (!ret)
@@ -407,7 +411,7 @@ int rep_chroot(const char *dname)
/*****************************************************************
Possibly replace mkstemp if it is broken.
-*****************************************************************/
+*****************************************************************/
#ifndef HAVE_SECURE_MKSTEMP
int rep_mkstemp(char *template)
@@ -425,7 +429,7 @@ int rep_mkstemp(char *template)
char *rep_mkdtemp(char *template)
{
char *dname;
-
+
if ((dname = mktemp(template))) {
if (mkdir(dname, 0700) >= 0) {
return dname;
@@ -532,7 +536,7 @@ long long int rep_strtoll(const char *str, char **endptr,
int base)
{
#ifdef HAVE_STRTOQ
return strtoq(str, endptr, base);
-#elif defined(HAVE___STRTOLL)
+#elif defined(HAVE___STRTOLL)
return __strtoll(str, endptr, base);
#elif SIZEOF_LONG == SIZEOF_LONG_LONG
return (long long int) strtol(str, endptr, base);
@@ -568,7 +572,7 @@ unsigned long long int rep_strtoull(const char *str, char
**endptr, int base)
{
#ifdef HAVE_STRTOUQ
return strtouq(str, endptr, base);
-#elif defined(HAVE___STRTOULL)
+#elif defined(HAVE___STRTOULL)
return __strtoull(str, endptr, base);
#elif SIZEOF_LONG == SIZEOF_LONG_LONG
return (unsigned long long int) strtoul(str, endptr, base);
@@ -599,7 +603,7 @@ unsigned long long int rep_strtoull(const char *str, char
**endptr, int base)
#endif /* HAVE_STRTOULL */
#ifndef HAVE_SETENV
-int rep_setenv(const char *name, const char *value, int overwrite)
+int rep_setenv(const char *name, const char *value, int overwrite)
{
char *p;
size_t l1, l2;
@@ -644,10 +648,10 @@ int rep_unsetenv(const char *name)
for (i=0;environ[i];i++) /* noop */ ;
count=i;
-
+
for (i=0;i<count;) {
if (strncmp(environ[i], name, len) == 0 && environ[i][len] ==
'=') {
- /* note: we do _not_ free the old variable here. It is
unsafe to
+ /* note: we do _not_ free the old variable here. It is
unsafe to
do so, as the pointer may not have come from malloc
*/
memmove(&environ[i], &environ[i+1],
(count-i)*sizeof(char *));
count--;
@@ -688,7 +692,7 @@ int rep_utimes(const char *filename, const struct timeval
tv[2])
#endif
#ifndef HAVE_DUP2
-int rep_dup2(int oldfd, int newfd)
+int rep_dup2(int oldfd, int newfd)
{
errno = ENOSYS;
return -1;
@@ -944,8 +948,183 @@ int rep_usleep(useconds_t sec)
#ifndef HAVE_SETPROCTITLE
void rep_setproctitle(const char *fmt, ...)
{
+#if defined(HAVE_PRCTL) && defined(PR_SET_MM_MAP) && defined(__NR_brk)
+ /*
+ * Implementation based on setproctitle from lcx under LGPL-2.1+
+ * https://github.com/lxc/lxc/
+ *
+ * Using PR_SET_MM_MAP requires CAP_SYS_RESOURCE.
+ */
+ static char *proctitle = NULL;
+ char *tmp_proctitle = NULL;
+ char buf[2048] = {0};
+ char title[2048] = {0};
+ va_list ap;
+ char *ptr = NULL;
+ FILE *f = NULL;
+ size_t title_len;
+ int ret = 0;
+ struct prctl_mm_map prctl_map = {
+ .exe_fd = -1,
+ };
+ long brk_val = 0;
+ /* See `man proc_pid_stat.5` */
+ unsigned long start_code = 0; // 26
+ unsigned long end_code = 0; // 27
+ unsigned long start_stack = 0; // 28
+
+ unsigned long start_data = 0; // 45
+ unsigned long end_data = 0; // 46
+ unsigned long start_brk = 0; // 47
+ unsigned long arg_start = 0; // 48
+ unsigned long arg_end = 0; // 49
+ unsigned long env_start = 0; // 50
+ unsigned long env_end = 0; // 51
+
+ f = fopen("/proc/self/stat", "r");
+ if (f == NULL) {
+ return;
+ }
+
+ ptr = fgets(buf, sizeof(buf), f);
+ fclose(f);
+ if (ptr == NULL) {
+ return;
+ }
+
+ /*
+ * Find the last ')' to skip the comm field which can contain spaces and
+ * maybe ')'.
+ */
+ ptr = strrchr(buf, ')');
+ if (ptr == NULL || ptr[1] == '\0') {
+ return;
+ }
+ ptr += 2; // Skip ') '
+
+ /* See `man proc_pid_stat.5` */
+ ret = sscanf(
+ ptr,
+ "%*c " // 3 (state)
+ "%*d " // 4 (ppid)
+ "%*d " // 5 (pgrp)
+ "%*d " // 6 (session)
+ "%*d " // 7 (tty_nr)
+ "%*d " // 8 (tpgid)
+ "%*u " // 9 (flags)
+ "%*u " // 10 (minflt)
+ "%*u " // 11 (cminflt)
+ "%*u " // 12 (majflt)
+ "%*u " // 13 (cmajflt)
+ "%*u " // 14 (utime)
+ "%*u " // 15 (stime)
+ "%*d " // 16 (cutime)
+ "%*d " // 17 (cstime)
+ "%*d " // 18 (priority)
+ "%*d " // 19 (nice)
+ "%*d " // 20 (num_threads)
+ "%*d " // 21 (itrealvalue)
+ "%*u " // 22 (starttime)
+ "%*u " // 23 (vsize)
+ "%*d " // 24 (rss)
+ "%*u " // 25 (rsslim)
+ "%lu " // 26 (start_code)
+ "%lu " // 27 (end_code)
+ "%lu " // 28 (start_stack)
+ "%*u " // 29 (kstkesp)
+ "%*u " // 30 (kstkeip)
+ "%*u " // 31 (signal)
+ "%*u " // 32 (blocked)
+ "%*u " // 33 (sigignore)
+ "%*u " // 34 (sigcatch)
+ "%*u " // 35 (wchan)
+ "%*u " // 36 (nswap)
+ "%*u " // 37 (cnswap)
+ "%*d " // 38 (exit_signal)
+ "%*d " // 39 (processor)
+ "%*d " // 40 (rt_priority)
+ "%*u " // 41 (policy)
+ "%*u " // 42 (delayacct_blkio_ticks)
+ "%*u " // 43 (guest_time)
+ "%*d " // 44 (cguest_time)
+ "%lu " // 45 (start_data)
+ "%lu " // 46 (end_data)
+ "%lu " // 47 (start_brk)
+ "%lu " // 48 (arg_start)
+ "%lu " // 49 (arg_end)
+ "%lu " // 50 (env_start)
+ "%lu", // 51 (env_end)
+ &start_code, // 26
+ &end_code, // 27
+ &start_stack, // 28
+ &start_data, // 45
+ &end_data, // 46
+ &start_brk, // 47
+ &arg_start, // 48
+ &arg_end, // 49
+ &env_start, // 50
+ &env_end // 51
+ );
+ if (ret != 10) {
+ return;
+ }
+
+ va_start(ap, fmt);
+ ret = vsnprintf(title, sizeof(title), fmt, ap);
+ va_end(ap);
+ if (ret <= 0) {
+ return;
+ }
+ /*
+ * Include the null byte here, because in the calculations below
+ * we want to have room for it.
+ */
+ title_len = ret + 1;
+
+ /* This will leak memory */
+ tmp_proctitle = realloc(proctitle, title_len);
+ if (tmp_proctitle == NULL) {
+ return;
+ }
+ proctitle = tmp_proctitle;
+
+ arg_start = (uint64_t)proctitle;
+ arg_end = arg_start + title_len;
+
+ brk_val = syscall(__NR_brk, 0);
+ if (brk_val < 0) {
+ return;
+ }
+
+ prctl_map = (struct prctl_mm_map) {
+ .start_code = start_code,
+ .end_code = end_code,
+ .start_stack = start_stack,
+ .start_data = start_data,
+ .end_data = end_data,
+ .start_brk = start_brk,
+ .brk = brk_val,
+ .arg_start = arg_start,
+ .arg_end = arg_end,
+ .env_start = env_start,
+ .env_end = env_end,
+ .auxv = NULL,
+ .auxv_size = 0,
+ .exe_fd = -1,
+ };
+
+ ret = prctl(PR_SET_MM,
+ PR_SET_MM_MAP,
+ (long)&prctl_map,
+ sizeof(prctl_map),
+ 0);
+ if (ret == 0) {
+ strlcpy((char *)arg_start, title, title_len);
+ }
+#endif /* HAVE_PRCTL */
}
#endif
+
#ifndef HAVE_SETPROCTITLE_INIT
void rep_setproctitle_init(int argc, char *argv[], char *envp[])
{
diff --git a/lib/replace/wscript b/lib/replace/wscript
index 9c0cb7047f1..e351b5d19f2 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -439,7 +439,7 @@ def configure(conf):
msg='Checking for posix_fallocate-capable libc'):
conf.CHECK_FUNCS('posix_fallocate')
- conf.CHECK_FUNCS('prctl dirname basename')
+ conf.CHECK_FUNCS('dirname basename')
strlcpy_in_bsd = False
--
Samba Shared Repository