Uploaded image for project: 'CFEngine Community'
  1. CFEngine Community
  2. CFE-1906

"files.cf" bundles: possible cross-contamination across multiple files

    XMLWordPrintable

    Details

      Description

      Regarding edit_file bundles in "lib/3.6/files.cf" I think there is a cross-contamination bug caused by inadequately differentiated class names.

      Imagine maintaining a set of two or more similar configuration files, such as (in RHEL) "/etc/sysconfig/network-scripts/ifcfg-eth*" using bundles such as "set_variable_values", "set_line_based()", etc. The files look like:
      <pre>
      KEY_1=VALUE_A
      KEY_2=VALUE_B
      </pre>

      Internally, the bundle controls its actions using classes. But some of the classes are set in "replace_patterns:" using "classes => ...". Such classes are global, not local, in scope. So if this bundle is used on two or more similar files, the global class set from one file can influence the behaviour of subsequent files. This cross-contamination is surely not intended, is it?

      The problem is in the class names. Firstly, a more simple analogy. Imagine using a simple class name (e.g. "replace_attempted"). Then even within one file this would clearly cause cross-contamination across its multiple lines. Fortunately, the library bundles already correctly avoid this by qualifying the name with a representation of the various the "key" values (e.g. ending up as "replace_attempted_KEY_1"). This is good.

      But this same principle needs also to be considered across multiple files, because "replace_attempted_KEY_1" from one file will interfere with that on any subsequent files containing any of these keys. This is bad.

      I think, however, that there is a simple fix. In just the same way as the class name already includes the key to avoid cross-contamination between lines within a single file, then similarly also the class name should include the filename to avoid cross-contamination across files.

      So for a clause:
      <pre>
      classes => always("replace_attempted_$(key)")
      </pre>

      instead use something like:
      <pre>
      classes => always("replace_attempted_$(key)in$(edit.filename)")
      </pre>

      (In the above, for clarity of this discussion, I have simplified the actual "$(ci[$(i)])" to a representative equivalent, "$(key)".)

      We need to recognise and appreciate that:

      • these classes, being used within the bundle with supposedly local intention, are unfortunately global in scope;
      • the bundle may be called multiple times with similar data for similar files;
      • the classnames must be constructed with uniqueness for such multiple calls with multiple key/value pairs.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                a10042 Nick Anderson
                Reporter:
                davidlee David Lee
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Summary Panel