Dear Maintainer,
`crontab <file>` silently truncates the file path argument at 100 chars
instead of rejecting a too-long path, then fails against the truncated
path with a misleading "No such file or directory" or "Not a regular
file" error that doesn't match the path the user actually passed.
Root cause: cron.h defines
#define MAX_FNAME 100 /* max length of internally generated fn */
That buffer is meant for cron's own internally-generated filenames, but
crontab.c reuses the same constant for the buffer that holds the
user-supplied CLI path argument:
static char Filename[MAX_FNAME]; /* crontab.c:60 */
...
(void) strncpy (Filename, argv[optind], (sizeof Filename)-1);
Filename[(sizeof Filename)-1] = '\0'; /* crontab.c:255-256 */
There is no length check before the strncpy, so any path >=100 chars
(99 usable chars + NUL) is silently truncated. The program then tries
to open/stat the truncated path, which either doesn't exist (ENOENT,
"No such file or directory") or happens to resolve to an existing
directory ("Not a regular file") -- neither error message reflects
what actually went wrong, which makes this very confusing to debug:
the file genuinely exists at the path the user gave, but crontab is
silently operating on a different, truncated path.
Reproduction (byte-precision, confirmed on 3.0pl1-197):
$ f=/tmp/$(python3 -c "print('a'*86)")/x # 99 chars total
$ mkdir -p "$(dirname "$f")"; echo '* * * * * true' > "$f"
$ crontab "$f"; echo $?
0
$ f=/tmp/$(python3 -c "print('a'*87)")/x # 100 chars total
$ mkdir -p "$(dirname "$f")"; echo '* * * * * true' > "$f"
$ crontab "$f"
/tmp/aaaa....aaa: Not a regular file.
(the printed path is the truncated 99-char string, cut off before
the trailing "/x" -- it happens to equal the parent directory,
which is why stat() succeeds but S_ISREG() fails)
Proposed fix: reject with a clear error instead of truncating silently.
Minimal patch against crontab.c, just before the existing strncpy at
line 255:
--- a/crontab.c
+++ b/crontab.c
@@ -252,6 +252,11 @@
if (argv[optind] != NULL) {
Option = opt_replace;
+ if (strlen(argv[optind]) >= sizeof(Filename)) {
+ fprintf(stderr,
+ "%s: pathname too long (max %zu chars)\n",
+ argv[optind], sizeof(Filename) - 1);
+ exit(ERROR_EXIT);
+ }
(void) strncpy (Filename, argv[optind], (sizeof Filename)-1);
Filename[(sizeof Filename)-1] = '\0';
This preserves the existing MAX_FNAME=100 limit used elsewhere in the
codebase for internally-generated filenames, and just stops it from
silently truncating a user-supplied path into a different, unintended
path.
We believe that the bug you reported is fixed in the latest version of
cron, which is due to be installed in the Debian FTP archive.
A summary of the changes between this version and the previous one is
attached.
Thank you for reporting the bug, which will now be closed. If you
have further comments please address them to 1144850@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.
Debian distribution maintenance software
pp.
Georges Khaznadar <georgesk@debian.org> (supplier of updated cron package)
(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmaster@ftp-master.debian.org)
Format: 1.8
Date: Sun, 27 Sep 2026 17:45:19 +0200
Source: cron
Architecture: source
Version: 3.0pl1-211
Distribution: unstable
Urgency: medium
Maintainer: Georges Khaznadar <georgesk@debian.org>
Changed-By: Georges Khaznadar <georgesk@debian.org>
Closes: 1144850
Changes:
cron (3.0pl1-211) unstable; urgency=medium
.
* applied the patch sent by perrytomhave@gmail.com, thanks!
Closes: #1144850
* added a test to check the fix.
Checksums-Sha1:
370e536dcb673623610d1d3f2faad5370797338a 2189 cron_3.0pl1-211.dsc
ecfccd21901da41afa8812db5ad3313e582c9630 142536 cron_3.0pl1-211.debian.tar.xz
8625441ed74cea761b46e7be79d86dbd7a26d551 6379 cron_3.0pl1-211_source.buildinfo
Checksums-Sha256:
ebe72cadaacacdc22d82c3d105e8aad28a2d8b3c76b8a3fa97c518133cba1688 2189 cron_3.0pl1-211.dsc
4c32b0193eda318909af9cd23077216ce92d41fe4f13889f28507d5ef19b249a 142536 cron_3.0pl1-211.debian.tar.xz
8283aeebc9731d51570e7fb49bf51d3ce138dc45c63db6c7a449f72d3b5138d7 6379 cron_3.0pl1-211_source.buildinfo
Files:
e061bfc4a58da0307a9b1ef48de35c76 2189 admin important cron_3.0pl1-211.dsc
340366f5e5b9945113e585dc3ff1f769 142536 admin important cron_3.0pl1-211.debian.tar.xz
77f428b47cce41cba02118139a69f7d3 6379 admin important cron_3.0pl1-211_source.buildinfo
-----BEGIN PGP SIGNATURE-----
iQJIBAEBCgAyFiEEM0CzZP9nFT+3zK6FHCgWkHE2rjkFAmq5OuoUHGdlb3JnZXNr
QGRlYmlhbi5vcmcACgkQHCgWkHE2rjlT+g/8Cu3oS6kEEy4j3UKGEDPfmggBimxb
NP3jA079OBOA4GhupbG484XW48WHLo+CB9PQbXY2HLbiPNEv40XUCGDq72hglEdD
o6LO6MHrPyw1bPPlCE6SKqZo7OpoAnRItLiCyK2H20rquUZtSXOfsef0jIJ1YroV
xpgkaYeZEsc8vnYAV5j9zbqvtgzUqrBTdTt/dC9Ea6v34OUE0xy+nGqBSvww2MTd
SMFUEWSx4GbAT2cpErxsfpXf/aj9b16kTj8sOFNCHefNXfXaysSTrM2ENgf6l6p0
dhwY5sgLjUG2HGdnGQRL6ftLIIwh/6X2alAUbaCwvklNeP3iQqhyxMoZjWo/Db75
8qw1m44sbzdZxkOjVwG7J8a4euxV/vufE2sjK44OnsiFRbjiglqLtMvLYbRa0uPn
9ZM2/dJd3XC1ngDIZkb3v20Po78VDbqlXse5VzweGIQH6u9KFu9QRvRB8iVxyUr/
1TfY6rf6kBQR0XhBpklDhHLafqTWKj9jKCp6TKbTI1h+a6mLgFBDRTmYyJ8c94Fa
yQAPwv1Hck0YdNq30VwIr/bFuqmc+4l3TEZfHef9MlkPihG7dPjW11dy7NQrT+sk
XqSkDCRdvS81I+0wO/v9ZU9CdY9pmXOs+nuHNs1Ei34ztV/33pr47tjSzmbucMbR
GRhyG7BJIE/qiUM=
=00u+
-----END PGP SIGNATURE-----