Skip to content

Commit ece9727

Browse files
author
matz
committed
security enhancement of dl library (need test).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3609 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent ab7dac4 commit ece9727

File tree

9 files changed

+175
-158
lines changed

9 files changed

+175
-158
lines changed

eval.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ rb_secure(level)
139139
}
140140

141141
void
142-
rb_check_safe_str(x)
142+
rb_check_safe_obj(x)
143143
VALUE x;
144144
{
145145
if (ruby_safe_level > 0 && OBJ_TAINTED(x)){
@@ -152,6 +152,13 @@ rb_check_safe_str(x)
152152
}
153153
}
154154
rb_secure(4);
155+
}
156+
157+
void
158+
rb_check_safe_str(x)
159+
VALUE x;
160+
{
161+
rb_check_safe_obj(x);
155162
if (TYPE(x)!= T_STRING) {
156163
rb_raise(rb_eTypeError, "wrong argument type %s (expected String)",
157164
rb_obj_classname(x));

ext/dl/dl.c

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ rb_dl_scan_callback_args(long stack[], const char *proto,
2424
VALUE val;
2525

2626
sp = stack;
27-
for( i=1; proto[i]; i++ ){
28-
switch( proto[i] ){
27+
for (i=1; proto[i]; i++) {
28+
switch (proto[i]) {
2929
case 'C':
3030
{
3131
char v;
@@ -162,11 +162,11 @@ dlsizeof(const char *cstr)
162162

163163
len = strlen(cstr);
164164
size = 0;
165-
for( i=0; i<len; i++ ){
165+
for (i=0; i<len; i++) {
166166
n = 1;
167-
if( isdigit(cstr[i+1]) ){
167+
if (isdigit(cstr[i+1])) {
168168
dlen = 1;
169-
while( isdigit(cstr[i+dlen]) ){ dlen ++; };
169+
while (isdigit(cstr[i+dlen])) { dlen ++; };
170170
dlen --;
171171
d = ALLOCA_N(char, dlen + 1);
172172
strncpy(d, cstr + i + 1, dlen);
@@ -177,7 +177,7 @@ dlsizeof(const char *cstr)
177177
dlen = 0;
178178
}
179179

180-
switch( cstr[i] ){
180+
switch (cstr[i]) {
181181
case 'I':
182182
DLALIGN(0,size,INT_ALIGN);
183183
case 'i':
@@ -234,9 +234,9 @@ c_farray(VALUE v, long *size)
234234
len = RARRAY(v)->len;
235235
*size = sizeof(float) * len;
236236
ary = dlmalloc(*size);
237-
for( i=0; i < len; i++ ){
237+
for (i=0; i < len; i++) {
238238
e = rb_ary_entry(v, i);
239-
switch( TYPE(e) ){
239+
switch (TYPE(e)) {
240240
case T_FLOAT:
241241
ary[i] = (float)(RFLOAT(e)->value);
242242
break;
@@ -262,9 +262,9 @@ c_darray(VALUE v, long *size)
262262
len = RARRAY(v)->len;
263263
*size = sizeof(double) * len;
264264
ary = dlmalloc(*size);
265-
for( i=0; i < len; i++ ){
265+
for (i=0; i < len; i++) {
266266
e = rb_ary_entry(v, i);
267-
switch( TYPE(e) ){
267+
switch (TYPE(e)) {
268268
case T_FLOAT:
269269
ary[i] = (double)(RFLOAT(e)->value);
270270
break;
@@ -290,9 +290,9 @@ c_larray(VALUE v, long *size)
290290
len = RARRAY(v)->len;
291291
*size = sizeof(long) * len;
292292
ary = dlmalloc(*size);
293-
for( i=0; i < len; i++ ){
293+
for (i=0; i < len; i++) {
294294
e = rb_ary_entry(v, i);
295-
switch( TYPE(e) ){
295+
switch (TYPE(e)) {
296296
case T_FIXNUM:
297297
case T_BIGNUM:
298298
ary[i] = (long)(NUM2INT(e));
@@ -319,9 +319,9 @@ c_iarray(VALUE v, long *size)
319319
len = RARRAY(v)->len;
320320
*size = sizeof(int) * len;
321321
ary = dlmalloc(*size);
322-
for( i=0; i < len; i++ ){
322+
for (i=0; i < len; i++) {
323323
e = rb_ary_entry(v, i);
324-
switch( TYPE(e) ){
324+
switch (TYPE(e)) {
325325
case T_FIXNUM:
326326
case T_BIGNUM:
327327
ary[i] = (int)(NUM2INT(e));
@@ -348,9 +348,9 @@ c_harray(VALUE v, long *size)
348348
len = RARRAY(v)->len;
349349
*size = sizeof(short) * len;
350350
ary = dlmalloc(*size);
351-
for( i=0; i < len; i++ ){
351+
for (i=0; i < len; i++) {
352352
e = rb_ary_entry(v, i);
353-
switch( TYPE(e) ){
353+
switch (TYPE(e)) {
354354
case T_FIXNUM:
355355
case T_BIGNUM:
356356
ary[i] = (short)(NUM2INT(e));
@@ -377,9 +377,9 @@ c_carray(VALUE v, long *size)
377377
len = RARRAY(v)->len;
378378
*size = sizeof(char) * len;
379379
ary = dlmalloc(*size);
380-
for( i=0; i < len; i++ ){
380+
for (i=0; i < len; i++) {
381381
e = rb_ary_entry(v, i);
382-
switch( TYPE(e) ){
382+
switch (TYPE(e)) {
383383
case T_FIXNUM:
384384
case T_BIGNUM:
385385
ary[i] = (char)(NUM2INT(e));
@@ -401,15 +401,23 @@ c_parray(VALUE v, long *size)
401401
{
402402
int i, len;
403403
void **ary;
404-
VALUE e;
404+
VALUE e, tmp;
405405

406406
len = RARRAY(v)->len;
407407
*size = sizeof(void*) * len;
408408
ary = dlmalloc(*size);
409-
for( i=0; i < len; i++ ){
409+
for (i=0; i < len; i++) {
410410
e = rb_ary_entry(v, i);
411-
switch( TYPE(e) ){
411+
switch (TYPE(e)) {
412+
default:
413+
tmp = rb_check_string_type(e);
414+
if (NIL_P(tmp)) {
415+
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
416+
}
417+
e = tmp;
418+
/* fall through */
412419
case T_STRING:
420+
rb_check_safe_str(e);
413421
{
414422
char *str, *src;
415423
src = RSTRING(e)->ptr;
@@ -421,7 +429,7 @@ c_parray(VALUE v, long *size)
421429
ary[i] = NULL;
422430
break;
423431
case T_DATA:
424-
if( rb_obj_is_kind_of(e, rb_cDLPtrData) ){
432+
if (rb_obj_is_kind_of(e, rb_cDLPtrData)) {
425433
struct ptr_data *pdata;
426434
Data_Get_Struct(e, struct ptr_data, pdata);
427435
ary[i] = (void*)(pdata->ptr);
@@ -430,9 +438,6 @@ c_parray(VALUE v, long *size)
430438
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
431439
}
432440
break;
433-
default:
434-
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
435-
break;
436441
}
437442
}
438443

@@ -445,24 +450,26 @@ rb_ary2cary(char t, VALUE v, long *size)
445450
int len;
446451
VALUE val0;
447452

448-
if( TYPE(v) != T_ARRAY ){
453+
val0 = rb_check_array_type(v);
454+
if(NIL_P(TYPE(val0))) {
449455
rb_raise(rb_eDLTypeError, "an array is expected.");
450456
}
457+
v = val0;
451458

452459
len = RARRAY(v)->len;
453-
if( len == 0 ){
460+
if (len == 0) {
454461
return NULL;
455462
}
456463

457-
if( !size ){
464+
if (!size) {
458465
size = ALLOCA_N(long,1);
459466
}
460467

461468
val0 = rb_ary_entry(v,0);
462-
switch( TYPE(val0) ){
469+
switch (TYPE(val0)) {
463470
case T_FIXNUM:
464471
case T_BIGNUM:
465-
switch( t ){
472+
switch (t) {
466473
case 'C': case 'c':
467474
return (void*)c_carray(v,size);
468475
case 'H': case 'h':
@@ -477,15 +484,15 @@ rb_ary2cary(char t, VALUE v, long *size)
477484
case T_STRING:
478485
return (void*)c_parray(v,size);
479486
case T_FLOAT:
480-
switch( t ){
487+
switch (t) {
481488
case 'F': case 'f':
482489
return (void*)c_farray(v,size);
483490
case 'D': case 'd': case 0:
484491
return (void*)c_darray(v,size);
485492
}
486493
rb_raise(rb_eDLTypeError, "type mismatch");
487494
case T_DATA:
488-
if( rb_obj_is_kind_of(val0, rb_cDLPtrData) ){
495+
if (rb_obj_is_kind_of(val0, rb_cDLPtrData)) {
489496
return (void*)c_parray(v,size);
490497
}
491498
rb_raise(rb_eDLTypeError, "type mismatch");
@@ -516,7 +523,7 @@ rb_ary_to_ptr(int argc, VALUE argv[], VALUE self)
516523
VALUE t;
517524
long size;
518525

519-
switch( rb_scan_args(argc, argv, "01", &t) ){
526+
switch (rb_scan_args(argc, argv, "01", &t)) {
520527
case 1:
521528
ptr = rb_ary2cary(StringValuePtr(t)[0], self, &size);
522529
break;
@@ -556,15 +563,13 @@ rb_dl_malloc(VALUE self, VALUE size)
556563
VALUE
557564
rb_dl_strdup(VALUE self, VALUE str)
558565
{
559-
rb_secure(4);
560-
str = rb_String(str);
566+
SafeStringValue(str);
561567
return rb_dlptr_new(strdup(RSTRING(str)->ptr), RSTRING(str)->len, dlfree);
562568
}
563569

564570
static VALUE
565571
rb_dl_sizeof(VALUE self, VALUE str)
566572
{
567-
rb_secure(4);
568573
return INT2NUM(dlsizeof(StringValuePtr(str)));
569574
}
570575

@@ -577,9 +582,9 @@ rb_dl_callback(int argc, VALUE argv[], VALUE self)
577582

578583
rb_secure(4);
579584
proc = Qnil;
580-
switch( rb_scan_args(argc, argv, "11", &type, &proc) ){
585+
switch (rb_scan_args(argc, argv, "11", &type, &proc)) {
581586
case 1:
582-
if( rb_block_given_p() ){
587+
if (rb_block_given_p()) {
583588
proc = rb_f_lambda();
584589
}
585590
else{
@@ -589,8 +594,8 @@ rb_dl_callback(int argc, VALUE argv[], VALUE self)
589594
break;
590595
}
591596

592-
Check_Type(type, T_STRING);
593-
switch( RSTRING(type)->ptr[0] ){
597+
StringValue(type);
598+
switch (RSTRING(type)->ptr[0]) {
594599
case '0':
595600
rettype = 0x00;
596601
break;
@@ -620,13 +625,13 @@ rb_dl_callback(int argc, VALUE argv[], VALUE self)
620625
}
621626

622627
entry = -1;
623-
for( i=0; i < MAX_CALLBACK; i++ ){
624-
if( rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(rettype), INT2NUM(i))) == Qnil ){
628+
for (i=0; i < MAX_CALLBACK; i++) {
629+
if (rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(rettype), INT2NUM(i))) == Qnil) {
625630
entry = i;
626631
break;
627632
}
628633
}
629-
if( entry < 0 ){
634+
if (entry < 0) {
630635
rb_raise(rb_eDLError, "too many callbacks are defined.");
631636
}
632637

@@ -646,9 +651,9 @@ rb_dl_remove_callback(VALUE mod, VALUE sym)
646651

647652
rb_secure(4);
648653
f = rb_dlsym2csym(sym);
649-
for( i=0; i < CALLBACK_TYPES; i++ ){
650-
for( j=0; j < MAX_CALLBACK; j++ ){
651-
if( rb_dl_callback_table[i][j] == f ){
654+
for (i=0; i < CALLBACK_TYPES; i++) {
655+
for (j=0; j < MAX_CALLBACK; j++) {
656+
if (rb_dl_callback_table[i][j] == f) {
652657
rb_hash_aset(DLFuncTable, rb_assoc_new(INT2NUM(i),INT2NUM(j)),Qnil);
653658
break;
654659
}

0 commit comments

Comments
 (0)