Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Dry-run mode writes to /etc/apt/sources.list on the legacy Debian/Ubuntu source-list path

Open Beginner friendly
#396 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
82/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
c, linux
Domain
cli, devtools

Research direction

Read src/recipe/os/APT/common.h around ensure_debian_or_ubuntu_old_sourcelist() and compare its write with the dry-run-aware path in src/framework/OS.c. Check the Debian and Ubuntu call sites listed in the issue, then run the project’s relevant tests or reproduce with chsrc set -dry debian where the legacy source-list file is absent. Done means dry-run does not create /etc/apt/sources.list and the function keeps the stated return behavior.

Written by the indexing model from the issue text.

Description

Summary

chsrc set -dry writes to /etc/apt/sources.list on Debian/Ubuntu when the file does not exist. Dry-run mode is not fully honored on this code path.

Problem

ensure_debian_or_ubuntu_old_sourcelist() in src/recipe/os/APT/common.h generates a source-list template and writes it with a raw fopen/fwrite, without checking in_dry_run_mode():

src/recipe/os/APT/common.h:116-118

  FILE *f = fopen (OS_Apt_SourceList, "w");
  fwrite (makeup, strlen (makeup), 1, f);
  fclose (f);

This bypasses chsrc_overwrite_file() (src/framework/OS.c:836), which is where the dry-run guard normally lives.

Call sites:

  • src/recipe/os/APT/Debian.c:127
  • src/recipe/os/APT/Debian.c:145 (re-invoked after CDROM source removal)
  • src/recipe/os/APT/Ubuntu.c:127

Trigger

The function is reached only on the old-format (non-DEB822) path. os_debian_setsrc() returns early when a DEB822 file exists (src/recipe/os/APT/Debian.c:117-122), so the bug does not trigger on a stock Debian 12 / Ubuntu 24.04 installation.

It triggers when:

  • the system still uses the legacy /etc/apt/sources.list (pre-Debian-12 / pre-Ubuntu-24.04 layout), and the file is absent, or
  • a minimal container image ships neither debian.sources nor sources.list

Reproduction

On a Debian-family system where /etc/apt/sources.list does not exist:

sudo chsrc set -dry debian

Expected: prints the command it would run, writes nothing.

Actual: /etc/apt/sources.list is created on disk.

Verify:

ls -l /etc/apt/sources.list    # file now exists, despite -dry

Why this matters

Dry-run mode is the recommended way to preview a change on a system you care about — and it is the only isolation mechanism available to non-root users. This path silently writes to a system-wide config file, which is exactly what -dry is supposed to prevent.

It is most surprising inside containers and chroots, where an isolated -dry run is the normal way to test a configuration change before applying it.

Suggested fix

Route the write through chsrc_overwrite_file() (or add an explicit in_dry_run_mode() check before the fopen), so the guard applies consistently:

  if (in_dry_run_mode ())
    return false;

  FILE *f = fopen (OS_Apt_SourceList, "w");
  ...

Note that this function returns bool (whether the file existed). Under -dry it should keep returning false so the caller continues down the existing path without acting on a file that was never written.

Related

  • The DEB822 path (os_debian_setsrc_for_deb822, src/recipe/os/APT/Debian.c:83) goes through chsrc_run(), which does honor -dry. The inconsistency between the two branches is what makes this easy to miss.
  • Reference: upstream issue #185 introduced this function for systems with no existing source list, but did not account for dry-run mode.

Environment

  • chsrc: v0.2.7.2 (0bcc4c2)
  • Reproduced by code inspection; the logic path is unconditional once the old-format branch is taken
Dominant language
C
Stars
6.9k
Forks
285
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from RubyMetric/chsrc

All issues in RubyMetric/chsrc

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.