Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cups-browsed.c: create_queue() may leave make_model uninitialized #42

Closed
solardiz opened this issue Oct 1, 2024 · 0 comments
Closed

Comments

@solardiz
Copy link

solardiz commented Oct 1, 2024

I just happened to notice the below code snippet appearing twice at

make_model = (char*)malloc(sizeof(char) * 256);
and
make_model = (char*)malloc(sizeof(char)*256);

      make_model = (char*)malloc(sizeof(char) * 256);
      printer_attributes = get_cluster_attributes(p->queue_name);
      if ((attr = ippFindAttribute(printer_attributes,
                                   "printer-make-and-model",
                                   IPP_TAG_TEXT)) != NULL)
        strncpy(make_model, ippGetString(attr, 0, NULL),
                sizeof(make_model) - 1);

There are several issues here:

  1. If the if condition above is false, the contents of make_model are left completely uninitialized.
  2. strncpy doesn't NUL-terminate (it NUL-pads if space permits), so if the string is later used then uninitialized data may be processed after the string end.
  3. sizeof(make_model) returns the size of the pointer, not of the memory allocation, so the copying is commonly limited to 7 characters followed by uninitialized memory.
  4. If malloc returns NULL (on out-of-memory), this code will crash - but such issues are all over the place in this source file (perhaps a deliberate design decision, even if sloppy), so there's no point in singling out this one occurrence.

In both places, this is followed by code like:

    if (ppdfile == NULL)
    {
      // If we do not want CUPS-generated PPDs or we cannot obtain a
      // CUPS-generated PPD, for example if CUPS does not create a
      // temporary queue for this printer, we generate a PPD by
      // ourselves
      printer_ipp_response = (num_cluster_printers == 1) ? p->prattrs :
        printer_attributes;
      if (!ppdCreatePPDFromIPP2(ppdname, sizeof(ppdname), printer_ipp_response,
                                make_model,

so the potentially fully or partially uninitialized make_model may be actually used.

This may be a security issue, but that is not immediately clear (would need further analysis) and an individual bug like this may not matter much given the overall poor code quality (this is just something I happened to notice quickly).

Regardless, if this code is to stay, the bug (issued 1, 2, 3 above) should be fixed (in both places), e.g. quick-and-dirty (preserving code style):

      make_model = (char*)malloc(sizeof(char) * 256);
      *make_model = 0; /* Empty string for possibly strncat'ing to */
      printer_attributes = get_cluster_attributes(p->queue_name);
      if ((attr = ippFindAttribute(printer_attributes,
                                   "printer-make-and-model",
                                   IPP_TAG_TEXT)) != NULL)
        strncat(make_model, ippGetString(attr, 0, NULL), 255);

Note that this is deliberately strncat rather than strncpy, so that NUL termination and not NUL padding is done.

Ideally, code duplication should be avoided, and whether this code is needed at all reconsidered (if the truncation to 7 or even 3 characters went undetected for years, then perhaps this functionality didn't matter).

tillkamppeter added a commit to OpenPrinting/cups-filters that referenced this issue Jan 7, 2025
Fixes #598

At 2 points the string buffer for make_model got malloced but not
initialized by putting a terminating zero to its beginning.

At the same points sizeof() was applied to the pointer to the buffer
rsulting in a 7-byte limit and strncpy was used which does not put a
terminating zero when the string copied is too long for the given
limit (which was always the case). No we use an explicit number for
the limit and strncat which always zero-terminates.

Thanks, Solar Designer, for describing bug and solution so well in
your report.

Same as OpenPrinting/cups-browsed#42:

OpenPrinting/cups-browsed@f6bf616b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant