Compare commits

...

No commits in common. "c8s" and "c9s" have entirely different histories.
c8s ... c9s

18 changed files with 510 additions and 474 deletions

8
.gitignore vendored
View File

@ -1,2 +1,8 @@
SOURCES/cronie-1.5.2.tar.gz
/cronie-1.5.0.tar.gz
/cronie-1.5.1.tar.gz
/cronie-1.5.2.tar.gz
/cronie-1.5.3.tar.gz
/cronie-1.5.4.tar.gz
/cronie-1.5.5.tar.gz
/cronie-1.5.6.tar.gz
/cronie-1.5.7.tar.gz

View File

@ -0,0 +1,114 @@
From 09afe49c73cb495f32b96dce32728352c46ba865 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Stan=C4=9Bk?= <jstanek@redhat.com>
Date: Thu, 29 Apr 2021 16:03:05 +0200
Subject: [PATCH] Address issues found by coverity scan
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Jan Staněk <jstanek@redhat.com>
---
anacron/main.c | 8 ++++++--
anacron/runjob.c | 2 ++
src/crontab.c | 1 +
src/database.c | 3 ++-
src/pw_dup.c | 1 +
5 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/anacron/main.c b/anacron/main.c
index d092970..65f8fed 100644
--- a/anacron/main.c
+++ b/anacron/main.c
@@ -44,8 +44,8 @@ int day_now;
int year, month, day_of_month; /* date anacron started */
char *program_name;
-char *anacrontab;
-char *spooldir;
+char *anacrontab = NULL;
+char *spooldir = NULL;
int serialize, force, update_only, now,
no_daemon, quiet, testing_only; /* command-line options */
char **job_args; /* vector of "job" command-line arguments */
@@ -128,12 +128,14 @@ parse_opts(int argc, char *argv[])
quiet = 1;
break;
case 't':
+ free(anacrontab);
anacrontab = strdup(optarg);
break;
case 'T':
testing_only = 1;
break;
case 'S':
+ free(spooldir);
spooldir = strdup(optarg);
break;
case 'V':
@@ -208,9 +210,11 @@ go_background(void)
/* stdin is already closed */
if (fclose(stdout)) die_e("Can't close stdout");
+ /* coverity[leaked_handle] fd 1 closed automatically */
xopen(1, "/dev/null", O_WRONLY);
if (fclose(stderr)) die_e("Can't close stderr");
+ /* coverity[leaked_handle] fd 2 closed automatically */
xopen(2, "/dev/null", O_WRONLY);
pid = xfork();
diff --git a/anacron/runjob.c b/anacron/runjob.c
index 341351f..04d6904 100644
--- a/anacron/runjob.c
+++ b/anacron/runjob.c
@@ -237,7 +237,9 @@ launch_mailer(job_rec *jr)
xcloselog();
/* Ensure stdout/stderr are sane before exec-ing sendmail */
+ /* coverity[leaked_handle] STDOUT closed automatically */
xclose(STDOUT_FILENO); xopen(STDOUT_FILENO, "/dev/null", O_WRONLY);
+ /* coverity[leaked_handle] STDERR closed automatically */
xclose(STDERR_FILENO); xopen(STDERR_FILENO, "/dev/null", O_WRONLY);
xclose(jr->output_fd);
diff --git a/src/crontab.c b/src/crontab.c
index 240c112..41c8984 100644
--- a/src/crontab.c
+++ b/src/crontab.c
@@ -872,6 +872,7 @@ static int replace_cmd(void) {
if ((error = check_syntax(tmp)) < 0) {
fprintf(stderr, "Invalid crontab file, can't install.\n");
+ fclose(tmp);
goto done;
}
diff --git a/src/database.c b/src/database.c
index c1e4593..bff0256 100644
--- a/src/database.c
+++ b/src/database.c
@@ -559,7 +559,8 @@ int load_database(cron_db * old_db) {
if (not_a_crontab(dp))
continue;
- strncpy(fname, dp->d_name, NAME_MAX + 1);
+ strncpy(fname, dp->d_name, NAME_MAX);
+ fname[NAME_MAX] = '\0';
if (!glue_strings(tabname, sizeof tabname, SPOOL_DIR, fname, '/'))
continue; /* XXX log? */
diff --git a/src/pw_dup.c b/src/pw_dup.c
index ea787cd..c6f7b00 100644
--- a/src/pw_dup.c
+++ b/src/pw_dup.c
@@ -121,6 +121,7 @@ pw_dup(const struct passwd *pw) {
cp += ssize;
}
+ /* cppcheck-suppress[memleak symbolName=cp] memory originally pointed to by cp returned via newpw */
return (newpw);
}
--
2.31.1

View File

@ -1,8 +1,8 @@
From 0f1704a0f8c5fd2a4da6f530694bdd93a7ca3226 Mon Sep 17 00:00:00 2001
From 8c3f71bbe109f5df8280eeaa2152dabc4f48474a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Poho=C5=99elsk=C3=BD?=
<35430604+opohorel@users.noreply.github.com>
Date: Mon, 8 Nov 2021 16:20:09 +0100
Subject: [PATCH] Add random within range '~' operator
Subject: [PATCH 2/5] Add random within range '~' operator
With the operator one can specify for a job a random time or date within
a specified range for a field.
@ -10,14 +10,14 @@ The random value is generated when the crontab where the job is
specified, is loaded.
---
man/crontab.5 | 9 ++
src/entry.c | 262 ++++++++++++++++++++++++++++++++------------------
2 files changed, 176 insertions(+), 95 deletions(-)
src/entry.c | 267 +++++++++++++++++++++++++++++++-------------------
2 files changed, 175 insertions(+), 101 deletions(-)
diff --git a/man/crontab.5 b/man/crontab.5
index a011c89..ba8f0c3 100644
index 04358cb..5d89862 100644
--- a/man/crontab.5
+++ b/man/crontab.5
@@ -199,6 +199,15 @@ hyphen. The specified range is inclusive. For example, 8-11 for
@@ -205,6 +205,15 @@ hyphen. The specified range is inclusive. For example, 8-11 for
an 'hours' entry specifies execution at hours 8, 9, 10, and 11. The first
number must be less than or equal to the second one.
.PP
@ -34,7 +34,7 @@ index a011c89..ba8f0c3 100644
commas. Examples: "1,2,5,9", "0-4,8-12".
.PP
diff --git a/src/entry.c b/src/entry.c
index 92b55f5..9276f47 100644
index 36e639e..f2bb717 100644
--- a/src/entry.c
+++ b/src/entry.c
@@ -62,9 +62,22 @@ static const char *ecodes[] = {
@ -62,7 +62,7 @@ index 92b55f5..9276f47 100644
set_element(bitstr_t *, int, int, int);
void free_entry(entry * e) {
@@ -449,11 +462,14 @@ get_list(bitstr_t * bits, int low, int high, const char *names[],
@@ -467,11 +480,14 @@ get_list(bitstr_t * bits, int low, int high, const char *names[],
/* process all ranges
*/
done = FALSE;
@ -79,7 +79,7 @@ index 92b55f5..9276f47 100644
else
done = TRUE;
}
@@ -468,137 +484,193 @@ get_list(bitstr_t * bits, int low, int high, const char *names[],
@@ -486,144 +502,193 @@ get_list(bitstr_t * bits, int low, int high, const char *names[],
return (ch);
}
@ -146,7 +146,7 @@ index 92b55f5..9276f47 100644
+ }
+ return (EOF);
- if (ch == '*') {
- if (ch == '*') {
- /* '*' means "first-last" but can still be modified by /step
- */
- num1 = low;
@ -247,6 +247,7 @@ index 92b55f5..9276f47 100644
- /* no step. default==1.
- */
- num3 = 1;
- }
+ case R_RANDOM:
+ if (is_separator(ch)) {
+ num2 = high;
@ -260,7 +261,12 @@ index 92b55f5..9276f47 100644
+ */
+ else
+ return (EOF);
+
- /* num1 (through i) will be validated by set_element() below, but num2
- * and num3 are merely used as loop condition and increment, and must
- * be validated separately.
- */
- if (num2 < low || num2 > high || num3 > high)
+ /* if invalid random range was selected */
+ if (num1 > num2)
+ return (EOF);
@ -276,9 +282,9 @@ index 92b55f5..9276f47 100644
+ */
+ return (EOF);
+ }
}
+ }
+ if (state != R_FINISH || ch == EOF)
+ return (EOF);
return (EOF);
- /* range. set all elements from num1 to num2, stepping
- * by num3. (the step is a downward-compatible extension
@ -348,7 +354,7 @@ index 92b55f5..9276f47 100644
- for (i = 0; names[i] != NULL; i++) {
- Debug(DPARS | DEXT,
- ("get_num, compare(%s,%s)\n", names[i], temp));
- if (!strcasecmp(names[i], temp)) {
- if (!strcasecmp(names[i], temp)) {
- *numptr = i + low;
- return (ch);
- }
@ -365,5 +371,5 @@ index 92b55f5..9276f47 100644
bad:
--
2.35.1
2.36.1

View File

@ -1,7 +1,7 @@
From 07bf4b9037de19b580cfa24f5ad023b56725b285 Mon Sep 17 00:00:00 2001
From 0589b06aa369efd3cd5dfc0bba9a868f48a14506 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tmraz@fedoraproject.org>
Date: Wed, 5 Jan 2022 19:17:18 +0100
Subject: [PATCH 2/4] get_number: Add missing NUL termination for the scanned
Subject: [PATCH 3/5] get_number: Add missing NUL termination for the scanned
string
---
@ -21,5 +21,5 @@ index f2bb717..15ce9b5 100644
goto bad;
--
2.35.1
2.36.1

View File

@ -1,7 +1,7 @@
From 299ef06ea4371afa97301cec64dc8f21c4f7b11b Mon Sep 17 00:00:00 2001
From 991a5f2a44c68f576b6c6da3a7ac8fbc8f97a3b0 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tmraz@fedoraproject.org>
Date: Tue, 22 Mar 2022 14:35:48 +0100
Subject: [PATCH 3/4] Fix regression in handling */x crontab entries
Subject: [PATCH 4/5] Fix regression in handling */x crontab entries
Fixes #102
---
@ -24,5 +24,5 @@ index 15ce9b5..e9e258b 100644
break;
}
--
2.35.1
2.36.1

View File

@ -1,7 +1,7 @@
From 62e53f1cdb9c1e12a01ee7814c92cd937d50328d Mon Sep 17 00:00:00 2001
From d1a4e2b1a091df104881a6dcd0e41d805c86cb1a Mon Sep 17 00:00:00 2001
From: w30023233 <wangyuhang27@huawei.com>
Date: Wed, 23 Mar 2022 15:40:01 +0800
Subject: [PATCH 4/4] Fix regression in handling 1-5 crontab entries
Subject: [PATCH 5/5] Fix regression in handling 1-5 crontab entries
---
src/entry.c | 1 +
@ -20,5 +20,5 @@ index e9e258b..bb7cb62 100644
state = R_RANGE_NUM2;
break;
--
2.35.1
2.36.1

View File

@ -1,41 +0,0 @@
From 1f866530f5b3c49012c61b299f3c4e1dceff2a71 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tmraz@fedoraproject.org>
Date: Thu, 18 Oct 2018 14:25:58 +0200
Subject: [PATCH] Use the role from the crond context for system job contexts.
New SELinux policy added multiple roles for the system_u user on crond_t.
The default context returned from get_default_context_with_level() is now
unconfined_t instead of system_cronjob_t which is incorrect for system cron
jobs.
We use the role to limit the default context to system_cronjob_t.
---
src/security.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/security.c b/src/security.c
index d1bdc7f..5213cf3 100644
--- a/src/security.c
+++ b/src/security.c
@@ -505,6 +505,7 @@ get_security_context(const char *name, int crontab_fd,
retval = get_default_context_with_level(seuser, level, NULL, &scontext);
}
else {
+ const char *current_user, *current_role;
if (getcon(&current_context_str) < 0) {
log_it(name, getpid(), "getcon FAILED", "", 0);
return (security_getenforce() > 0);
@@ -517,8 +518,9 @@ get_security_context(const char *name, int crontab_fd,
return (security_getenforce() > 0);
}
- const char *current_user = context_user_get(current_context);
- retval = get_default_context_with_level(current_user, level, NULL, &scontext);
+ current_user = context_user_get(current_context);
+ current_role = context_role_get(current_context);
+ retval = get_default_context_with_rolelevel(current_user, current_role, level, NULL, &scontext);
freecon(current_context_str);
context_free(current_context);
--
2.14.5

View File

@ -1,26 +0,0 @@
From 0570c2cd979bc9ce1da6a873089e89dbca900a1f Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tmraz@fedoraproject.org>
Date: Tue, 7 May 2019 14:45:53 +0200
Subject: [PATCH] Revert "Avoid creating pid files when crond doesn't fork"
This reverts commit 5b285b46b88dc63689c6a56542cb2ba81f861b66.
The PID file is useful to avoid running multiple crond instances
at once.
---
src/misc.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/misc.c b/src/misc.c
index 42153b8..faf6ffb 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -315,9 +315,6 @@ void acquire_daemonlock(int closeflag) {
return;
}
- if (NoFork == 1)
- return; //move along, nothing to do here...
-
if (fd == -1) {
pidfile = _PATH_CRON_PID;
/* Initial mode is 0600 to prevent flock() race/DoS. */

View File

@ -1,13 +0,0 @@
diff -ru cronie-1.5.2/contrib/cronie.systemd cronie-1.5.2_patched/contrib/cronie.systemd
--- cronie-1.5.2/contrib/cronie.systemd 2018-11-27 15:26:46.797288342 +0100
+++ cronie-1.5.2_patched/contrib/cronie.systemd 2018-11-27 15:26:19.479159225 +0100
@@ -7,6 +7,8 @@
ExecStart=/usr/sbin/crond -n $CRONDARGS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
+Restart=on-failure
+RestartSec=30s
[Install]
WantedBy=multi-user.target

View File

@ -1,26 +0,0 @@
From 978a00ea7ac92852c153ebb3b2152886730ca51c Mon Sep 17 00:00:00 2001
From: Marcel Plch <mplch@redhat.com>
Date: Fri, 7 Dec 2018 15:01:19 +0100
Subject: [PATCH] Use system-auth instead of password-auth for PAM
authentication (#25)
---
pam/crond | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/pam/crond b/pam/crond
index 91964aa..560529d 100644
--- a/pam/crond
+++ b/pam/crond
@@ -4,8 +4,8 @@
#
# Although no PAM authentication is called, auth modules
# are used for credential setting
-auth include password-auth
+auth include system-auth
account required pam_access.so
-account include password-auth
+account include system-auth
session required pam_loginuid.so
-session include password-auth
+session include system-auth

View File

@ -5,13 +5,28 @@
Summary: Cron daemon for executing programs at set times
Name: cronie
Version: 1.5.2
Release: 10%{?dist}
Version: 1.5.7
Release: 12%{?dist}
License: MIT and BSD and ISC and GPLv2+
Group: System Environment/Base
URL: https://github.com/cronie-crond/cronie
Source0: https://github.com/cronie-crond/cronie/releases/download/cronie-%{version}/cronie-%{version}.tar.gz
Patch: 0001-Address-issues-found-by-coverity-scan.patch
# Add support for "~" ("random within range") + regression fixing patches (rhbz#2090691)
Patch: 0002-Add-random-within-range-operator.patch
Patch: 0003-get_number-Add-missing-NUL-termination-for-the-scann.patch
Patch: 0004-Fix-regression-in-handling-x-crontab-entries.patch
Patch: 0005-Fix-regression-in-handling-1-5-crontab-entries.patch
# Add support for `-n` option in crontab entries
# https://github.com/cronie-crond/cronie/commit/ce7d5bf0a43d147f8502e6424cd523b56adf5599
Patch: n_option.patch
# Optimization to close fds from /proc/self/fd in case of high nofile limit after fork
# https://github.com/cronie-crond/cronie/commit/e3682c7135b9176b60d226c60ee4e78cf1ab711b
Patch: optimization_to_close_fds.patch
# Increase the maximum number of crontab entries
# https://github.com/cronie-crond/cronie/pull/92/commits/36bb94cceda71c83ca01be22a959d8bf3e59b37b
Patch: increase_max_crontabs.patch
Requires: dailyjobs
%if %{with selinux}
@ -28,34 +43,17 @@ Buildrequires: audit-libs-devel >= 1.4.1
BuildRequires: gcc
BuildRequires: systemd
BuildRequires: make
Obsoletes: %{name}-sysvinit
Requires(post): coreutils sed
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
Requires(post): systemd
# Some parts of code could result in a memory leak.
Patch0: fix-memory-leaks.patch
# Some parts of code could result in undefined behavior.
Patch1: fix-unsafe-code.patch
# Use correct selinux role
Patch2: cronie-1.5.2-context-role.patch
# Make systemd restart crond when it fails.
Patch3: cronie-1.5.2-restart-on-failure.patch
# Revert "Avoid creating pid files when crond doesn't fork"
Patch4: cronie-1.5.2-create-pid-files.patch
# Use system-auth in PAM (rhbz#2005526)
Patch5: cronie-1.5.2-use-pam-system-auth.patch
# Add support for "~" ("random within range") + regression fixing patches (rhbz#1832510)
Patch6: 0001-Add-random-within-range-operator.patch
Patch7: 0002-get_number-Add-missing-NUL-termination-for-the-scann.patch
Patch8: 0003-Fix-regression-in-handling-x-crontab-entries.patch
Patch9: 0004-Fix-regression-in-handling-1-5-crontab-entries.patch
# Optimization to close fds from /proc/self/fd in case of high nofile limit after fork
# https://github.com/cronie-crond/cronie/commit/e3682c7135b9176b60d226c60ee4e78cf1ab711b
Patch10: optimization_to_close_fds.patch
%if 0%{?fedora} && 0%{?fedora} < 28 || 0%{?rhel} && 0%{?rhel} < 8
%{?systemd_requires}
%else
%{?systemd_ordering} # does not exist on Fedora27/RHEL7
%endif
%description
Cronie contains the standard UNIX daemon crond that runs specified programs at
@ -66,7 +64,6 @@ SELinux.
%package anacron
Summary: Utility for running regular jobs
Requires: crontabs
Group: System Environment/Base
Provides: dailyjobs
Provides: anacron = 2.4
Obsoletes: anacron <= 2.3
@ -86,7 +83,6 @@ for better utilization of resources shared among multiple systems.
%package noanacron
Summary: Utility for running simple regular jobs in old cron style
Group: System Environment/Base
Provides: dailyjobs
Requires: crontabs
Requires: %{name} = %{version}-%{release}
@ -96,19 +92,7 @@ Old style of running {hourly,daily,weekly,monthly}.jobs without anacron. No
extra features.
%prep
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%autosetup -p1
%build
%configure \
@ -128,10 +112,10 @@ extra features.
--enable-pie \
--enable-relro
make %{?_smp_mflags} V=2
%make_build V=2
%install
make install DESTDIR=$RPM_BUILD_ROOT DESTMAN=$RPM_BUILD_ROOT%{_mandir}
%make_install DESTMAN=$RPM_BUILD_ROOT%{_mandir}
mkdir -pm700 $RPM_BUILD_ROOT%{_localstatedir}/spool/cron
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/
mkdir -pm755 $RPM_BUILD_ROOT%{_sysconfdir}/cron.d/
@ -153,8 +137,7 @@ touch $RPM_BUILD_ROOT/var/spool/anacron/cron.monthly
install -m 644 contrib/dailyjobs $RPM_BUILD_ROOT/%{_sysconfdir}/cron.d/dailyjobs
# install systemd initscript
mkdir -p $RPM_BUILD_ROOT/lib/systemd/system/
install -m 644 contrib/cronie.systemd $RPM_BUILD_ROOT/lib/systemd/system/crond.service
install -m 644 -D contrib/cronie.systemd $RPM_BUILD_ROOT/usr/lib/systemd/system/crond.service
%post
# run after an installation
@ -220,7 +203,7 @@ exit 0
%config(noreplace) %{_sysconfdir}/sysconfig/crond
%config(noreplace,missingok) %{_sysconfdir}/cron.deny
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/cron.d/0hourly
%attr(0644,root,root) /lib/systemd/system/crond.service
%attr(0644,root,root) /usr/lib/systemd/system/crond.service
%files anacron
%{_sbindir}/anacron
@ -237,42 +220,90 @@ exit 0
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/cron.d/dailyjobs
%changelog
* Thu Nov 30 2023 Ondřej Pohořelský <opohorel@redhat.com> - 1.5.2-10
- Bump release because of CI issues
- Related: RHEL-2609
* Thu Sep 26 2024 Ondřej Pohořelský <opohorel@redhat.com> - 1.5.7-12
- Add `increase_max_crontabs.patch`
- Resolves: RHEL-60279
* Thu Nov 30 2023 Ondřej Pohořelský <opohorel@redhat.com> - 1.5.2-9
* Thu Nov 30 2023 Ondřej Pohořelský <opohorel@redhat.com> - 1.5.7-11
- Add `optimization_to_close_fds.patch`
- Resolves: RHEL-2609
- Resolves: RHEL-17710
* Mon Jul 11 2022 Jan Staněk <jstanek@redhat.com> - 1.5.2-8
* Thu Nov 16 2023 Jan Houška <jhouska@redhat.com> - 1.5.7-10
- Related: RHEL-5372
- remove obsolete tests.
- Correct gating.yaml for CI.
* Fri Nov 10 2023 Ondřej Pohořelský <opohorel@redhat.com> - 1.5.7-9
- Add support for `-n` option in crontab entries
- Resolves: RHEL-5372
* Mon Jul 11 2022 Jan Staněk <jstanek@redhat.com> - 1.5.7-8
- Set 'missingok' for /etc/cron.deny to not recreate it on update
* Mon May 02 2022 Ondřej Pohořelský <opohorel@redhat.com> - 1.5.2-7
- Add support for "~" ("random within range")
Resolves: rhbz#1832510
* Tue May 31 2022 Ondřej Pohořelský <opohorel@redhat.com> - 1.5.7-7
- Add gating.yaml
Related: rhbz#2090691
* Mon Sep 20 2021 Jan Staněk <jstanek@redhat.com> - 1.5.2-6
- Use system-auth for PAM authentication
Resolves: rhbz#2005526
* Fri May 27 2022 Ondřej Pohořelský <opohorel@redhat.com> - 1.5.7-6
- Add support for "~" ("random within range")
Resolves: rhbz#2090691
* Fri Sep 03 2021 Jan Staněk <jstanek@redhat.com> - 1.5.2-5
- Create PID files even when crond does not fork
Resolves: rhbz#1926300
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 1.5.7-5
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Wed Jun 12 2019 Marcel Plch <mplch@redhat.com> - 1.5.2-4
- Make crond restart on failure
- Resolves: rhbz#1715137
* Wed May 12 2021 Jan Staněk <jstanek@redhat.com> - 1.5.7-4
- Install crond.service into /usr/lib
* Mon May 20 2019 Marcel Plch <mplch@redhat.com> - 1.5.2-3
- use role from the current context for system crontabs
- Resolves: rhbz#1708557
* Fri Apr 30 2021 Jan Staněk <jstanek@redhat.com> - 1.5.7-3
- Address issues found by static scanners
* Fri Sep 07 2018 Marcel Plch <mplch@redhat.com> - 1.5.2-2
- Covscan issues review
- Fix potential memory leaks
- Fix unsafe code
- Resolves: rhbz#1602467
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 1.5.7-2
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Mon Mar 29 2021 Tomáš Mráz <tmraz@fedoraproject.org> - 1.5.7-1
- new upstream release 1.5.7 with bug fixes and enhancements
* Wed Mar 17 2021 Tomáš Mráz <tmraz@fedoraproject.org> - 1.5.6-1
- new upstream release 1.5.6 with bug fixes and enhancements
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.5.5-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.5.5-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Mon Jul 13 2020 Tom Stellard <tstellar@redhat.com> - 1.5.5-3
- Use make macros
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.5.5-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Thu Oct 31 2019 Tomáš Mráz <tmraz@redhat.com> - 1.5.5-1
- new upstream release 1.5.5 with multiple bug fixes and improvements
* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.5.4-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Mon Mar 18 2019 Tomáš Mráz <tmraz@redhat.com> - 1.5.4-1
- new upstream release 1.5.4 with regression fix
* Fri Mar 15 2019 Tomáš Mráz <tmraz@redhat.com> - 1.5.3-1
- new upstream release 1.5.3 fixing CVE-2019-9704 and CVE-2019-9705
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.5.2-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Fri Nov 30 2018 Tomáš Mráz <tmraz@redhat.com> - 1.5.2-4
- Do not hard-require systemd as crond is used in containers without
systemd (#1654659)
* Wed Oct 31 2018 Tomáš Mráz <tmraz@redhat.com> - 1.5.2-3
- use role from the current context for system crontabs (#1639381)
* Thu Jul 12 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.5.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Thu May 3 2018 Tomáš Mráz <tmraz@redhat.com> - 1.5.2-1
- new upstream release 1.5.2

View File

@ -1,140 +0,0 @@
diff -ru cronie-1.5.2/anacron/readtab.c cronie-1.5.2_patched/anacron/readtab.c
--- cronie-1.5.2/anacron/readtab.c 2017-09-14 13:53:21.000000000 +0200
+++ cronie-1.5.2_patched/anacron/readtab.c 2018-09-07 15:13:17.752498050 +0200
@@ -134,8 +134,19 @@
var_len = (int)strlen(env_var);
val_len = (int)strlen(value);
+ if (!var_len) {
+ return;
+ }
+
er = obstack_alloc(&tab_o, sizeof(env_rec));
+ if (er == NULL) {
+ die_e("Cannot allocate memory.");
+ }
+
er->assign = obstack_alloc(&tab_o, var_len + 1 + val_len + 1);
+ if (er->assign == NULL) {
+ die_e("Cannot allocate memory.");
+ }
strcpy(er->assign, env_var);
er->assign[var_len] = '=';
strcpy(er->assign + var_len + 1, value);
@@ -167,15 +178,24 @@
return;
}
jr = obstack_alloc(&tab_o, sizeof(job_rec));
+ if (jr == NULL) {
+ die_e("Cannot allocate memory.");
+ }
jr->period = period;
jr->named_period = 0;
delay += random_number;
jr->delay = delay;
jr->tab_line = line_num;
jr->ident = obstack_alloc(&tab_o, ident_len + 1);
+ if (jr->ident == NULL) {
+ die_e("Cannot allocate memory.");
+ }
strcpy(jr->ident, ident);
jr->arg_num = job_arg_num(ident);
jr->command = obstack_alloc(&tab_o, command_len + 1);
+ if (jr->command == NULL) {
+ die_e("Cannot allocate memory.");
+ }
strcpy(jr->command, command);
jr->job_pid = jr->mailer_pid = 0;
if (last_job_rec != NULL) last_job_rec->next = jr;
@@ -208,6 +228,9 @@
}
jr = obstack_alloc(&tab_o, sizeof(job_rec));
+ if (jr == NULL) {
+ die_e("Cannot allocate memory.");
+ }
if (!strncmp ("@monthly", periods, 8)) {
jr->named_period = 1;
} else if (!strncmp("@yearly", periods, 7) || !strncmp("@annually", periods, 9) || !strncmp(/* backwards compat misspelling */"@annualy", periods, 8)) {
@@ -225,9 +248,15 @@
jr->delay = delay;
jr->tab_line = line_num;
jr->ident = obstack_alloc(&tab_o, ident_len + 1);
+ if (jr->ident == NULL) {
+ die_e("Cannot allocate memory.");
+ }
strcpy(jr->ident, ident);
jr->arg_num = job_arg_num(ident);
jr->command = obstack_alloc(&tab_o, command_len + 1);
+ if (jr->command == NULL) {
+ die_e("Cannot allocate memory.");
+ }
strcpy(jr->command, command);
jr->job_pid = jr->mailer_pid = 0;
if (last_job_rec != NULL) last_job_rec->next = jr;
diff -ru cronie-1.5.2/anacron/runjob.c cronie-1.5.2_patched/anacron/runjob.c
--- cronie-1.5.2/anacron/runjob.c 2018-01-24 17:02:33.000000000 +0100
+++ cronie-1.5.2_patched/anacron/runjob.c 2018-09-07 15:13:17.752498050 +0200
@@ -104,9 +104,44 @@
static void
xputenv(const char *s)
{
- char *copy = strdup (s);
- if (!copy) die_e("Not enough memory to set the environment");
- if (putenv(copy)) die_e("Can't set the environment");
+ char *name = NULL, *val = NULL;
+ char *eq_ptr;
+ const char *errmsg;
+ size_t eq_index;
+
+ if (s == NULL) {
+ die_e("Invalid environment string");
+ }
+
+ eq_ptr = strchr(s, '=');
+ if (eq_ptr == NULL) {
+ die_e("Invalid environment string");
+ }
+
+ eq_index = (size_t) (eq_ptr - s);
+
+ name = malloc((eq_index + 1) * sizeof(char));
+ if (name == NULL) {
+ die_e("Not enough memory to set the environment");
+ }
+
+ val = malloc((strlen(s) - eq_index) * sizeof(char));
+ if (val == NULL) {
+ die_e("Not enough memory to set the environment");
+ }
+
+ strncpy(name, s, eq_index);
+ name[eq_index] = '\0';
+ strcpy(val, s + eq_index + 1);
+
+ if (setenv(name, val, 1)) {
+ die_e("Can't set the environment");
+ }
+
+ free(name);
+ free(val);
+ return;
+
}
static void
diff -ru cronie-1.5.2/src/entry.c cronie-1.5.2_patched/src/entry.c
--- cronie-1.5.2/src/entry.c 2017-09-14 13:53:21.000000000 +0200
+++ cronie-1.5.2_patched/src/entry.c 2018-09-07 15:13:17.752498050 +0200
@@ -131,8 +131,10 @@
goto eof;
}
ch = get_char(file);
- if (ch == EOF)
+ if (ch == EOF) {
+ free(e);
return NULL;
+ }
}
if (ch == '@') {

View File

@ -1,117 +0,0 @@
diff -ru cronie-1.5.2/src/cronnext.c cronie-1.5.2_patched/src/cronnext.c
--- cronie-1.5.2/src/cronnext.c 2018-05-03 18:41:12.000000000 +0200
+++ cronie-1.5.2_patched/src/cronnext.c 2018-09-07 15:17:54.555924440 +0200
@@ -71,13 +71,13 @@
/*
* print entry flags
*/
-char *flagname[]= {
- [MIN_STAR] = "MIN_STAR",
- [HR_STAR] = "HR_STAR",
- [DOM_STAR] = "DOM_STAR",
- [DOW_STAR] = "DOW_STAR",
- [WHEN_REBOOT] = "WHEN_REBOOT",
- [DONT_LOG] = "DONT_LOG"
+const char *flagname[]= {
+ "MIN_STAR",
+ "HR_STAR",
+ "DOM_STAR",
+ "DOW_STAR",
+ "WHEN_REBOOT",
+ "DONT_LOG"
};
void printflags(char *indent, int flags) {
@@ -85,8 +85,8 @@
int first = 1;
printf("%s flagnames:", indent);
- for (f = 1; f < sizeof(flagname); f = f << 1)
- if (flags & f) {
+ for (f = 0; f < sizeof(flagname)/sizeof(char *); f++)
+ if (flags & (int)1 << f) {
printf("%s%s", first ? " " : "|", flagname[f]);
first = 0;
}
diff -ru cronie-1.5.2/src/do_command.c cronie-1.5.2_patched/src/do_command.c
--- cronie-1.5.2/src/do_command.c 2017-09-14 13:53:21.000000000 +0200
+++ cronie-1.5.2_patched/src/do_command.c 2018-09-07 15:17:54.555924440 +0200
@@ -418,7 +418,7 @@
if (mailto && safe_p(usernm, mailto)
&& strncmp(MailCmd,"off",3) && !SyslogOutput) {
char **env;
- char mailcmd[MAX_COMMAND];
+ char mailcmd[MAX_COMMAND+1]; /* +1 for terminator */
char hostname[MAXHOSTNAMELEN];
char *content_type = env_get("CONTENT_TYPE", jobenv),
*content_transfer_encoding =
@@ -434,7 +434,7 @@
}
}
else {
- strncpy(mailcmd, MailCmd, MAX_COMMAND);
+ strncpy(mailcmd, MailCmd, MAX_COMMAND+1);
}
if (!(mail = cron_popen(mailcmd, "w", e->pwd, jobenv))) {
perror(mailcmd);
diff -ru cronie-1.5.2/src/env.c cronie-1.5.2_patched/src/env.c
--- cronie-1.5.2/src/env.c 2017-09-14 13:53:21.000000000 +0200
+++ cronie-1.5.2_patched/src/env.c 2018-09-07 15:17:54.554924435 +0200
@@ -63,7 +63,7 @@
for (i = 0; i < count; i++)
if ((p[i] = strdup(envp[i])) == NULL) {
save_errno = errno;
- while (--i >= 0)
+ while (i-- > 0)
free(p[i]);
free(p);
errno = save_errno;
@@ -263,7 +263,9 @@
}
if (state != FINI && state != EQ2 && !(state == VALUE && !quotechar)) {
Debug(DPARS, ("load_env, not an env var, state = %d\n", state));
- fseek(f, filepos, 0);
+ if (fseek(f, filepos, 0)) {
+ return ERR;
+ }
Set_LineNum(fileline);
return (FALSE);
}
diff -ru cronie-1.5.2/src/globals.h cronie-1.5.2_patched/src/globals.h
--- cronie-1.5.2/src/globals.h 2017-01-17 16:53:50.000000000 +0100
+++ cronie-1.5.2_patched/src/globals.h 2018-09-07 15:17:54.555924440 +0200
@@ -77,7 +77,7 @@
XTRN time_t StartTime;
XTRN int NoFork;
XTRN int PermitAnyCrontab;
-XTRN char MailCmd[MAX_COMMAND];
+XTRN char MailCmd[MAX_COMMAND+1]; /* +1 for terminator */
XTRN char cron_default_mail_charset[MAX_ENVSTR];
XTRN int EnableClustering;
XTRN int ChangePath;
diff -ru cronie-1.5.2/src/security.c cronie-1.5.2_patched/src/security.c
--- cronie-1.5.2/src/security.c 2017-09-14 13:29:47.000000000 +0200
+++ cronie-1.5.2_patched/src/security.c 2018-09-07 15:17:54.554924435 +0200
@@ -417,7 +417,7 @@
}
}
- if (strcmp(u->scontext, ucontext)) {
+ if (!ucontext || strcmp(u->scontext, ucontext)) {
if (!cron_authorize_range(u->scontext, ucontext)) {
if (security_getenforce() > 0) {
# ifdef WITH_AUDIT
diff -ru cronie-1.5.2/src/user.c cronie-1.5.2_patched/src/user.c
--- cronie-1.5.2/src/user.c 2017-01-17 16:53:50.000000000 +0100
+++ cronie-1.5.2_patched/src/user.c 2018-09-07 15:17:54.555924440 +0200
@@ -44,6 +44,10 @@
free_user (user * u) {
entry *e, *ne;
+ if (!u) {
+ return;
+ }
+
free(u->name);
free(u->tabname);
for (e = u->crontab; e != NULL; e = ne) {

View File

@ -1,6 +1,6 @@
--- !Policy
product_versions:
- rhel-8
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier1.functional}
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}

View File

@ -0,0 +1,25 @@
From 36bb94cceda71c83ca01be22a959d8bf3e59b37b Mon Sep 17 00:00:00 2001
From: Danilo Spinella <danilo.spinella@suse.com>
Date: Tue, 13 Jul 2021 17:08:36 +0200
Subject: [PATCH] Increase the maximum number of crontab entries
Old limit is considered too low for users with edge cases.
Fixes #91.
---
src/macros.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/macros.h b/src/macros.h
index cba5fb2..d50e981 100644
--- a/src/macros.h
+++ b/src/macros.h
@@ -59,7 +59,7 @@
#define ROOT_UID 0 /* don't change this, it really must be root */
#define ROOT_USER "root" /* ditto */
#define MAX_USER_ENVS 1000 /* maximum environment variables in user's crontab */
-#define MAX_USER_ENTRIES 1000 /* maximum crontab entries in user's crontab */
+#define MAX_USER_ENTRIES 10000 /* maximum crontab entries in user's crontab */
#define MAX_GARBAGE 32768 /* max num of chars of comments and whitespaces between entries */
#define MAX_CLOSE_FD 10000 /* max fd num to close when spawning a child process */

205
n_option.patch Normal file
View File

@ -0,0 +1,205 @@
From ce7d5bf0a43d147f8502e6424cd523b56adf5599 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Poho=C5=99elsk=C3=BD?= <opohorel@redhat.com>
Date: Mon, 26 Sep 2022 16:51:41 +0200
Subject: [PATCH] Add -n option for crontab entries
The -n option causes no mail to be sent
when the command finishes successfully.
These kind of options are already supported in *BSD;
in fact, this is a port of a patch from NetBSD [1].
This was requested in [2].
[1]: NetBSD/src@666eac5
[2]: https://bugzilla.redhat.com/show_bug.cgi?id=1591763
---
src/do_command.c | 32 +++++++++++++++++++++++++++++---
src/entry.c | 31 +++++++++++++++++++++++++++++++
src/funcs.h | 1 +
src/popen.c | 33 ++++++++++++++++++++++++++++++---
src/structs.h | 1 +
5 files changed, 92 insertions(+), 6 deletions(-)
diff --git a/src/do_command.c b/src/do_command.c
index 87f996f..6a3886a 100644
--- a/src/do_command.c
+++ b/src/do_command.c
@@ -94,6 +94,7 @@ static int child_process(entry * e, char **jobenv) {
char mailfrom_expanded[MAX_EMAILSTR];
int children = 0;
pid_t pid = getpid();
+ pid_t jobpid = -1;
struct sigaction sa;
/* Ignore SIGPIPE as we will be writing to pipes and do not want to terminate
@@ -199,7 +200,7 @@ static int child_process(entry * e, char **jobenv) {
/* fork again, this time so we can exec the user's command.
*/
- switch (fork()) {
+ switch (jobpid = fork()) {
case -1:
log_it("CRON", pid, "CAN'T FORK", "child_process", errno);
return ERROR_EXIT;
@@ -552,10 +553,35 @@ static int child_process(entry * e, char **jobenv) {
}
#endif
}
- /* only close pipe if we opened it -- i.e., we're
- * mailing...
+ /* if -n option was specified, abort the sending
+ * now when we read all of the command output
+ * and thus can wait for it's exit status
*/
+ if (mail && e->flags & MAIL_WHEN_ERR) {
+ int jobstatus = -1;
+ if (jobpid > 0) {
+ while (waitpid(jobpid, &jobstatus, WNOHANG) == -1) {
+ if (errno == EINTR) continue;
+ log_it("CRON", getpid(), "error", "invalid job pid", errno);
+ break;
+ }
+ } else {
+ log_it("CRON", getpid(), "error", "invalid job pid", 0);
+ }
+ /* if everything went well, -n is set, and we have mail,
+ * we won't be mailing so shoot the messenger!
+ */
+ if (WIFEXITED(jobstatus) && WEXITSTATUS(jobstatus) == EXIT_SUCCESS) {
+ Debug(DPROC, ("[%ld] aborting pipe to mail\n", (long)getpid()));
+ status = cron_pabort(mail);
+ mail = NULL;
+ }
+ }
+
+ /* only close pipe if we opened it -- i.e., we're (still)
+ * mailing...
+ */
if (mail) {
Debug(DPROC, ("[%ld] closing pipe to mail\n", (long) getpid()));
/* Note: the pclose will probably see
diff --git a/src/entry.c b/src/entry.c
index bb7cb62..9e199fe 100644
--- a/src/entry.c
+++ b/src/entry.c
@@ -417,6 +417,37 @@ entry *load_entry(FILE * file, void (*error_func) (), struct passwd *pw,
Debug(DPARS, ("load_entry()...about to parse command\n"));
+ /* If the first character of the command is '-', it is a cron option. */
+ ch = get_char(file);
+ while (ch == '-') {
+ switch (ch = get_char(file)) {
+ case 'n':
+ /* only allow user to set the option once */
+ if ((e->flags & MAIL_WHEN_ERR) == MAIL_WHEN_ERR) {
+ ecode = e_option;
+ goto eof;
+ }
+ e->flags |= MAIL_WHEN_ERR;
+ break;
+
+ default:
+ ecode = e_option;
+ goto eof;
+ }
+
+ ch = get_char(file);
+ if (ch != '\t' && ch != ' ') {
+ ecode = e_option;
+ goto eof;
+ }
+ Skip_Blanks(ch, file);
+ if (ch == EOF || ch == '\n') {
+ ecode = e_cmd;
+ goto eof;
+ }
+ }
+ unget_char(ch, file);
+
/* Everything up to the next \n or EOF is part of the command...
* too bad we don't know in advance how long it will be, since we
* need to malloc a string for it... so, we limit it to MAX_COMMAND.
diff --git a/src/funcs.h b/src/funcs.h
index dea737e..427e027 100644
--- a/src/funcs.h
+++ b/src/funcs.h
@@ -67,6 +67,7 @@ int load_database(cron_db *),
swap_uids_back(void),
load_env(char *, FILE *),
env_set_from_environ(char ***envpp),
+ cron_pabort(FILE *),
cron_pclose(FILE *),
glue_strings(char *, size_t, const char *, const char *, char),
strcmp_until(const char *, const char *, char),
diff --git a/src/popen.c b/src/popen.c
index 4397264..3043eb6 100644
--- a/src/popen.c
+++ b/src/popen.c
@@ -167,7 +167,7 @@ FILE *cron_popen(char *program, const char *type, struct passwd *pw, char **jobe
return (iop);
}
-int cron_pclose(FILE * iop) {
+static int cron_finalize(FILE * iop, int sig) {
int fdes;
sigset_t oset, nset;
WAIT_T stat_loc;
@@ -180,7 +180,12 @@ int cron_pclose(FILE * iop) {
fdes = fileno(iop);
if (pids == NULL || fdes >= fds || pids[fdes] == 0L)
return (-1);
- (void) fclose(iop);
+
+ if (!sig) {
+ (void) fclose(iop);
+ } else if (kill(pids[fdes], sig) == -1) {
+ return -1;
+ }
sigemptyset(&nset);
sigaddset(&nset, SIGINT);
@@ -189,6 +194,28 @@ int cron_pclose(FILE * iop) {
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
while ((pid = wait(&stat_loc)) != pids[fdes] && pid != -1) ;
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
+
+ if (sig) {
+ (void) fclose(iop);
+ }
pids[fdes] = 0;
- return (pid == -1 ? -1 : WEXITSTATUS(stat_loc));
+
+ if (pid < 0) {
+ return pid;
+ }
+
+ if (WIFEXITED(stat_loc)) {
+ return WEXITSTATUS(stat_loc);
+ } else {
+ return WTERMSIG(stat_loc);
+ }
+}
+
+int cron_pclose(FILE * iop) {
+ return cron_finalize(iop, 0);
+}
+
+int cron_pabort(FILE * iop) {
+ int esig = cron_finalize(iop, SIGKILL);
+ return esig == SIGKILL ? 0 : esig;
}
diff --git a/src/structs.h b/src/structs.h
index 6d3c15b..d930da5 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -48,6 +48,7 @@ typedef struct _entry {
#define DOW_STAR 0x08
#define WHEN_REBOOT 0x10
#define DONT_LOG 0x20
+#define MAIL_WHEN_ERR 0x40
} entry;
/* the crontab database will be a list of the

View File

@ -1,5 +1,17 @@
--- ./src/do_command.c 2023-09-07 09:40:32.016272074 +0200
+++ ./src/do_command.c 2023-09-07 09:43:04.938995232 +0200
From e3682c7135b9176b60d226c60ee4e78cf1ab711b Mon Sep 17 00:00:00 2001
From: bwelterl <bwelterl@redhat.com>
Date: Thu, 7 Sep 2023 10:05:36 +0200
Subject: [PATCH] Optimization to close fds from /proc/self/fd in case of high
nofile limit after fork
---
src/do_command.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/src/do_command.c b/src/do_command.c
index 500f1b0..665e1f0 100644
--- a/src/do_command.c
+++ b/src/do_command.c
@@ -30,6 +30,7 @@
#include <string.h>
#include <sys/wait.h>
@ -8,10 +20,10 @@
#include "externs.h"
#include "funcs.h"
@@ -239,10 +240,26 @@
@@ -264,10 +265,26 @@ static int child_process(entry * e, char **jobenv) {
{
char *shell = env_get("SHELL", jobenv);
int fd, fdmax = getdtablesize();
int fd, fdmax = TMIN(getdtablesize(), MAX_CLOSE_FD);
+ DIR *dir;
+ struct dirent *dent;
@ -29,10 +41,10 @@
+ fd = atoi(dent->d_name);
+ if (fd > STDERR_FILENO)
+ close(fd);
+ }
+ }
+ } else {
+ /* close all unwanted open file descriptors */
+ for(fd = STDERR + 1; fd < fdmax; fd++) {
+ for (fd = STDERR + 1; fd < fdmax; fd++) {
+ close(fd);
+ }
}

View File

@ -1 +1 @@
SHA512 (cronie-1.5.2.tar.gz) = e306b4b8388bff0181ca4b3f15b81c0881d727b0f502c28204e8325359c49baeb1b1a4a5751ffc11eb5ebdeefe42704b77f6727f029c60c99c70b9885f6b4d18
SHA512 (cronie-1.5.7.tar.gz) = c306468d2e8d618a168e55204796f15d845520130d9601395e6413c55a71e94b4264a73e2e3f5d7011b3e53af9dad812f56662de3a7c9e50977d57b2a49a6893