* Don't allow derivations with fixed and non-fixed outputs.
This commit is contained in:
		
							parent
							
								
									b2027f70d9
								
							
						
					
					
						commit
						c8606664ab
					
				
					 1 changed files with 40 additions and 45 deletions
				
			
		|  | @ -394,23 +394,11 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) | ||||||
|         throw EvalError(format("derivation names are not allowed to end in `%1%'") |         throw EvalError(format("derivation names are not allowed to end in `%1%'") | ||||||
|             % drvExtension); |             % drvExtension); | ||||||
| 
 | 
 | ||||||
|     /* Construct the "masked" store derivation, which is the final one
 |     if (outputHash != "") { | ||||||
|        except that in the list of outputs, the output paths are empty, |         /* Handle fixed-output derivations. */ | ||||||
|        and the corresponding environment variables have an empty |         if (outputs.size() != 1 || *(outputs.begin()) != "out") | ||||||
|        value.  This ensures that changes in the set of output names do |             throw Error("multiple outputs are not supported in fixed-output derivations"); | ||||||
|        get reflected in the hash. |  | ||||||
|          |          | ||||||
|        However, for fixed-output derivations, we can compute the |  | ||||||
|        output path directly, so we don't need this. */ |  | ||||||
|     bool fixedOnly = true; |  | ||||||
|     foreach (StringSet::iterator, i, outputs) { |  | ||||||
|         if (*i != "out" || outputHash == "") { |  | ||||||
|             drv.env[*i] = ""; |  | ||||||
|             drv.outputs[*i] = DerivationOutput("", "", ""); |  | ||||||
|             fixedOnly = false; |  | ||||||
|         } else { |  | ||||||
|             /* If an output hash was given, check it, and compute the
 |  | ||||||
|                output path. */ |  | ||||||
|         HashType ht = parseHashType(outputHashAlgo); |         HashType ht = parseHashType(outputHashAlgo); | ||||||
|         if (ht == htUnknown) |         if (ht == htUnknown) | ||||||
|             throw EvalError(format("unknown hash algorithm `%1%'") % outputHashAlgo); |             throw EvalError(format("unknown hash algorithm `%1%'") % outputHashAlgo); | ||||||
|  | @ -427,20 +415,27 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) | ||||||
|         string s = outputHash; |         string s = outputHash; | ||||||
|         outputHash = printHash(h); |         outputHash = printHash(h); | ||||||
|         if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo; |         if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo; | ||||||
|  |          | ||||||
|         Path outPath = makeFixedOutputPath(outputHashRecursive, ht, h, drvName); |         Path outPath = makeFixedOutputPath(outputHashRecursive, ht, h, drvName); | ||||||
|             drv.env[*i] = outPath; |         drv.env["out"] = outPath; | ||||||
|             drv.outputs[*i] = DerivationOutput(outPath, outputHashAlgo, outputHash); |         drv.outputs["out"] = DerivationOutput(outPath, outputHashAlgo, outputHash); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     else { | ||||||
|  |         /* Construct the "masked" store derivation, which is the final
 | ||||||
|  |            one except that in the list of outputs, the output paths | ||||||
|  |            are empty, and the corresponding environment variables have | ||||||
|  |            an empty value.  This ensures that changes in the set of | ||||||
|  |            output names do get reflected in the hash. */ | ||||||
|  |         foreach (StringSet::iterator, i, outputs) { | ||||||
|  |             drv.env[*i] = ""; | ||||||
|  |             drv.outputs[*i] = DerivationOutput("", "", ""); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* Use the masked derivation expression to compute the output
 |         /* Use the masked derivation expression to compute the output
 | ||||||
|        path.  !!! Isn't it a potential security problem that the name |            path. */ | ||||||
|        of each output path (including the suffix) isn't taken into |  | ||||||
|        account?  For instance, changing the suffix for one path |  | ||||||
|        (‘i->first == "out" ...’) doesn't affect the hash of the |  | ||||||
|        others.  Is that exploitable? */ |  | ||||||
|     if (!fixedOnly) { |  | ||||||
|         Hash h = hashDerivationModulo(drv); |         Hash h = hashDerivationModulo(drv); | ||||||
|  |          | ||||||
|         foreach (DerivationOutputs::iterator, i, drv.outputs) |         foreach (DerivationOutputs::iterator, i, drv.outputs) | ||||||
|             if (i->second.path == "") { |             if (i->second.path == "") { | ||||||
|                 Path outPath = makeOutputPath(i->first, h, drvName); |                 Path outPath = makeOutputPath(i->first, h, drvName); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue