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

segmentation fault during calls to cups gem v0.1.10 #21

Open
dsaronin opened this issue Jun 26, 2015 · 2 comments
Open

segmentation fault during calls to cups gem v0.1.10 #21

dsaronin opened this issue Jun 26, 2015 · 2 comments

Comments

@dsaronin
Copy link

This is reproducible; originally reported as bug to Ruby 2.2.1 ( https://bugs.ruby-lang.org/issues/11306 ). But their recommendation is for changes to cups.c (shown below as the first comment to this issue). This may or may not be related to issue #10 .

the following works okay:

2.2.1 :001 > list = Cups.show_destinations
 => ["laserjet_1102w", "lp_null"] 
2.2.1 :002 > Cups.device_uri_for( list.first )
 => "hp:/net/HP_LaserJet_Professional_P_1102w?ip=192.168.0.65" 
2.2.1 :003 > Cups.device_uri_for( list.last )
 => "file:https:///dev/null" 

the following fails (the order is not important; the second call always fails with abort):

2.2.1 :001 > list = Cups.show_destinations
 => ["laserjet_1102w", "lp_null"] 
2.2.1 :002 > CupsDevice.testit( list.first )
 => "hp:/net/HP_LaserJet_Professional_P_1102w?ip=192.168.0.65" 
2.2.1 :003 > CupsDevice.testit( list.last )
/home/daudi/projectspace/swalapala/app/models/cups_device.rb:101: [BUG] Segmentation fault at 0x0000000a491862
ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux]

where

class CupsDevice < ActiveRecord::Base
  def self.testit( cups_name )
       Cups.device_uri_for( cups_name )
  end
end # class CupsDevice

detailed core dump at: https://gist.github.com/dsaronin/52e1e8aa97b61210c478

@dsaronin
Copy link
Author

Response from Ruby/Eric Wong:
You want to use StringValueCStr or StringValuePtr when you see
untrusted user-input instead of RSTRING_PTR. RSTRING_PTR will segfault
if the user calls a function with a non-String. (see code below for incorrect)

static VALUE cups_get_device_uri(VALUE self, VALUE printer)
{
   if (!printer_exists(printer))
   {
     rb_raise(rb_eRuntimeError, "The printer or destination doesn't exist!");
   }

   VALUE options_list;
   http_t *http;
   ipp_t *request;
   ipp_t *response;
   ipp_attribute_t *attr;
   char uri[1024];
   char *location;
   char *name = RSTRING_PTR(printer);
                         ~~~~~~~~~~~~~~~~~~~~~~
request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
   httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", name);

You also need to add a GC guard for VALUE where you got name' from
after the last use ofname' in your function:

RB_GC_GUARD(printer);

Nowadays with better optimizing compilers, the `volatile' type qualifier
for args in the StringValue* family functions is insufficient to protect
VALUEs from inadvertant GC. RB_GC_GUARD must be used.

See doc/extension.rdoc in the latest Ruby trunk or README.EXT in the
2.2 source tarball for more info on these APIs

And feel free to ask for clarification here on the ruby-core ML.

cups.c (14.2 KB)

Lots of similar problems in cups.c too. The same pattern
described above needs to happen with

RSTRING_PTR => StringValueCStr/StringValuePtr 

and the addition of RB_GC_GUARD calls after the last access to the underlying pointer.

There may be other problems in the code, too, but these are the ones
that jumped out to my tired, sleepy eyes...

@dsaronin
Copy link
Author

Here's a one-liner to reproduce the error, assuming you have at least two registered CUPS printers (mine are: "laserjet_1102w", "lp_null")

 Cups.show_destinations.map {|cn| Cups.device_uri_for( cn ) }

and both of the following also reproduces the error:

["laserjet_1102w"].each {|cn| Cups.device_uri_for( cn ) }
1.times {|n| Cups.device_uri_for( "laserjet_1102w" ) }

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